<commit_before>#ifndef STAN_MATH_PRIM_FUN_LOG_HPP
#define STAN_MATH_PRIM_FUN_LOG_HPP

#include <stan/math/prim/meta.hpp>
#include <stan/math/rev/meta.hpp>
#include <stan/math/prim/fun/Eigen.hpp>
#include <stan/math/prim/fun/isinf.hpp>
#include <stan/math/prim/fun/is_inf.hpp>
#include <stan/math/prim/fun/is_nan.hpp>
#include <cmath>
#include <complex>
#include <limits>

namespace stan {
namespace math {

/**
 * Structure to wrap `log()` so that it can be vectorized.
 */
struct log_fun {
  /**
   * Return natural log of specified argument.
   *
   * @tparam T type of argument
   * @param[in] x argument
   * @return Natural log of x.
   */
  template <typename T>
  static inline T fun(const T& x) {
    using std::log;
    return log(x);
  }
};

/**
 * Return the elementwise natural log of the specified argument,
 * which may be a scalar or any Stan container of numeric scalars.
 * The return type is the same as the argument type.
 *
 * @tparam Container type of container
 * @param[in] x container
 * @return Elementwise application of natural log to the argument.
 */
template <typename Container,
          require_not_container_st<std::is_arithmetic, Container>* = nullptr>
inline auto log(const Container& x) {
  return apply_scalar_unary<log_fun, Container>::apply(x);
}

/**
 * Version of `log()` that accepts std::vectors, Eigen Matrix/Array objects
 *  or expressions, and containers of these.
 *
 * @tparam Container Type of x
 * @param x Container
 * @return Natural log of each variable in the container.
 */
template <typename Container,
          require_container_st<std::is_arithmetic, Container>* = nullptr>
inline auto log(const Container& x) {
  return apply_vector_unary<Container>::apply(
      x, [](const auto& v) { return v.array().log(); });
}

namespace internal {
/**
 * Return the natural logarithm of the complex argument.
 *
 * @tparam V value type of argument
 * @param[in] z argument
 * @return natural logarithm of the argument
 */
template <typename V>
inline std::complex<V> complex_log(const std::complex<V>& z) {
  static const double inf = std::numeric_limits<double>::infinity();
  static const double nan = std::numeric_limits<double>::quiet_NaN();
  if ((is_nan(z.real()) && is_inf(z.imag()))
      || (is_inf(z.real()) && is_nan(z.imag()))) {
    return {inf, nan};
  }
  V r = sqrt(norm(z));
  V theta = arg(z);
  return {log(r), theta};
}
}  // namespace internal

}  // namespace math
}  // namespace stan
#endif
<commit_msg>restrict dependencies for prim/fun/log to prim<commit_after>#ifndef STAN_MATH_PRIM_FUN_LOG_HPP
#define STAN_MATH_PRIM_FUN_LOG_HPP

#include <stan/math/prim/meta.hpp>
#include <stan/math/prim/fun/Eigen.hpp>
#include <stan/math/prim/fun/isinf.hpp>
#include <stan/math/prim/fun/is_inf.hpp>
#include <stan/math/prim/fun/is_nan.hpp>
#include <cmath>
#include <complex>
#include <limits>

namespace stan {
namespace math {

/**
 * Structure to wrap `log()` so that it can be vectorized.
 */
struct log_fun {
  /**
   * Return natural log of specified argument.
   *
   * @tparam T type of argument
   * @param[in] x argument
   * @return Natural log of x.
   */
  template <typename T>
  static inline T fun(const T& x) {
    using std::log;
    return log(x);
  }
};

/**
 * Return the elementwise natural log of the specified argument,
 * which may be a scalar or any Stan container of numeric scalars.
 * The return type is the same as the argument type.
 *
 * @tparam Container type of container
 * @param[in] x container
 * @return Elementwise application of natural log to the argument.
 */
template <typename Container,
          require_not_container_st<std::is_arithmetic, Container>* = nullptr>
inline auto log(const Container& x) {
  return apply_scalar_unary<log_fun, Container>::apply(x);
}

/**
 * Version of `log()` that accepts std::vectors, Eigen Matrix/Array objects
 *  or expressions, and containers of these.
 *
 * @tparam Container Type of x
 * @param x Container
 * @return Natural log of each variable in the container.
 */
template <typename Container,
          require_container_st<std::is_arithmetic, Container>* = nullptr>
inline auto log(const Container& x) {
  return apply_vector_unary<Container>::apply(
      x, [](const auto& v) { return v.array().log(); });
}

namespace internal {
/**
 * Return the natural logarithm of the complex argument.
 *
 * @tparam V value type of argument
 * @param[in] z argument
 * @return natural logarithm of the argument
 */
template <typename V>
inline std::complex<V> complex_log(const std::complex<V>& z) {
  static const double inf = std::numeric_limits<double>::infinity();
  static const double nan = std::numeric_limits<double>::quiet_NaN();
  if ((is_nan(z.real()) && is_inf(z.imag()))
      || (is_inf(z.real()) && is_nan(z.imag()))) {
    return {inf, nan};
  }
  V r = sqrt(norm(z));
  V theta = arg(z);
  return {log(r), theta};
}
}  // namespace internal

}  // namespace math
}  // namespace stan
#endif
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: config.cxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-07 15:05:21 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#pragma hdrstop

#ifndef _SFXITEMSET_HXX //autogen
#include <svtools/itemset.hxx>
#endif
#ifndef _SFXHINT_HXX //autogen
#include <svtools/hint.hxx>
#endif
#ifndef _SFXSMPLHINT_HXX //autogen
#include <svtools/smplhint.hxx>
#endif
#ifndef INCLUDED_SVTOOLS_PATHOPTIONS_HXX
#include <svtools/pathoptions.hxx>
#endif
#ifndef _SFXSIDS_HRC //autogen
#include <sfx2/sfxsids.hrc>
#endif
#ifndef _SFXENUMITEM_HXX //autogen
#include <svtools/eitem.hxx>
#endif
#ifndef _SFXITEMPOOL_HXX //autogen
#include <svtools/itempool.hxx>
#endif
#ifndef _SFXSTRITEM_HXX //autogen
#include <svtools/stritem.hxx>
#endif
#ifndef _SFXINTITEM_HXX //autogen
#include <svtools/intitem.hxx>
#endif
#ifndef _STREAM_HXX
#include <tools/stream.hxx>
#endif

#ifndef CONFIG_HXX
#include "config.hxx"
#endif
#ifndef FORMAT_HXX
#include "format.hxx"
#endif
#ifndef _SMMOD_HXX
#include "smmod.hxx"
#endif
#ifndef _STARMATH_HRC
#include "starmath.hrc"
#endif

/////////////////////////////////////////////////////////////////

SmConfig::SmConfig()
{
}

SmConfig::~SmConfig()
{
}

void SmConfig::ItemSetToConfig(const SfxItemSet &rSet)
{
    const SfxPoolItem *pItem     = NULL;

    UINT16 nU16;
    BOOL bVal;
    if (rSet.GetItemState(SID_PRINTSIZE, TRUE, &pItem) == SFX_ITEM_SET)
    {   nU16 = ((const SfxUInt16Item *) pItem)->GetValue();
        SetPrintSize( (SmPrintSize) nU16 );
    }
    if (rSet.GetItemState(SID_PRINTZOOM, TRUE, &pItem) == SFX_ITEM_SET)
    {   nU16 = ((const SfxUInt16Item *) pItem)->GetValue();
        SetPrintZoomFactor( nU16 );
    }
    if (rSet.GetItemState(SID_PRINTTITLE, TRUE, &pItem) == SFX_ITEM_SET)
    {   bVal = ((const SfxBoolItem *) pItem)->GetValue();
        SetPrintTitle( bVal );
    }
    if (rSet.GetItemState(SID_PRINTTEXT, TRUE, &pItem) == SFX_ITEM_SET)
    {   bVal = ((const SfxBoolItem *) pItem)->GetValue();
        SetPrintFormulaText( bVal );
    }
    if (rSet.GetItemState(SID_PRINTFRAME, TRUE, &pItem) == SFX_ITEM_SET)
    {   bVal = ((const SfxBoolItem *) pItem)->GetValue();
        SetPrintFrame( bVal );
    }
    if (rSet.GetItemState(SID_AUTOREDRAW, TRUE, &pItem) == SFX_ITEM_SET)
    {   bVal = ((const SfxBoolItem *) pItem)->GetValue();
        SetAutoRedraw( bVal );
    }
    if (rSet.GetItemState(SID_NO_RIGHT_SPACES, TRUE, &pItem) == SFX_ITEM_SET)
    {   bVal = ((const SfxBoolItem *) pItem)->GetValue();
        if (IsIgnoreSpacesRight() != bVal)
        {
            SetIgnoreSpacesRight( bVal );

            // (angezeigte) Formeln muessen entsprechen neu formatiert werden.
            // Das erreichen wir mit:
            Broadcast(SfxSimpleHint(HINT_FORMATCHANGED));
        }
    }
}

void SmConfig::ConfigToItemSet(SfxItemSet &rSet) const
{
    const SfxItemPool *pPool = rSet.GetPool();

    rSet.Put(SfxUInt16Item(pPool->GetWhich(SID_PRINTSIZE),
                           (UINT16) GetPrintSize()));
    rSet.Put(SfxUInt16Item(pPool->GetWhich(SID_PRINTZOOM),
                           (UINT16) GetPrintZoomFactor()));

    rSet.Put(SfxBoolItem(pPool->GetWhich(SID_PRINTTITLE), IsPrintTitle()));
    rSet.Put(SfxBoolItem(pPool->GetWhich(SID_PRINTTEXT),  IsPrintFormulaText()));
    rSet.Put(SfxBoolItem(pPool->GetWhich(SID_PRINTFRAME), IsPrintFrame()));
    rSet.Put(SfxBoolItem(pPool->GetWhich(SID_AUTOREDRAW), IsAutoRedraw()));
    rSet.Put(SfxBoolItem(pPool->GetWhich(SID_NO_RIGHT_SPACES), IsIgnoreSpacesRight()));
}

/////////////////////////////////////////////////////////////////

<commit_msg>INTEGRATION: CWS swqbf40 (1.9.24); FILE MERGED 2005/10/17 12:54:08 tl 1.9.24.1: #i55936# calling of SaveOther/SaveForamt fixed. Configuration will now be updated (again).<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: config.cxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: hr $ $Date: 2005-10-27 15:55:23 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#pragma hdrstop

#ifndef _SFXITEMSET_HXX //autogen
#include <svtools/itemset.hxx>
#endif
#ifndef _SFXHINT_HXX //autogen
#include <svtools/hint.hxx>
#endif
#ifndef _SFXSMPLHINT_HXX //autogen
#include <svtools/smplhint.hxx>
#endif
#ifndef INCLUDED_SVTOOLS_PATHOPTIONS_HXX
#include <svtools/pathoptions.hxx>
#endif
#ifndef _SFXSIDS_HRC //autogen
#include <sfx2/sfxsids.hrc>
#endif
#ifndef _SFXENUMITEM_HXX //autogen
#include <svtools/eitem.hxx>
#endif
#ifndef _SFXITEMPOOL_HXX //autogen
#include <svtools/itempool.hxx>
#endif
#ifndef _SFXSTRITEM_HXX //autogen
#include <svtools/stritem.hxx>
#endif
#ifndef _SFXINTITEM_HXX //autogen
#include <svtools/intitem.hxx>
#endif
#ifndef _STREAM_HXX
#include <tools/stream.hxx>
#endif

#ifndef CONFIG_HXX
#include "config.hxx"
#endif
#ifndef FORMAT_HXX
#include "format.hxx"
#endif
#ifndef _SMMOD_HXX
#include "smmod.hxx"
#endif
#ifndef _STARMATH_HRC
#include "starmath.hrc"
#endif

/////////////////////////////////////////////////////////////////

SmConfig::SmConfig()
{
}

SmConfig::~SmConfig()
{
}

void SmConfig::ItemSetToConfig(const SfxItemSet &rSet)
{
    const SfxPoolItem *pItem     = NULL;

    UINT16 nU16;
    BOOL bVal;
    if (rSet.GetItemState(SID_PRINTSIZE, TRUE, &pItem) == SFX_ITEM_SET)
    {   nU16 = ((const SfxUInt16Item *) pItem)->GetValue();
        SetPrintSize( (SmPrintSize) nU16 );
    }
    if (rSet.GetItemState(SID_PRINTZOOM, TRUE, &pItem) == SFX_ITEM_SET)
    {   nU16 = ((const SfxUInt16Item *) pItem)->GetValue();
        SetPrintZoomFactor( nU16 );
    }
    if (rSet.GetItemState(SID_PRINTTITLE, TRUE, &pItem) == SFX_ITEM_SET)
    {   bVal = ((const SfxBoolItem *) pItem)->GetValue();
        SetPrintTitle( bVal );
    }
    if (rSet.GetItemState(SID_PRINTTEXT, TRUE, &pItem) == SFX_ITEM_SET)
    {   bVal = ((const SfxBoolItem *) pItem)->GetValue();
        SetPrintFormulaText( bVal );
    }
    if (rSet.GetItemState(SID_PRINTFRAME, TRUE, &pItem) == SFX_ITEM_SET)
    {   bVal = ((const SfxBoolItem *) pItem)->GetValue();
        SetPrintFrame( bVal );
    }
    if (rSet.GetItemState(SID_AUTOREDRAW, TRUE, &pItem) == SFX_ITEM_SET)
    {   bVal = ((const SfxBoolItem *) pItem)->GetValue();
        SetAutoRedraw( bVal );
    }
    if (rSet.GetItemState(SID_NO_RIGHT_SPACES, TRUE, &pItem) == SFX_ITEM_SET)
    {   bVal = ((const SfxBoolItem *) pItem)->GetValue();
        if (IsIgnoreSpacesRight() != bVal)
        {
            SetIgnoreSpacesRight( bVal );

            // (angezeigte) Formeln muessen entsprechen neu formatiert werden.
            // Das erreichen wir mit:
            Broadcast(SfxSimpleHint(HINT_FORMATCHANGED));
        }
    }

    SaveOther();
}

void SmConfig::ConfigToItemSet(SfxItemSet &rSet) const
{
    const SfxItemPool *pPool = rSet.GetPool();

    rSet.Put(SfxUInt16Item(pPool->GetWhich(SID_PRINTSIZE),
                           (UINT16) GetPrintSize()));
    rSet.Put(SfxUInt16Item(pPool->GetWhich(SID_PRINTZOOM),
                           (UINT16) GetPrintZoomFactor()));

    rSet.Put(SfxBoolItem(pPool->GetWhich(SID_PRINTTITLE), IsPrintTitle()));
    rSet.Put(SfxBoolItem(pPool->GetWhich(SID_PRINTTEXT),  IsPrintFormulaText()));
    rSet.Put(SfxBoolItem(pPool->GetWhich(SID_PRINTFRAME), IsPrintFrame()));
    rSet.Put(SfxBoolItem(pPool->GetWhich(SID_AUTOREDRAW), IsAutoRedraw()));
    rSet.Put(SfxBoolItem(pPool->GetWhich(SID_NO_RIGHT_SPACES), IsIgnoreSpacesRight()));
}

/////////////////////////////////////////////////////////////////

<|endoftext|>


<commit_before>/*------------------------------------------------------------------------------
| This file is distributed under the BSD 2-Clause License.
| See LICENSE for details.
*-----------------------------------------------------------------------------*/
#pragma once

#include <cassert>
#include <cstdint>

namespace lsy {

/*------------------------------------------------------------------------------
| cube32
| ------
| TLDR: efficient cube data structure for Boolean functions with up to 32
|       variables
|
| A cube is the Boolean AND or 'k' literals. Given a Boolean function with N
| variables, there are 2*N literals. In a cube of this function each literal
| can either appear as a positive literal ('1'), as a negative literal ('0') or
| not appear at all (don't care, '-').
|
| Since each literal can assume one to these three values, we need at least two
| bits to represent the state of each literal. Thus, if we limit the number of
| variables in the function to 32, it's clear we only need 64 bits to encode a
| cube.
|
| Here, 'mask' tells us if a literal appears ('1') or not ('0' - don't care).
| For the cases where the literal appears in the cube, the 'polarity' indicates
| it's polarity (duh :)
|
| * A constant 1 is represented by all literal being don't care.
*-----------------------------------------------------------------------------*/
struct cube32 {
	using ui32_t = std::uint32_t;
	using ui64_t = std::uint64_t;
	using c32_t  = struct cube32;

	union {
		struct {
			ui32_t polarity;
			ui32_t mask;
		};
		ui64_t value;
	};

	cube32()
	: value{0u}
	{ }

	cube32(const ui64_t v)
	: value{v}
	{ }

	constexpr cube32(const ui32_t m, const ui32_t p)
	: polarity{p}, mask{m}
	{ }

	bool operator==(const c32_t that) const
	{ return value == that.value; }

	bool operator!=(const c32_t that) const
	{ return value != that.value; }

	bool operator< (const c32_t that) const
	{ return value <  that.value; }

	bool operator==(const ui64_t v) const
	{ return value == v; }

	bool operator!=(const ui64_t v) const
	{ return value != v; }

	c32_t operator&(const c32_t that) const
	{
		const auto tmp_mask = mask & that.mask;
		if ((polarity ^ that.polarity) & tmp_mask)
			return cube32{0xFFFFFFFFu, 0x00000000u};
		return cube32{value | that.value};
	}

	ui32_t n_lits() const
	{ return __builtin_popcount(mask); }

	void add_lit(const ui32_t var, const ui32_t p)
	{
		assert(p <= 1);
		mask |= (1 << var);
		polarity |= (p << var);
	}
};

constexpr auto cube32_zero = cube32{0xFFFFFFFFu, 0x00000000u};
constexpr auto cube32_one  = cube32{0u, 0u};

} // namespace lsy
<commit_msg>Adding "normal" include guards.<commit_after>/*------------------------------------------------------------------------------
| This file is distributed under the BSD 2-Clause License.
| See LICENSE for details.
*-----------------------------------------------------------------------------*/
#ifndef LOSYS_CUBE32_HPP
#define LOSYS_CUBE32_HPP

#include <cassert>
#include <cstdint>

namespace lsy {

/*------------------------------------------------------------------------------
| cube32
| ------
| TLDR: efficient cube data structure for Boolean functions with up to 32
|       variables
|
| A cube is the Boolean AND or 'k' literals. Given a Boolean function with N
| variables, there are 2*N literals. In a cube of this function each literal
| can either appear as a positive literal ('1'), as a negative literal ('0') or
| not appear at all (don't care, '-').
|
| Since each literal can assume one to these three values, we need at least two
| bits to represent the state of each literal. Thus, if we limit the number of
| variables in the function to 32, it's clear we only need 64 bits to encode a
| cube.
|
| Here, 'mask' tells us if a literal appears ('1') or not ('0' - don't care).
| For the cases where the literal appears in the cube, the 'polarity' indicates
| it's polarity (duh :)
|
| * A constant 1 is represented by all literal being don't care.
*-----------------------------------------------------------------------------*/
struct cube32 {
	using ui32_t = std::uint32_t;
	using ui64_t = std::uint64_t;
	using c32_t  = struct cube32;

	union {
		struct {
			ui32_t polarity;
			ui32_t mask;
		};
		ui64_t value;
	};

	cube32()
	: value{0u}
	{ }

	cube32(const ui64_t v)
	: value{v}
	{ }

	constexpr cube32(const ui32_t m, const ui32_t p)
	: polarity{p}, mask{m}
	{ }

	bool operator==(const c32_t that) const
	{ return value == that.value; }

	bool operator!=(const c32_t that) const
	{ return value != that.value; }

	bool operator< (const c32_t that) const
	{ return value <  that.value; }

	bool operator==(const ui64_t v) const
	{ return value == v; }

	bool operator!=(const ui64_t v) const
	{ return value != v; }

	c32_t operator&(const c32_t that) const
	{
		const auto tmp_mask = mask & that.mask;
		if ((polarity ^ that.polarity) & tmp_mask)
			return cube32{0xFFFFFFFFu, 0x00000000u};
		return cube32{value | that.value};
	}

	ui32_t n_lits() const
	{ return __builtin_popcount(mask); }

	void add_lit(const ui32_t var, const ui32_t p)
	{
		assert(p <= 1);
		mask |= (1 << var);
		polarity |= (p << var);
	}
};

constexpr auto cube32_zero = cube32{0xFFFFFFFFu, 0x00000000u};
constexpr auto cube32_one  = cube32{0u, 0u};

} // namespace lsy

#endif
<|endoftext|>


<commit_before>// Copyright 2013 Mirus Project

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

// http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//
// kernel.cpp - main source file + kernel entry point
//              we all have to begin somewhere, right?
//

#include <stdafx.hpp>
#include <boot/multiboot.hpp>

#include <cpu/gdt.hpp>
#include <cpu/idt.hpp>
#include <cpu/isr.hpp>
#include <cpu/irq.hpp>

#include <hardware/timer.hpp>
#include <hardware/serial.hpp>
#include <hardware/rtc.hpp>

#include <msg/message_handler.hpp>
#include <msg/message.hpp>

namespace mirus
{
    //
    // kernel_main - our kernel entry point
    //
    extern "C" void kernel_main(multiboot_info_t* mbd,
        unsigned int magic)
    {
        // Print debug stub
        debug::debugger::writeln("[log] Mirus 0.2.5-dev");
        debug::debugger::flush();

        uintptr_t ramdisk_top = 0;
        char*     ramdisk;

        // Get avalible memory
        if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
            debug::debugger::writeln("[error] Multiboot bootloader magic doesn't match!");

        int memory_size = 0;

        if (mbd->flags & 1)
        {
            debug::debugger::writeln("[log] Reading multiboot header");

            memory_map_t* mmap = (memory_map_t*)mbd->mmap_addr;

            // parse entries
            while ((unsigned int)mmap < (unsigned int)(mbd->mmap_addr) + mbd->mmap_length)
            {
                memory_size += mmap->length_low;
                mmap = (memory_map_t*)((unsigned int)mmap + mmap->size + sizeof(unsigned int));
            }

            debug::debugger::write("[log] Avalible memory: ");
            debug::debugger::write((memory_size / 1024) / 1024);
            debug::debugger::writeln("m");

            debug::debugger::writeln("[log] Trying to get ramdisk.");

            // Check for any modules, the only of which should be the ramdisk
            if (mbd->mods_count > 0)
            {
                uint32_t* module_start = ((uint32_t*)mbd->mods_addr);
                uint32_t* module_end   = ((uint32_t*)(mbd->mods_addr + 4));
                ramdisk                = (char*)0x30000000;
                ramdisk_top            = (uintptr_t)ramdisk + (module_end - module_start);

                // TODO: do we need to move the ramdisk somewhere
                //       more convinient

                debug::debugger::write("[log] Ramdisk top: ");
                debug::debugger::writeln((const char*)ramdisk_top);
            }
            else
            {
                debug::debugger::writeln("[log] No modules found.");
            }
        }

        if (((memory_size / 1024) / 1024) < 512)
            debug::debugger::writeln("[warning] Memory is less than expected minimum");

        // Install CPU hardware devices
        cpu::gdt::install();
        cpu::idt::install();
        cpu::isr::install();
        cpu::irq::install();

        // Set up screen
        screen::terminal::install();

        // Set up additional hardware
        hardware::pit::install();
        hardware::serial::install();

        // Testing the message system
        system::message_t msg;
        msg.pid_sender = 0;
        msg.pid_dest = 0;
        msg.priority = 0;
        msg.type = (int)system::message_request_type::pingback;
        msg.data = "this is your kernel speaking, enjoy the ride.";

        // message_handler::dispatch_message(msg);

        // WE MUST NEVER RETURN!!!!
        while (true);
    }
} // !namespace
<commit_msg>Find those modules!<commit_after>// Copyright 2013 Mirus Project

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

// http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//
// kernel.cpp - main source file + kernel entry point
//              we all have to begin somewhere, right?
//

#include <stdafx.hpp>
#include <boot/multiboot.hpp>

#include <cpu/gdt.hpp>
#include <cpu/idt.hpp>
#include <cpu/isr.hpp>
#include <cpu/irq.hpp>

#include <hardware/timer.hpp>
#include <hardware/serial.hpp>
#include <hardware/rtc.hpp>

#include <msg/message_handler.hpp>
#include <msg/message.hpp>

namespace mirus
{
    //
    // kernel_main - our kernel entry point
    //
    extern "C" void kernel_main(multiboot_info_t* mbd,
        unsigned int magic)
    {
        // Print debug stub
        debug::debugger::writeln("[log] Mirus 0.2.5-dev");
        debug::debugger::flush();

        uintptr_t ramdisk_top = 0;
        char*     ramdisk;

        // Get avalible memory
        if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
            debug::debugger::writeln("[error] Multiboot bootloader magic doesn't match!");

        int memory_size = 0;

        if (mbd->flags & 1)
        {
            debug::debugger::writeln("[log] Reading multiboot header");

            memory_map_t* mmap = (memory_map_t*)mbd->mmap_addr;

            // parse entries
            while ((unsigned int)mmap < (unsigned int)(mbd->mmap_addr) + mbd->mmap_length)
            {
                memory_size += mmap->length_low;
                mmap = (memory_map_t*)((unsigned int)mmap + mmap->size + sizeof(unsigned int));
            }

            debug::debugger::write("[log] Avalible memory: ");
            debug::debugger::write((memory_size / 1024) / 1024);
            debug::debugger::writeln("m");

            debug::debugger::writeln("[log] Trying to get ramdisk.");

            // Check for any modules, the only of which should be the ramdisk
            if (mbd->mods_count > 0)
            {
                debug::debugger::write("[log] Modules found: ");
                debug::debugger::write((int)mbd->mods_count);
                debug::debugger::flush();

                uint32_t* module_start = ((uint32_t*)mbd->mods_addr);
                uint32_t* module_end   = ((uint32_t*)(mbd->mods_addr + 4));

                // TODO: do we need to move the ramdisk somewhere
                //       more convinient

                debug::debugger::write("[log] Module start: ");
                debug::debugger::write((int)&module_start);
                debug::debugger::flush();
            }
            else
            {
                debug::debugger::writeln("[log] No modules found.");
            }
        }

        if (((memory_size / 1024) / 1024) < 512)
            debug::debugger::writeln("[warning] Memory is less than expected minimum");

        // Install CPU hardware devices
        cpu::gdt::install();
        cpu::idt::install();
        cpu::isr::install();
        cpu::irq::install();

        // Set up screen
        screen::terminal::install();

        // Set up additional hardware
        hardware::pit::install();
        hardware::serial::install();

        // Testing the message system
        system::message_t msg;
        msg.pid_sender = 0;
        msg.pid_dest = 0;
        msg.priority = 0;
        msg.type = (int)system::message_request_type::pingback;
        msg.data = "this is your kernel speaking, enjoy the ride.";

        // message_handler::dispatch_message(msg);

        // WE MUST NEVER RETURN!!!!
        while (true);
    }
} // !namespace
<|endoftext|>


<commit_before>//
//  Area.cpp
//  Phantasma
//
//  Created by Thomas Harte on 25/12/2013.
//  Copyright (c) 2013 Thomas Harte. All rights reserved.
//

#include "Area.h"
#include "Object.h"
#include <list>

Object *Area::objectWithIDFromMap(ObjectMap *map, uint16_t objectID)
{
	if(!map) return NULL;
	if(!map->count(objectID)) return NULL;
	return (*map)[objectID];
}

Object *Area::objectWithID(uint16_t objectID)
{
	return objectWithIDFromMap(objectsByID, objectID);
}

Object *Area::entranceWithID(uint16_t objectID)
{
	return objectWithIDFromMap(entrancesByID, objectID);
}

uint16_t Area::getAreaID()
{
	return areaID;
}

Area::Area(
	uint16_t _areaID,
	ObjectMap *_objectsByID,
	ObjectMap *_entrancesByID)
{
	areaID = _areaID;
	objectsByID = _objectsByID;
	entrancesByID = _entrancesByID;
	areaBuffer = nullptr;

	// create a list of drawable obejcts only
//	int c = 0;
	for(ObjectMap::iterator iterator = objectsByID->begin(); iterator != objectsByID->end(); iterator++)
	{
		if(iterator->second->isDrawable())
		{
//			c++;
//			if(
//				(c == 5) ||
//				(c == 6) ||
//				(c == 7)
//			)
				drawableObjects.push_back(iterator->second);
		}
	}
}

Area::~Area()
{
	for(ObjectMap::iterator iterator = entrancesByID->begin(); iterator != entrancesByID->end(); iterator++)
		delete iterator->second;

	for(ObjectMap::iterator iterator = objectsByID->begin(); iterator != objectsByID->end(); iterator++)
		delete iterator->second;

	delete entrancesByID;
	delete objectsByID;
}

void Area::setupOpenGL()
{
	delete areaBuffer;
	areaBuffer = GeometricObject::newVertexBuffer();

	for(ObjectMap::iterator iterator = objectsByID->begin(); iterator != objectsByID->end(); iterator++)
		iterator->second->setupOpenGL(areaBuffer);
}

int compareObjects(Object *object1, Object *object2, float *position)
{
	Vector3d objectOrigins[2]	= {	object1->getOrigin(),	object2->getOrigin()	};
	Vector3d objectSizes[2]		= {	object1->getSize(),		object2->getSize()		};

	int results[3] = {0, 0, 0};

	for(int axis = 0; axis < 3; axis++)
	{
		// figure out which box is lower down this axis than the other
		int invertResult;
		int lowerObject;

		if(objectOrigins[1][axis] < objectOrigins[0][axis])
		{
			invertResult = -1;
			lowerObject = 1;
		}
		else
		{
			invertResult = 1;
			lowerObject = 0;
		}

		// is there a separating plane between these two at all?
		uint16_t endOfLowerObject = objectOrigins[lowerObject][axis] + objectSizes[lowerObject][axis];
		if(endOfLowerObject <= objectOrigins[lowerObject ^ 1][axis])
		{
			// if so, is the player positioned within the gap? We don't have
			// an opinion on draw order if that's the case
			if((position[axis] < endOfLowerObject) || (position[axis] >  objectOrigins[lowerObject ^ 1][axis]))
			{
				int result = (position[axis] >= endOfLowerObject) ? 1 : -1;
				result *= invertResult;
				results[axis] = result;
			}
		}
	}

	// if no opinion was expressed then the two are coplanar, so compare by ID
	if(!results[0] && !results[1] && !results[2])
		return (object1->getObjectID() < object2->getObjectID()) ? -1 : 1;

	// otherwise we need all axes with opinions to match
	int result = 0;
	for(int c = 0; c < 3; c++)
	{
		if(results[c])
		{
			if(!result)
			{
				result = results[c];
			}
			else
			{
				if(results[c] != result)
					return 0;
			}
		}
	}

	return result;
}

void Area::draw(float *playerPosition)
{
	/*
		Here's a relic for you: we're going to use painter's algorithm
		(ie, back-to-front drawing, no depth testing, overdraw to obscure)
		to draw the scene. Why? Because:

			(1)	the original engine appears to use the painter's algorith;
				I've concluded this by observing that it cannot deal with
				mutual overlap;

			(2)	because the original engine uses painter's algorithm and
				because of the geometry involved it's standard practive to
				use coplanar geometry for doors and adornments;

			(3)	depth buffers deal very poorly with coplanar geometry,
				with even use of polygon offsets being difficult to scale
				to the arbitrary case; and

			(4)	with the tiny amount of geometry involved and absolutely
				trivial single-coloured surfaces involved, the cost of
				overdraw is not a concern.

	*/
	std::list <Object *> orderedObjects;

	for(std::vector<Object *>::iterator incomingIterator = drawableObjects.begin(); incomingIterator != drawableObjects.end(); incomingIterator++)
	{
		bool didInsert = false;

		for(std::list<Object *>::iterator existingIterator = orderedObjects.begin(); existingIterator != orderedObjects.end(); existingIterator++)
		{
			int comparison = compareObjects(*incomingIterator, *existingIterator, playerPosition);

			if(comparison > 0)
			{
				didInsert = true;
				orderedObjects.insert(existingIterator, *incomingIterator);
				break;
			}
		}

		if(!didInsert)
			orderedObjects.push_back(*incomingIterator);
	}

	for(std::list<Object *>::iterator iterator = orderedObjects.begin(); iterator != orderedObjects.end(); iterator++)
	{
		(*iterator)->draw(areaBuffer);
	}
}
<commit_msg>Fixed: the object ID comparison occurs only if no separating axis was found.<commit_after>//
//  Area.cpp
//  Phantasma
//
//  Created by Thomas Harte on 25/12/2013.
//  Copyright (c) 2013 Thomas Harte. All rights reserved.
//

#include "Area.h"
#include "Object.h"
#include <list>

Object *Area::objectWithIDFromMap(ObjectMap *map, uint16_t objectID)
{
	if(!map) return NULL;
	if(!map->count(objectID)) return NULL;
	return (*map)[objectID];
}

Object *Area::objectWithID(uint16_t objectID)
{
	return objectWithIDFromMap(objectsByID, objectID);
}

Object *Area::entranceWithID(uint16_t objectID)
{
	return objectWithIDFromMap(entrancesByID, objectID);
}

uint16_t Area::getAreaID()
{
	return areaID;
}

Area::Area(
	uint16_t _areaID,
	ObjectMap *_objectsByID,
	ObjectMap *_entrancesByID)
{
	areaID = _areaID;
	objectsByID = _objectsByID;
	entrancesByID = _entrancesByID;
	areaBuffer = nullptr;

	// create a list of drawable obejcts only
//	int c = 0;
	for(ObjectMap::iterator iterator = objectsByID->begin(); iterator != objectsByID->end(); iterator++)
	{
		if(iterator->second->isDrawable())
		{
//			c++;
//			if(
//				(c == 5) ||
//				(c == 6) ||
//				(c == 7)
//			)
				drawableObjects.push_back(iterator->second);
		}
	}
}

Area::~Area()
{
	for(ObjectMap::iterator iterator = entrancesByID->begin(); iterator != entrancesByID->end(); iterator++)
		delete iterator->second;

	for(ObjectMap::iterator iterator = objectsByID->begin(); iterator != objectsByID->end(); iterator++)
		delete iterator->second;

	delete entrancesByID;
	delete objectsByID;
}

void Area::setupOpenGL()
{
	delete areaBuffer;
	areaBuffer = GeometricObject::newVertexBuffer();

	for(ObjectMap::iterator iterator = objectsByID->begin(); iterator != objectsByID->end(); iterator++)
		iterator->second->setupOpenGL(areaBuffer);
}

int compareObjects(Object *object1, Object *object2, float *position)
{
	Vector3d objectOrigins[2]	= {	object1->getOrigin(),	object2->getOrigin()	};
	Vector3d objectSizes[2]		= {	object1->getSize(),		object2->getSize()		};

	int results[3] = {0, 0, 0};
	int separations = 0;

	for(int axis = 0; axis < 3; axis++)
	{
		// figure out which box is lower down this axis than the other
		int invertResult;
		int lowerObject;

		if(objectOrigins[1][axis] < objectOrigins[0][axis])
		{
			invertResult = -1;
			lowerObject = 1;
		}
		else
		{
			invertResult = 1;
			lowerObject = 0;
		}

		// is there a separating plane between these two at all?
		uint16_t endOfLowerObject = objectOrigins[lowerObject][axis] + objectSizes[lowerObject][axis];
		if(endOfLowerObject <= objectOrigins[lowerObject ^ 1][axis])
		{
			// if so, is the player positioned within the gap? We don't have
			// an opinion on draw order if that's the case
			if((position[axis] < endOfLowerObject) || (position[axis] >  objectOrigins[lowerObject ^ 1][axis]))
			{
				int result = (position[axis] >= endOfLowerObject) ? 1 : -1;
				result *= invertResult;
				results[axis] = result;
			}
		}
		else
			separations |= (1 << axis);
	}

	// if no opinion was expressed then the two are coplanar, so compare by ID
	if(separations == 0x7)
		return (object1->getObjectID() < object2->getObjectID()) ? -1 : 1;

	// otherwise we need all axes with opinions to match
	int result = 0;
	for(int c = 0; c < 3; c++)
	{
		if(results[c])
		{
			if(!result)
			{
				result = results[c];
			}
			else
			{
				if(results[c] != result)
					return 0;
			}
		}
	}

	return result;
}

void Area::draw(float *playerPosition)
{
	/*
		Here's a relic for you: we're going to use painter's algorithm
		(ie, back-to-front drawing, no depth testing, overdraw to obscure)
		to draw the scene. Why? Because:

			(1)	the original engine appears to use the painter's algorith;
				I've concluded this by observing that it cannot deal with
				mutual overlap;

			(2)	because the original engine uses painter's algorithm and
				because of the geometry involved it's standard practive to
				use coplanar geometry for doors and adornments;

			(3)	depth buffers deal very poorly with coplanar geometry,
				with even use of polygon offsets being difficult to scale
				to the arbitrary case; and

			(4)	with the tiny amount of geometry involved and absolutely
				trivial single-coloured surfaces involved, the cost of
				overdraw is not a concern.

	*/
	std::list <Object *> orderedObjects;

	for(std::vector<Object *>::iterator incomingIterator = drawableObjects.begin(); incomingIterator != drawableObjects.end(); incomingIterator++)
	{
		bool didInsert = false;

		for(std::list<Object *>::iterator existingIterator = orderedObjects.begin(); existingIterator != orderedObjects.end(); existingIterator++)
		{
			int comparison = compareObjects(*incomingIterator, *existingIterator, playerPosition);

			if(comparison > 0)
			{
				didInsert = true;
				orderedObjects.insert(existingIterator, *incomingIterator);
				break;
			}
		}

		if(!didInsert)
			orderedObjects.push_back(*incomingIterator);
	}

	for(std::list<Object *>::iterator iterator = orderedObjects.begin(); iterator != orderedObjects.end(); iterator++)
	{
		(*iterator)->draw(areaBuffer);
	}
}
<|endoftext|>


<commit_before>#include "nimble/nimbleGraph.h"

graphNode::graphNode(int inputCgraphID, NODETYPE inputType, const string &inputName ) :
  role(UNKNOWNROLE),
  type(inputType),
  CgraphID(inputCgraphID),
  name(inputName),
  touched(false),
  numChildren(0) {
  RgraphID = CgraphID + 1;
};

void graphNode::addChild( graphNode *toNode, int childParentExpressionID) {
#ifdef _DEBUGNIMGRAPH
  PRINTF("adding child %s to parent %s\n", toNode->name.c_str(), name.c_str());
#endif
  children.push_back(toNode);
  childrenParentExpressionIDs.push_back(childParentExpressionID);
  numChildren++;
  toNode->addParent(this);
};

void graphNode::addParent(graphNode *fromNode) {
#ifdef _DEBUGNIMGRAPH
  PRINTF("adding parent %s to child %s\n", fromNode->name.c_str(), name.c_str());
#endif
  parents.push_back(fromNode);
};

void SEXP_2_nodeType(SEXP Stypes, vector<NODETYPE> &ans) {
  //  enum NODETYPE {UNKNOWNTYPE, STOCH, DETERM, RHSONLY};
  if(!isString(Stypes)) {
    PRINTF("Error:  called for SEXP that is not a string!\n");
    return;
  }
  int nn = LENGTH(Stypes);
  ans.resize(nn);
  string oneString;
  for(int i = 0; i < nn; i++) {
    oneString.assign(CHAR(STRING_ELT(Stypes, i)), LENGTH(STRING_ELT(Stypes, i)));
    if(oneString == "stoch")
      ans[i] = STOCH;
    else if(oneString == "determ")
      ans[i] = DETERM;
    else if(oneString == "RHSonly")
      ans[i] = RHSONLY;
    else if(oneString == "LHSinferred")
      ans[i] = LHSINFERRED;
    else if(oneString == "unknown")
      ans[i] = UNKNOWNTYPE;
    else {
      ans[i] = UNKNOWNTYPE;
      PRINTF("In SEXP_2_nodeType: unknown string type label %s\n", oneString.c_str());
    }
  }
}

SEXP setGraph(SEXP SedgesFrom, SEXP SedgesTo, SEXP SedgesFrom2ParentExprIDs, SEXP Stypes, SEXP Snames, SEXP SnumNodes) {
  vector<int> edgesFrom = SEXP_2_vectorInt(SedgesFrom, -1); // -1 subtracted here
  vector<int> edgesTo = SEXP_2_vectorInt(SedgesTo, -1); // -1 substracted here
  vector<int> edgesFrom2ParentExprIDs = SEXP_2_vectorInt(SedgesFrom2ParentExprIDs);
  vector<NODETYPE> types;
  SEXP_2_nodeType(Stypes, types);
  vector<string> names;
  STRSEXP_2_vectorString(Snames, names);
  int numNodes = SEXP_2_int(SnumNodes);
  nimbleGraph *newGraph = new nimbleGraph;
  newGraph->setNodes(edgesFrom, edgesTo, edgesFrom2ParentExprIDs, types, names, numNodes);
  SEXP SextPtrAns;
  PROTECT(SextPtrAns = R_MakeExternalPtr(newGraph, R_NilValue, R_NilValue));
  R_RegisterCFinalizerEx(SextPtrAns, &nimbleGraphFinalizer, TRUE);
  UNPROTECT(1);
  return(SextPtrAns);
};

void nimbleGraphFinalizer(SEXP SgraphExtPtr) {
  nimbleGraph *graphPtr = static_cast<nimbleGraph *>(R_ExternalPtrAddr(SgraphExtPtr));
  delete graphPtr;
}

nimbleGraph::~nimbleGraph() {
  int n = graphNodeVec.size();
  for(int i = 0; i < n; i++) {
    delete graphNodeVec[i];
  }
}

SEXP anyStochDependencies(SEXP SgraphExtPtr) {
  nimbleGraph *graphPtr = static_cast<nimbleGraph *>(R_ExternalPtrAddr(SgraphExtPtr));
  vector<int> ans(graphPtr->anyStochDependencies());
  SEXP Sans;
  PROTECT(Sans = allocVector(LGLSXP, ans.size()));
  int *SansPtr = INTEGER(Sans);
  for(int i = 0; i < ans.size(); i++) {
    if(ans[i] == 0) PRINTF("Element %i was not processed\n", i);
    SansPtr[i] = ans[i]==2 ? 1 : 0;
  }
  UNPROTECT(1);
  return(Sans);
}

SEXP getDependencies(SEXP SgraphExtPtr, SEXP Snodes, SEXP Somit, SEXP Sdownstream) {
  nimbleGraph *graphPtr = static_cast<nimbleGraph *>(R_ExternalPtrAddr(SgraphExtPtr));
  vector<int> nodes = SEXP_2_vectorInt(Snodes, -1); // subtract 1 index for C
  vector<int> omit = SEXP_2_vectorInt(Somit, -1);
  bool downstream = SEXP_2_bool(Sdownstream);
  vector<int> ans = graphPtr->getDependencies(nodes, omit, downstream);
  return(vectorInt_2_SEXP(ans, 1)); // add 1 index for R
}

SEXP anyStochParents(SEXP SgraphExtPtr) {
  nimbleGraph *graphPtr = static_cast<nimbleGraph *>(R_ExternalPtrAddr(SgraphExtPtr));
  vector<int> ans(graphPtr->anyStochParents());
  SEXP Sans;
  PROTECT(Sans = allocVector(LGLSXP, ans.size()));
  int *SansPtr = INTEGER(Sans);
  for(int i = 0; i < ans.size(); i++) {
    if(ans[i] == 0) PRINTF("Element %i was not processed\n", i);
    SansPtr[i] = ans[i]==2 ? 1 : 0;
  }
  UNPROTECT(1);
  return(Sans);
}

void nimbleGraph::setNodes(const vector<int> &edgesFrom, const vector<int> &edgesTo,
		     const vector<int> &edgesFrom2ParentExprIDs,
		     const vector<NODETYPE> &types,
		     const vector<string> &names,
		     int inputNumNodes) {
  numNodes = inputNumNodes;
  int numEdges = edgesFrom.size();

#ifdef _DEBUGNIMGRAPH
  PRINTF("numNodes %i\n", numNodes);
  PRINTF("numEdges %i\n", numEdges);
#endif
  if(numEdges != edgesTo.size() | numEdges != edgesFrom2ParentExprIDs.size() | numNodes != types.size() | numNodes != names.size()) {
    PRINTF("Something is not the right size\n");
    return;
  }
  graphNodeVec.resize(numNodes);
  for(int iNode = 0; iNode < numNodes; iNode++) {
    graphNodeVec[iNode] = new graphNode(iNode, types[iNode], names[iNode]);
  }
  for(int iEdge = 0; iEdge < numEdges; iEdge++) {
    graphNodeVec[ edgesFrom[iEdge]]->addChild( graphNodeVec[edgesTo[iEdge]], edgesFrom2ParentExprIDs[iEdge] );
  }
}

vector<int> nimbleGraph::anyStochDependencies() {
  vector<int> ans(numNodes, 0);
  for(int i = 0; i < numNodes; i++) {
    anyStochDependenciesOneNode(ans, i);
  }
  return(ans);
}

bool nimbleGraph::anyStochDependenciesOneNode(vector<int> &anyStochDependencies, int CgraphID) {
  // 0 = untouched, 1 = false, 2 = true
  if(anyStochDependencies[CgraphID] != 0) return(anyStochDependencies[CgraphID] == 2);
  bool thisHasAstochDep(false);
  graphNode *thisGraphNode = graphNodeVec[CgraphID];
  graphNode *thisChildNode;
  int numChildren = thisGraphNode->numChildren;
  /* If no children, answer is false */
  if(numChildren == 0) {
    anyStochDependencies[CgraphID] = 1;
    return(false);
  }
  int i(0);
  /* Check type of children without recursing.  If any are STOCH, answer is true */
  while((i < numChildren) & (!thisHasAstochDep)) {
    if(thisGraphNode->children[i]->type == STOCH) {
      thisHasAstochDep = true;
    }
    i++;
  }
  /* If answer was true, we're done */
  if(thisHasAstochDep) {
    anyStochDependencies[CgraphID] = 2;
    return(true);
  }
  /* all children were not STOCH, so now recurse through children */
  i = 0;
  while((i < numChildren) & (!thisHasAstochDep)) {
    thisChildNode = thisGraphNode->children[i];
    if(anyStochDependenciesOneNode(anyStochDependencies, thisChildNode->CgraphID)) {
      thisHasAstochDep = true;
    }
    i++;
  }
  if(thisHasAstochDep) {
    anyStochDependencies[CgraphID] = 2;
    return(true);
  }
  anyStochDependencies[CgraphID] = 1;
  return(false);
}

vector<int> nimbleGraph::anyStochParents() {
  vector<int> ans(numNodes, 0);
  for(int i = numNodes - 1; i >= 0; i--) {
    anyStochParentsOneNode(ans, i);
  }
  return(ans);
}

bool nimbleGraph::anyStochParentsOneNode(vector<int> &anyStochParents, int CgraphID) {
  // 0 = untouched, 1 = false, 2 = true
  if(anyStochParents[CgraphID] != 0) return(anyStochParents[CgraphID] == 2);
  bool thisHasAstochParent(false);
  graphNode *thisGraphNode = graphNodeVec[CgraphID];
  graphNode *thisParentNode;
  int numParents = thisGraphNode->parents.size();
  if(numParents == 0) {
    anyStochParents[CgraphID] = 1;
    return(false);
  }
  int i(0);
  while((i < numParents) & (!thisHasAstochParent)) {
    if(thisGraphNode->parents[i]->type == STOCH) {
      thisHasAstochParent = true;
    }
    i++;
  }
  if(thisHasAstochParent) {
    anyStochParents[CgraphID] = 2;
    return(true);
  }
  i = 0;
  while((i < numParents) & (!thisHasAstochParent)) {
    thisParentNode = thisGraphNode->parents[i];
    if(anyStochParentsOneNode(anyStochParents, thisParentNode->CgraphID)) {
      thisHasAstochParent = true;
    }
    i++;
  }
  if(thisHasAstochParent) {
    anyStochParents[CgraphID] = 2;
    return(true);
  }
  anyStochParents[CgraphID] = 1;
  return(false);
}

//#define _DEBUG_GETDEPS

vector<int> nimbleGraph::getDependencies(const vector<int> &Cnodes, const vector<int> &Comit, bool downstream) {
  // assume on entry that touched = false on all nodes
  // Cnodes and Comit are C-indices (meaning they start at 0)
  int n = Comit.size();
  int i;
  vector<int> ans;
  // touch omit nodes
#ifdef _DEBUG_GETDEPS
  int iDownstream = static_cast<int>(downstream);
  PRINTF("debugging output for getDependencies with %i nodes, %i omits, and downstream = %i.  C indices (graphIDs) shown are 0-based\n", Cnodes.size(), Comit.size(), iDownstream);
#endif
  for(i = 0; i < n; i++) {
    graphNodeVec[ Comit[i] ]->touched = true;
#ifdef _DEBUG_GETDEPS
    PRINTF("touching %i to omit\n", Comit[i]);
#endif
  }
  n = Cnodes.size();
  graphNode *thisGraphNode;
  int thisGraphNodeID;
  for(i = 0; i < n; i++) {
    thisGraphNodeID = Cnodes[i];
    thisGraphNode = graphNodeVec[ thisGraphNodeID ];
#ifdef _DEBUG_GETDEPS
    PRINTF("Working on input node %i\n", thisGraphNodeID);
#endif
    if(!thisGraphNode->touched) {
#ifdef _DEBUG_GETDEPS
      PRINTF("  Adding node %i to ans and recursing\n", thisGraphNodeID);
#endif
      ans.push_back(thisGraphNodeID);
      thisGraphNode->touched = true;
      getDependenciesOneNode(ans, thisGraphNodeID, downstream, 1);
    } else {
#ifdef _DEBUG_GETDEPS
      PRINTF("  Node %i was already touched\n", thisGraphNodeID);
#endif
    }
  }

  // untouch nodes and omit
  n = Comit.size();
  for(i = 0; i < n; i++) {
    graphNodeVec[ Comit[i] ]->touched = false;
  }
  n = ans.size();
  for(i = 0; i < n; i++) {
    graphNodeVec[ ans[i] ]->touched = false;
  }
  std::sort(ans.begin(), ans.end());
  return(ans);
}

void nimbleGraph::getDependenciesOneNode(vector<int> &deps, int CgraphID, bool downstream, int recursionDepth) {
  if(recursionDepth > graphNodeVec.size()) {
    PRINTF("ERROR: getDependencies has recursed too far.  Something must be wrong.\n");
    return;
  }
#ifdef _DEBUG_GETDEPS
  PRINTF("    Entering recursion for node %i\n", CgraphID);
#endif
  graphNode *thisGraphNode = graphNodeVec[CgraphID];
  int numChildren = thisGraphNode->numChildren;
  int i(0);
  graphNode *thisChildNode;
  int thisChildCgraphID;
#ifdef _DEBUG_GETDEPS
  PRINTF("      Starting to iterate through %i children of node %i\n", numChildren, CgraphID);
#endif
  for(; i < numChildren; i++) {
    thisChildNode = thisGraphNode->children[i];
    if(thisChildNode->touched) continue;
    thisChildCgraphID = thisChildNode->CgraphID;
#ifdef _DEBUG_GETDEPS
    PRINTF("        Adding child node %i\n", thisChildCgraphID);
#endif
    deps.push_back(thisChildNode->CgraphID);
    thisChildNode->touched = true;
    if(downstream | (thisChildNode->type != STOCH)) {
#ifdef _DEBUG_GETDEPS
    PRINTF("          Recursing into child node %i\n", thisChildCgraphID);
#endif
      getDependenciesOneNode(deps, thisChildCgraphID, downstream, recursionDepth + 1);
    }
  }
#ifdef _DEBUG_GETDEPS
  PRINTF("      Done iterating through %i children of node %i\n", numChildren, CgraphID);
#endif
}

<commit_msg>clean nimbleGraph.cpp out of src<commit_after><|endoftext|>


<commit_before>// Petter Strandmark 2013.

#include <cstdio>
#include <queue>
#include <set>
#include <sstream>

#include <spii/solver.h>
#include <spii/spii.h>

namespace spii {

struct GlobalQueueEntry
{
	double volume;
	IntervalVector box;
	double best_known_lower_bound;

	bool operator < (const GlobalQueueEntry& rhs) const
	{
		return this->volume < rhs.volume;
	}
};

typedef std::priority_queue<GlobalQueueEntry> IntervalQueue;

std::ostream& operator << (std::ostream& out, IntervalQueue queue)
{
	while (!queue.empty()) {
		const auto box = queue.top().box;
		queue.pop();
		out << box[0] << "; ";
	}
	out << std::endl;
	return out;
}

void midpoint(const IntervalVector& x, Eigen::VectorXd* x_mid)
{
	x_mid->resize(x.size());
	for (int i = 0; i < x.size(); ++i) {
		(*x_mid)[i] = (x[i].get_upper() + x[i].get_lower()) / 2.0;
	}
}

double volume(const IntervalVector& x)
{
	if (x.empty()) {
		return 0.0;
	}

	double vol = 1.0;
	for (auto itr = x.begin(); itr != x.end(); ++itr) {
		const auto& interval = *itr;
		vol *= interval.get_upper() - interval.get_lower();
	}
	return vol;
}

IntervalVector get_bounding_box(const IntervalQueue& queue_in,
                                double* function_lower_bound,
                                double* sum_of_volumes)
{
	*sum_of_volumes = 0;

	if (queue_in.empty()) {
		return IntervalVector();
	}
	// Make copy.
	auto queue = queue_in;
	auto n = queue_in.top().box.size();
	std::vector<double> upper_bound(n, -1e100);
	std::vector<double> lower_bound(n, 1e100);

	*function_lower_bound = std::numeric_limits<double>::infinity();

	while (!queue.empty()) {
		const auto& box = queue.top().box;
		for (int i = 0; i < n; ++i) {
			lower_bound[i] = std::min(lower_bound[i], box[i].get_lower());
			upper_bound[i] = std::max(upper_bound[i], box[i].get_upper());
		}
		*sum_of_volumes += spii::volume(box);
		*function_lower_bound = std::min(*function_lower_bound, queue.top().best_known_lower_bound);
		queue.pop();
	}

	IntervalVector out(n);
	for (int i = 0; i < n; ++i) {
		out[i] = Interval<double>(lower_bound[i], upper_bound[i]);
	}

	return out;
}

void split_interval(const IntervalVector& x,
                    double lower_bound,
                    IntervalQueue* queue)
{
	auto n = x.size();
	std::vector<int> split(n, 0);

	Eigen::VectorXd mid;
	midpoint(x, &mid);

	while (true) {

		IntervalVector x_split(n);
		double volume = 1.0;
		for (int i = 0; i < n; ++i) {
			double a, b;
			if (split[i] == 0) {
				a = x[i].get_lower();
				b = mid[i];
			}
			else {
				a = mid[i];
				b = x[i].get_upper();
			}
			x_split[i] = Interval<double>(a, b);
			volume *= b - a;
		}

		GlobalQueueEntry entry;
		entry.volume = volume;
		entry.box = x_split;
		entry.best_known_lower_bound = lower_bound;
		queue->push(entry);

		// Move to the next binary vector
		//  000001
		//  000010
		//  000011
		//   ...
		//  111111
		int i = 0;
		split[i]++;
		while (split[i] > 1) {
			split[i] = 0;
			i++;
			if (i < n) {
				split[i]++;
			}
			else {
				break;
			}
		}
		if (i == n) {
			break;
		}
	}
}

void GlobalSolver::solve(const Function& function,
                         SolverResults* results) const
{
	spii_assert(false, "GlobalSolver::solve_global should be called.");
}

IntervalVector GlobalSolver::solve_global(const Function& function,
                                          const IntervalVector& x_interval,
                                          SolverResults* results) const
{
	using namespace std;
	double global_start_time = wall_time();

	check(x_interval.size() == function.get_number_of_scalars(),
		"solve_global: input vector does not match the function's number of scalars");
	auto n = x_interval.size();

	IntervalQueue queue;
	GlobalQueueEntry entry;
	entry.volume = 1e100;
	entry.box = x_interval;
	queue.push(entry);

	auto bounds = function.evaluate(x_interval);
	double upper_bound = bounds.get_upper();
	double lower_bound = - std::numeric_limits<double>::infinity();

	Eigen::VectorXd best_x(n);
	IntervalVector best_interval;

	int iterations = 0;
	results->exit_condition = SolverResults::INTERNAL_ERROR;

	while (!queue.empty()) {
		double start_time = wall_time();

		if (iterations >= this->maximum_iterations) {
			results->exit_condition = SolverResults::NO_CONVERGENCE;
			break;
		}

		const auto box = queue.top().box;
		best_interval = box;
		// Remove current element from queue.
		queue.pop();

		auto bounds = function.evaluate(box);

		//cerr << "-- Processing " << box << " resulting in " << bounds << ". Upper bound is " << upper_bound << endl;

		if (bounds.get_lower() < upper_bound) {
			// Evaluate middle point.
			Eigen::VectorXd x(box.size());
			midpoint(box, &x);
			double value = function.evaluate(x);

			if (value < upper_bound) {
				upper_bound = value;
				best_x = x;
			}

			// Add new elements to queue.
			split_interval(box, bounds.get_lower(), &queue);
		}
		results->function_evaluation_time += wall_time() - start_time;

		iterations++;

		start_time = wall_time();
		int log_interval = 1;
		if (iterations > 20) {
			log_interval = 10;
		}
		if (iterations > 200) {
			log_interval = 100;
		}
		if (iterations > 2000) {
			log_interval = 1000;
		}
		if (iterations > 20000) {
			log_interval = 10000;
		}
		if (iterations > 200000) {
			log_interval = 100000;
		}
		if (iterations >= this->maximum_iterations - 2) {
			log_interval = 1;
		}

		if (iterations % log_interval == 0) {
			double volumes_sum;
			lower_bound = upper_bound;  // Default lower bound if queue is empty (problem is solved).
			auto bounding_box = get_bounding_box(queue, &lower_bound, &volumes_sum);
			double vol_bounding = volume(bounding_box);

			double avg_magnitude = (std::abs(lower_bound) + std::abs(upper_bound)) / 2.0;
			double relative_gap = (upper_bound - lower_bound) / avg_magnitude;

			results->stopping_criteria_time += wall_time() - start_time;
			start_time = wall_time();

			if (this->log_function) {
				if (iterations == 1) {
					this->log_function("Iteration Q-size   l.bound   u.bound     rel.gap    bounding   volume");
					this->log_function("----------------------------------------------------------------------");
				}

				char tmp[1024];
				sprintf(tmp, "%9d %6d %+10.3e %+10.3e %10.2e %10.3e %10.3e",
					iterations,
					int(queue.size()),
					lower_bound,
					upper_bound,
					relative_gap,
					vol_bounding,
					volumes_sum);
				this->log_function(tmp);
			}

			results->log_time += wall_time() - start_time;

			if (relative_gap <= this->function_improvement_tolerance) {
				results->exit_condition = SolverResults::FUNCTION_TOLERANCE;
				break;
			}

			if (vol_bounding <= this->argument_improvement_tolerance) {
				results->exit_condition = SolverResults::ARGUMENT_TOLERANCE;
				break;
			}
		}
	}

	double tmp1, tmp2;
	auto bounding_box = get_bounding_box(queue, &tmp1, &tmp2);
	if (bounding_box.empty()) {
		// Problem was solved exactly (queue empty)
		spii_assert(queue.empty());
		results->exit_condition = SolverResults::FUNCTION_TOLERANCE;
		bounding_box = best_interval;
	}

	function.copy_global_to_user(best_x);

	results->optimum_lower = lower_bound;
	results->optimum_upper = upper_bound;
	results->total_time = wall_time() - global_start_time;

	return bounding_box;
}

}  // namespace spii

<commit_msg>Performance improvements to global solver.<commit_after>// Petter Strandmark 2013.

#include <algorithm>
#include <cstdio>
#include <queue>
#include <set>
#include <sstream>

#include <spii/solver.h>
#include <spii/spii.h>

namespace spii {

struct GlobalQueueEntry
{
	double volume;
	IntervalVector box;
	double best_known_lower_bound;

	bool operator < (const GlobalQueueEntry& rhs) const
	{
		return this->volume < rhs.volume;
	}
};

typedef std::vector<GlobalQueueEntry> IntervalQueue;

std::ostream& operator << (std::ostream& out, IntervalQueue queue)
{
	while (!queue.empty()) {
		const auto box = queue.front().box;
		std::pop_heap(begin(queue), end(queue)); queue.pop_back();
		out << box[0] << "; ";
	}
	out << std::endl;
	return out;
}

void midpoint(const IntervalVector& x, Eigen::VectorXd* x_mid)
{
	x_mid->resize(x.size());
	for (int i = 0; i < x.size(); ++i) {
		(*x_mid)[i] = (x[i].get_upper() + x[i].get_lower()) / 2.0;
	}
}

double volume(const IntervalVector& x)
{
	if (x.empty()) {
		return 0.0;
	}

	double vol = 1.0;
	for (auto itr = x.begin(); itr != x.end(); ++itr) {
		const auto& interval = *itr;
		vol *= interval.get_upper() - interval.get_lower();
	}
	return vol;
}

IntervalVector get_bounding_box(const IntervalQueue& queue_in,
                                double* function_lower_bound,
                                double* sum_of_volumes)
{
	*sum_of_volumes = 0;

	if (queue_in.empty()) {
		return IntervalVector();
	}

	auto n = queue_in.front().box.size();
	std::vector<double> upper_bound(n, -1e100);
	std::vector<double> lower_bound(n, 1e100);

	*function_lower_bound = std::numeric_limits<double>::infinity();

	for (const auto& elem: queue_in) {
		const auto& box = elem.box;
		for (int i = 0; i < n; ++i) {
			lower_bound[i] = std::min(lower_bound[i], box[i].get_lower());
			upper_bound[i] = std::max(upper_bound[i], box[i].get_upper());
		}
		*sum_of_volumes += spii::volume(box);
		*function_lower_bound = std::min(*function_lower_bound, elem.best_known_lower_bound);
	}

	IntervalVector out(n);
	for (int i = 0; i < n; ++i) {
		out[i] = Interval<double>(lower_bound[i], upper_bound[i]);
	}

	return out;
}

void split_interval(const IntervalVector& x,
                    double lower_bound,
                    IntervalQueue* queue)
{
	auto n = x.size();
	std::vector<int> split(n, 0);

	Eigen::VectorXd mid;
	midpoint(x, &mid);

	while (true) {

		queue->emplace_back();
		GlobalQueueEntry& entry = queue->back();
		IntervalVector& x_split = entry.box;
		x_split.resize(n);

		double volume = 1.0;
		for (int i = 0; i < n; ++i) {
			double a, b;
			if (split[i] == 0) {
				a = x[i].get_lower();
				b = mid[i];
			}
			else {
				a = mid[i];
				b = x[i].get_upper();
			}
			x_split[i] = Interval<double>(a, b);
			volume *= b - a;
		}

		entry.volume = volume;
		entry.best_known_lower_bound = lower_bound;
		std::push_heap(begin(*queue), end(*queue));

		// Move to the next binary vector
		//  000001
		//  000010
		//  000011
		//   ...
		//  111111
		int i = 0;
		split[i]++;
		while (split[i] > 1) {
			split[i] = 0;
			i++;
			if (i < n) {
				split[i]++;
			}
			else {
				break;
			}
		}
		if (i == n) {
			break;
		}
	}
}

void GlobalSolver::solve(const Function& function,
                         SolverResults* results) const
{
	spii_assert(false, "GlobalSolver::solve_global should be called.");
}

IntervalVector GlobalSolver::solve_global(const Function& function,
                                          const IntervalVector& x_interval,
                                          SolverResults* results) const
{
	using namespace std;
	double global_start_time = wall_time();

	check(x_interval.size() == function.get_number_of_scalars(),
		"solve_global: input vector does not match the function's number of scalars");
	auto n = x_interval.size();

	IntervalQueue queue;
	queue.reserve(2 * this->maximum_iterations);

	GlobalQueueEntry entry;
	entry.volume = 1e100;
	entry.box = x_interval;
	queue.push_back(entry);

	auto bounds = function.evaluate(x_interval);
	double upper_bound = bounds.get_upper();
	double lower_bound = - std::numeric_limits<double>::infinity();

	Eigen::VectorXd best_x(n);
	IntervalVector best_interval;

	int iterations = 0;
	results->exit_condition = SolverResults::INTERNAL_ERROR;

	while (!queue.empty()) {
		double start_time = wall_time();

		if (iterations >= this->maximum_iterations) {
			results->exit_condition = SolverResults::NO_CONVERGENCE;
			break;
		}

		const auto box = queue.front().box;
		best_interval = box;
		// Remove current element from queue.
		pop_heap(begin(queue), end(queue)); queue.pop_back();

		auto bounds = function.evaluate(box);

		//cerr << "-- Processing " << box << " resulting in " << bounds << ". Upper bound is " << upper_bound << endl;

		if (bounds.get_lower() < upper_bound) {
			// Evaluate middle point.
			Eigen::VectorXd x(box.size());
			midpoint(box, &x);
			double value = function.evaluate(x);

			if (value < upper_bound) {
				upper_bound = value;
				best_x = x;
			}

			// Add new elements to queue.
			split_interval(box, bounds.get_lower(), &queue);
		}
		results->function_evaluation_time += wall_time() - start_time;

		iterations++;

		start_time = wall_time();
		int log_interval = 1;
		if (iterations > 20) {
			log_interval = 10;
		}
		if (iterations > 200) {
			log_interval = 100;
		}
		if (iterations > 2000) {
			log_interval = 1000;
		}
		if (iterations > 20000) {
			log_interval = 10000;
		}
		if (iterations > 200000) {
			log_interval = 100000;
		}
		if (iterations >= this->maximum_iterations - 2) {
			log_interval = 1;
		}

		if (iterations % log_interval == 0) {
			double volumes_sum;
			lower_bound = upper_bound;  // Default lower bound if queue is empty (problem is solved).
			auto bounding_box = get_bounding_box(queue, &lower_bound, &volumes_sum);
			double vol_bounding = volume(bounding_box);

			double avg_magnitude = (std::abs(lower_bound) + std::abs(upper_bound)) / 2.0;
			double relative_gap = (upper_bound - lower_bound) / avg_magnitude;

			results->stopping_criteria_time += wall_time() - start_time;
			start_time = wall_time();

			if (this->log_function) {
				if (iterations == 1) {
					this->log_function("Iteration Q-size   l.bound   u.bound     rel.gap    bounding   volume");
					this->log_function("----------------------------------------------------------------------");
				}

				char tmp[1024];
				sprintf(tmp, "%9d %6d %+10.3e %+10.3e %10.2e %10.3e %10.3e",
					iterations,
					int(queue.size()),
					lower_bound,
					upper_bound,
					relative_gap,
					vol_bounding,
					volumes_sum);
				this->log_function(tmp);
			}

			results->log_time += wall_time() - start_time;

			if (relative_gap <= this->function_improvement_tolerance) {
				results->exit_condition = SolverResults::FUNCTION_TOLERANCE;
				break;
			}

			if (vol_bounding <= this->argument_improvement_tolerance) {
				results->exit_condition = SolverResults::ARGUMENT_TOLERANCE;
				break;
			}
		}
	}

	double tmp1, tmp2;
	auto bounding_box = get_bounding_box(queue, &tmp1, &tmp2);
	if (bounding_box.empty()) {
		// Problem was solved exactly (queue empty)
		spii_assert(queue.empty());
		results->exit_condition = SolverResults::FUNCTION_TOLERANCE;
		bounding_box = best_interval;
	}

	function.copy_global_to_user(best_x);

	results->optimum_lower = lower_bound;
	results->optimum_upper = upper_bound;
	results->total_time = wall_time() - global_start_time;

	return bounding_box;
}

}  // namespace spii

<|endoftext|>


<commit_before>//===----------------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// <mutex>

// class recursive_timed_mutex;

// template <class Rep, class Period>
//     bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);

#include <mutex>
#include <thread>
#include <cstdlib>
#include <cassert>

std::recursive_timed_mutex m;

typedef std::chrono::monotonic_clock Clock;
typedef Clock::time_point time_point;
typedef Clock::duration duration;
typedef std::chrono::milliseconds ms;
typedef std::chrono::nanoseconds ns;

void f1()
{
    time_point t0 = Clock::now();
    assert(m.try_lock_for(ms(300)) == true);
    time_point t1 = Clock::now();
    assert(m.try_lock());
    m.unlock();
    m.unlock();
    ns d = t1 - t0 - ms(250);
    assert(d < ns(5000000));  // within 5ms
}

void f2()
{
    time_point t0 = Clock::now();
    assert(m.try_lock_for(ms(250)) == false);
    time_point t1 = Clock::now();
    ns d = t1 - t0 - ms(250);
    assert(d < ns(5000000));  // within 5ms
}

int main()
{
    {
        m.lock();
        std::thread t(f1);
        std::this_thread::sleep_for(ms(250));
        m.unlock();
        t.join();
    }
    {
        m.lock();
        std::thread t(f2);
        std::this_thread::sleep_for(ms(300));
        m.unlock();
        t.join();
    }
}
<commit_msg>Relaxing timing test a bit to avoid spurious test failures under load<commit_after>//===----------------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// <mutex>

// class recursive_timed_mutex;

// template <class Rep, class Period>
//     bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);

#include <mutex>
#include <thread>
#include <cstdlib>
#include <cassert>

std::recursive_timed_mutex m;

typedef std::chrono::monotonic_clock Clock;
typedef Clock::time_point time_point;
typedef Clock::duration duration;
typedef std::chrono::milliseconds ms;
typedef std::chrono::nanoseconds ns;

void f1()
{
    time_point t0 = Clock::now();
    assert(m.try_lock_for(ms(300)) == true);
    time_point t1 = Clock::now();
    assert(m.try_lock());
    m.unlock();
    m.unlock();
    ns d = t1 - t0 - ms(250);
    assert(d < ns(50000000));  // within 50ms
}

void f2()
{
    time_point t0 = Clock::now();
    assert(m.try_lock_for(ms(250)) == false);
    time_point t1 = Clock::now();
    ns d = t1 - t0 - ms(250);
    assert(d < ns(50000000));  // within 50ms
}

int main()
{
    {
        m.lock();
        std::thread t(f1);
        std::this_thread::sleep_for(ms(250));
        m.unlock();
        t.join();
    }
    {
        m.lock();
        std::thread t(f2);
        std::this_thread::sleep_for(ms(300));
        m.unlock();
        t.join();
    }
}
<|endoftext|>


<commit_before>/*
    Similar to #132. We need to look for factors q of \phi(9p) of the form q =
    2^a5^b such that 9n | 10^q. Unlike #132, the restriction that 0 <= a, b <= 9
    is removed here.
*/

#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include "number_util.h"
#include "prime_util.h"

bool is_factor(int p)
{
    int order_max = p == 3 ? 18 : 6 * (p - 1);
    int a_max = 0;
    int b_max = 0;
    while (order_max % 2 == 0)
    {
        a_max++;
        order_max /= 2;
    }
    while (order_max % 5 == 0)
    {
        b_max++;
        order_max /= 5;
    }

    for (int a = 0; a <= a_max; a++)
    {
        for (int b = 0; b <= b_max; b++)
        {
            unsigned long int q = std::pow(2, a) * std::pow(5, b);
            if (util::pow(mpz_class(10), q) % (9 * p) == 1)
                return true;
        }
    }

    return false;
}

int main()
{
    int s = 0;
    std::vector<int> primes = util::get_primes(100000 - 1);
    for (int &prime : primes)
        if (!is_factor(prime))
            s += prime;

    std::cout << s;
}
<commit_msg>Changed to pow_mod.<commit_after>/*
    Similar to #132. We need to look for factors q of \phi(9p) of the form q =
    2^a5^b such that 9n | 10^q. Unlike #132, the restriction that 0 <= a, b <= 9
    is removed here.
*/

#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include "number_util.h"
#include "prime_util.h"

bool is_factor(int p)
{
    int order_max = p == 3 ? 18 : 6 * (p - 1);
    int a_max = 0;
    int b_max = 0;
    while (order_max % 2 == 0)
    {
        a_max++;
        order_max /= 2;
    }
    while (order_max % 5 == 0)
    {
        b_max++;
        order_max /= 5;
    }

    for (int a = 0; a <= a_max; a++)
    {
        for (int b = 0; b <= b_max; b++)
        {
            unsigned long int q = std::pow(2, a) * std::pow(5, b);
            if (util::pow_mod(mpz_class(10), q, mpz_class(9 * p)) == 1)
                return true;
        }
    }

    return false;
}

int main()
{
    int s = 0;
    std::vector<int> primes = util::get_primes(100000 - 1);
    for (int &prime : primes)
        if (!is_factor(prime))
            s += prime;

    std::cout << s;
}
<|endoftext|>


<commit_before>#include <windows.h>

#include <gl\gl.h>

#ifdef _MSC_VER
#define _USE_MATH_DEFINES
#endif
#include <math.h>

#include "Window.h"
#include "Body.h"
#include "Error.h"
#include "Info.h"

#define NAME_FONT_NAME "Arial"
#define NAME_FONT_SIZE_AT_H600 24
#define NAME_FONT_SIZE (int)(NAME_FONT_SIZE_AT_H600*scrheight/600)

#define NAME_TEXT_COLOR_R 1.00f
#define NAME_TEXT_COLOR_G 1.00f
#define NAME_TEXT_COLOR_B 1.00f
#define NAME_TEXT_COLOR_A 0.50f

#define INFO_FONT_NAME "Arial"
#define INFO_FONT_SIZE_AT_H600 16
#define INFO_FONT_SIZE (int)(INFO_FONT_SIZE_AT_H600*scrheight/600)

#define INFO_TEXT_COLOR_R 1.00f
#define INFO_TEXT_COLOR_G 1.00f
#define INFO_TEXT_COLOR_B 1.00f
#define INFO_TEXT_COLOR_A 0.50f

#define SCREEN_SIZE_RATIO_STD (4.0f/3.0f)
#define FONT_SIZE_COEFF (4.6f/3.0f) // do not change!
#define SPACING_COEF 1.15f
#define LINES_AFTER_NAME 1.00f

#define WINDOW_COLOR_R 0.50f
#define WINDOW_COLOR_G 0.50f
#define WINDOW_COLOR_B 0.50f
#define WINDOW_COLOR_A 0.25f

#define MAX_FADE_TIME 3.0f
#define FADE_TIME_RATIO 0.10f
#define FADE_TIME(totaltime) min(MAX_FADE_TIME, (totaltime)*FADE_TIME_RATIO)

#define WINDOW_BORDER_REL 0.0125f
#define WINDOW_BORDER (int)(WINDOW_BORDER_REL*scrheight)

#define MARGIN_TOP_REL 0.0250f
#define MARGIN_BOTTOM_REL 0.0050f
#define MARGIN_LEFT_REL (0.0200f*SCREEN_SIZE_RATIO_STD)
#define MARGIN_LEFT_WIDTH (int)(MARGIN_LEFT_REL*scrheight)
#define MARGIN_TOP_HEIGHT (int)(MARGIN_TOP_REL*scrheight)
#define MARGIN_BOTTOM_HEIGHT (int)(MARGIN_BOTTOM_REL*scrheight)

#define WINDOW_WIDTH_REL_Y (0.3050f*SCREEN_SIZE_RATIO_STD)
#define WINDOW_WIDTH (int)(WINDOW_WIDTH_REL_Y*scrheight)
#define WINDOW_HEIGHT (MARGIN_TOP_HEIGHT+MARGIN_BOTTOM_HEIGHT+(int)(NAME_FONT_SIZE*LINES_AFTER_NAME*SPACING_COEF*FONT_SIZE_COEFF)+3*(int)(INFO_FONT_SIZE*SPACING_COEF*FONT_SIZE_COEFF))

#define WINDOW_POS_X1 (WINDOW_BORDER)
#define WINDOW_POS_Y1 (WINDOW_BORDER)
#define WINDOW_POS_X2 (WINDOW_POS_X1+WINDOW_WIDTH)
#define WINDOW_POS_Y2 (WINDOW_POS_Y1+WINDOW_HEIGHT)

CInfo::CInfo()
{
	Init();
}

CInfo::~CInfo()
{
	Free();
}

void CInfo::Init()
{
	loaded=false;
	scrwidth=0;
	scrheight=0;
	winlist=0;
	namelist=infolist=0;
	time=0;
	starttime=endtime=0;
	fadetime=1;
	alpha=0;
}

void CInfo::Free()
{
	nametext.Free();
	infotext.Free();
	if (winlist)
	{
		if (glIsList(winlist))
			glDeleteLists(winlist,3);
	}
	Init();
}

bool CInfo::Load()
{
	Free();

	scrwidth=CWindow::GetWidth();
	scrheight=CWindow::GetHeight();

	winlist=glGenLists(3);
	if (!winlist)
	{
		CError::LogError(WARNING_CODE,"Unable to load planet info - failed to generate display lists.");
		Free();
		return false;
	}
	namelist=winlist+1;
	infolist=namelist+1;

	MakeWindow(winlist);

	loaded=true;
	loaded&=nametext.BuildFTFont(NAME_FONT_NAME,NAME_FONT_SIZE);
	loaded&=infotext.BuildFTFont(INFO_FONT_NAME,INFO_FONT_SIZE);
	if (!loaded)
	{
		CError::LogError(WARNING_CODE,"Unable to load planet info - failed to load font.");
		Free();
	}

	return loaded;
}

void CInfo::MakeWindow(int list)
{
	glNewList(list,GL_COMPILE);
	{
		int l=WINDOW_POS_X1;
		int r=WINDOW_POS_X2;
		int b=WINDOW_POS_Y1;
		int t=WINDOW_POS_Y2;
		glDisable(GL_TEXTURE_2D);
		glLoadIdentity();
		glBegin(GL_QUADS);
		{
			glVertex2f((float)l,(float)b);
			glVertex2f((float)r,(float)b);
			glVertex2f((float)r,(float)t);
			glVertex2f((float)l,(float)t);
		}
		glEnd();
	}
	glEndList();
}

void CInfo::GetNameCoords(const char *text, int *x, int *y)
{
	float tw;
	nametext.GetTextSize(text,&tw,NULL);
	int th=NAME_FONT_SIZE;

	if (x) *x=WINDOW_POS_X1+(WINDOW_WIDTH-(int)tw)/2;
	if (y) *y=WINDOW_POS_Y2-MARGIN_TOP_HEIGHT-th;
}

void CInfo::GetInfoCoords(int linenum, int *x, int *y)
{
	int ymargin=WINDOW_POS_Y2-MARGIN_TOP_HEIGHT;

	float nameheight;
	nametext.GetTextSize("",NULL,&nameheight);

	float nameadd;
	nameadd=nameheight*SPACING_COEF*LINES_AFTER_NAME;

	int ioffset=INFO_FONT_SIZE;

	float th;
	infotext.GetTextSize("",NULL,&th);
	th*=SPACING_COEF;
	int thi=(int)th*(linenum-1);

	if (x) *x=WINDOW_POS_X1+MARGIN_LEFT_WIDTH;
	if (y) *y=ymargin-(int)nameadd-ioffset-thi;
}

void CInfo::MakeName(int list, char *targetname)
{
	if (!targetname) return;
	if (*targetname==' ') targetname++;
	int x,y;
	GetNameCoords(targetname,&x,&y);
	glNewList(list,GL_COMPILE);
	{
		glEnable(GL_TEXTURE_2D);
		glLoadIdentity();
		glTranslatef((float)x,(float)y,0);
		nametext.Print(targetname);
	}
	glEndList();
}

void CInfo::MakeInfoLine(int linenum, char *line)
{
	int x,y;
	GetInfoCoords(linenum,&x,&y);
	glPushMatrix();
	glTranslatef((float)x,(float)y,0);
	infotext.Print(line);
	glPopMatrix();
}

void CInfo::MakeInfo(int list, CBody *targetbody)
{
	bool star=(targetbody==NULL);
	if (star) targetbody=CBody::bodycache[0];
	glNewList(list,GL_COMPILE);
	{
		int n=0;
		glEnable(GL_TEXTURE_2D);
		glLoadIdentity();
		if (star)
		{
			char line[64];
			n++;
			sprintf(line,"star name: %s",targetbody->name);
			MakeInfoLine(n,line);
		}
		for (int i=0;i<targetbody->info.numlines;i++)
		{
			if (targetbody->info.textlines[i][0]=='/') continue;
			n++;
			MakeInfoLine(n,targetbody->info.textlines[i]);
		}
	}
	glEndList();
}

void CInfo::Start(float seconds, float duration, char *targetname, CBody *targetbody)
{
	if (!loaded)
		return;
	char name[32];
	strcpy(name,targetname);
	int l=strlen(name);
	for (int i=0;i<l;i++)
		if (name[i]=='_')
			name[i]=' ';
	starttime=seconds;
	endtime=starttime+duration;
	fadetime=FADE_TIME(duration);
	MakeName(namelist,name);
	MakeInfo(infolist,targetbody);
}

void CInfo::Update(float seconds)
{
	time=seconds;
	if (time<(endtime-fadetime))
		alpha=min(1,(time-starttime)/fadetime);
	else
		alpha=max(0,(endtime-time)/fadetime);
}

void CInfo::Restart()
{
	starttime-=time;
	endtime-=time;
	time=0;
}

void CInfo::Draw()
{
	if (!alpha || !loaded)
		return;

	glDisable(GL_LIGHTING);
	glDisable(GL_DEPTH_TEST);
	glDisable(GL_CULL_FACE);
	glEnable(GL_BLEND);

	glColor4f(WINDOW_COLOR_R,WINDOW_COLOR_G,WINDOW_COLOR_B,WINDOW_COLOR_A*alpha);
	glCallList(winlist);

	glColor4f(NAME_TEXT_COLOR_R,NAME_TEXT_COLOR_G,NAME_TEXT_COLOR_B,NAME_TEXT_COLOR_A*alpha);
	glCallList(namelist);

	glColor4f(INFO_TEXT_COLOR_R,INFO_TEXT_COLOR_G,INFO_TEXT_COLOR_B,INFO_TEXT_COLOR_A*alpha);
	glCallList(infolist);
}
<commit_msg>Adjustments to info parameters.<commit_after>#include <windows.h>

#include <gl\gl.h>

#ifdef _MSC_VER
#define _USE_MATH_DEFINES
#endif
#include <math.h>

#include "Window.h"
#include "Body.h"
#include "Error.h"
#include "Info.h"

#define NAME_FONT_NAME "Arial"
#define NAME_FONT_SIZE_AT_H600 24
#define NAME_FONT_SIZE (int)(NAME_FONT_SIZE_AT_H600*scrheight/600)

#define NAME_TEXT_COLOR_R 1.00f
#define NAME_TEXT_COLOR_G 1.00f
#define NAME_TEXT_COLOR_B 1.00f
#define NAME_TEXT_COLOR_A 0.50f

#define INFO_FONT_NAME "Arial"
#define INFO_FONT_SIZE_AT_H600 16
#define INFO_FONT_SIZE (int)(INFO_FONT_SIZE_AT_H600*scrheight/600)

#define INFO_TEXT_COLOR_R 1.00f
#define INFO_TEXT_COLOR_G 1.00f
#define INFO_TEXT_COLOR_B 1.00f
#define INFO_TEXT_COLOR_A 0.50f

#define SCREEN_SIZE_RATIO_STD (4.0f/3.0f)
#define FONT_SIZE_COEFF (4.6f/3.0f) // do not change!
#define SPACING_COEF 1.15f
#define LINES_AFTER_NAME 1.125f

#define WINDOW_COLOR_R 0.50f
#define WINDOW_COLOR_G 0.50f
#define WINDOW_COLOR_B 0.50f
#define WINDOW_COLOR_A 0.25f

#define MAX_FADE_TIME 3.0f
#define FADE_TIME_RATIO 0.10f
#define FADE_TIME(totaltime) min(MAX_FADE_TIME, (totaltime)*FADE_TIME_RATIO)

#define WINDOW_BORDER_REL 0.0125f
#define WINDOW_BORDER (int)(WINDOW_BORDER_REL*scrheight)

#define MARGIN_TOP_REL 0.0250f
#define MARGIN_BOTTOM_REL 0.0050f
#define MARGIN_LEFT_REL (0.0200f*SCREEN_SIZE_RATIO_STD)
#define MARGIN_LEFT_WIDTH (int)(MARGIN_LEFT_REL*scrheight)
#define MARGIN_TOP_HEIGHT (int)(MARGIN_TOP_REL*scrheight)
#define MARGIN_BOTTOM_HEIGHT (int)(MARGIN_BOTTOM_REL*scrheight)

#define WINDOW_WIDTH_REL_Y (0.3050f*SCREEN_SIZE_RATIO_STD)
#define WINDOW_WIDTH (int)(WINDOW_WIDTH_REL_Y*scrheight)
#define WINDOW_HEIGHT (MARGIN_TOP_HEIGHT+MARGIN_BOTTOM_HEIGHT+(int)(NAME_FONT_SIZE*LINES_AFTER_NAME*SPACING_COEF*FONT_SIZE_COEFF)+3*(int)(INFO_FONT_SIZE*SPACING_COEF*FONT_SIZE_COEFF))

#define WINDOW_POS_X1 (WINDOW_BORDER)
#define WINDOW_POS_Y1 (WINDOW_BORDER)
#define WINDOW_POS_X2 (WINDOW_POS_X1+WINDOW_WIDTH)
#define WINDOW_POS_Y2 (WINDOW_POS_Y1+WINDOW_HEIGHT)

CInfo::CInfo()
{
	Init();
}

CInfo::~CInfo()
{
	Free();
}

void CInfo::Init()
{
	loaded=false;
	scrwidth=0;
	scrheight=0;
	winlist=0;
	namelist=infolist=0;
	time=0;
	starttime=endtime=0;
	fadetime=1;
	alpha=0;
}

void CInfo::Free()
{
	nametext.Free();
	infotext.Free();
	if (winlist)
	{
		if (glIsList(winlist))
			glDeleteLists(winlist,3);
	}
	Init();
}

bool CInfo::Load()
{
	Free();

	scrwidth=CWindow::GetWidth();
	scrheight=CWindow::GetHeight();

	winlist=glGenLists(3);
	if (!winlist)
	{
		CError::LogError(WARNING_CODE,"Unable to load planet info - failed to generate display lists.");
		Free();
		return false;
	}
	namelist=winlist+1;
	infolist=namelist+1;

	MakeWindow(winlist);

	loaded=true;
	loaded&=nametext.BuildFTFont(NAME_FONT_NAME,NAME_FONT_SIZE);
	loaded&=infotext.BuildFTFont(INFO_FONT_NAME,INFO_FONT_SIZE);
	if (!loaded)
	{
		CError::LogError(WARNING_CODE,"Unable to load planet info - failed to load font.");
		Free();
	}

	return loaded;
}

void CInfo::MakeWindow(int list)
{
	glNewList(list,GL_COMPILE);
	{
		int l=WINDOW_POS_X1;
		int r=WINDOW_POS_X2;
		int b=WINDOW_POS_Y1;
		int t=WINDOW_POS_Y2;
		glDisable(GL_TEXTURE_2D);
		glLoadIdentity();
		glBegin(GL_QUADS);
		{
			glVertex2f((float)l,(float)b);
			glVertex2f((float)r,(float)b);
			glVertex2f((float)r,(float)t);
			glVertex2f((float)l,(float)t);
		}
		glEnd();
	}
	glEndList();
}

void CInfo::GetNameCoords(const char *text, int *x, int *y)
{
	float tw;
	nametext.GetTextSize(text,&tw,NULL);
	int th=NAME_FONT_SIZE;

	if (x) *x=WINDOW_POS_X1+(WINDOW_WIDTH-(int)tw)/2;
	if (y) *y=WINDOW_POS_Y2-MARGIN_TOP_HEIGHT-th;
}

void CInfo::GetInfoCoords(int linenum, int *x, int *y)
{
	int ymargin=WINDOW_POS_Y2-MARGIN_TOP_HEIGHT;

	float nameheight;
	nametext.GetTextSize("",NULL,&nameheight);

	float nameadd;
	nameadd=nameheight*SPACING_COEF*LINES_AFTER_NAME;

	int ioffset=INFO_FONT_SIZE;

	float th;
	infotext.GetTextSize("",NULL,&th);
	th*=SPACING_COEF;
	int thi=(int)th*(linenum-1);

	if (x) *x=WINDOW_POS_X1+MARGIN_LEFT_WIDTH;
	if (y) *y=ymargin-(int)nameadd-ioffset-thi;
}

void CInfo::MakeName(int list, char *targetname)
{
	if (!targetname) return;
	if (*targetname==' ') targetname++;
	int x,y;
	GetNameCoords(targetname,&x,&y);
	glNewList(list,GL_COMPILE);
	{
		glEnable(GL_TEXTURE_2D);
		glLoadIdentity();
		glTranslatef((float)x,(float)y,0);
		nametext.Print(targetname);
	}
	glEndList();
}

void CInfo::MakeInfoLine(int linenum, char *line)
{
	int x,y;
	GetInfoCoords(linenum,&x,&y);
	glPushMatrix();
	glTranslatef((float)x,(float)y,0);
	infotext.Print(line);
	glPopMatrix();
}

void CInfo::MakeInfo(int list, CBody *targetbody)
{
	bool star=(targetbody==NULL);
	if (star) targetbody=CBody::bodycache[0];
	glNewList(list,GL_COMPILE);
	{
		int n=0;
		glEnable(GL_TEXTURE_2D);
		glLoadIdentity();
		if (star)
		{
			char line[64];
			n++;
			sprintf(line,"star name: %s",targetbody->name);
			MakeInfoLine(n,line);
		}
		for (int i=0;i<targetbody->info.numlines;i++)
		{
			if (targetbody->info.textlines[i][0]=='/') continue;
			n++;
			MakeInfoLine(n,targetbody->info.textlines[i]);
		}
	}
	glEndList();
}

void CInfo::Start(float seconds, float duration, char *targetname, CBody *targetbody)
{
	if (!loaded)
		return;
	char name[32];
	strcpy(name,targetname);
	int l=strlen(name);
	for (int i=0;i<l;i++)
		if (name[i]=='_')
			name[i]=' ';
	starttime=seconds;
	endtime=starttime+duration;
	fadetime=FADE_TIME(duration);
	MakeName(namelist,name);
	MakeInfo(infolist,targetbody);
}

void CInfo::Update(float seconds)
{
	time=seconds;
	if (time<(endtime-fadetime))
		alpha=min(1,(time-starttime)/fadetime);
	else
		alpha=max(0,(endtime-time)/fadetime);
}

void CInfo::Restart()
{
	starttime-=time;
	endtime-=time;
	time=0;
}

void CInfo::Draw()
{
	if (!alpha || !loaded)
		return;

	glDisable(GL_LIGHTING);
	glDisable(GL_DEPTH_TEST);
	glDisable(GL_CULL_FACE);
	glEnable(GL_BLEND);

	glColor4f(WINDOW_COLOR_R,WINDOW_COLOR_G,WINDOW_COLOR_B,WINDOW_COLOR_A*alpha);
	glCallList(winlist);

	glColor4f(NAME_TEXT_COLOR_R,NAME_TEXT_COLOR_G,NAME_TEXT_COLOR_B,NAME_TEXT_COLOR_A*alpha);
	glCallList(namelist);

	glColor4f(INFO_TEXT_COLOR_R,INFO_TEXT_COLOR_G,INFO_TEXT_COLOR_B,INFO_TEXT_COLOR_A*alpha);
	glCallList(infolist);
}
<|endoftext|>