<commit_before>#include "engine/tile/TileSet.hpp"
#include "engine/utils/log.hpp"
#include <cassert>

namespace engine
{
    bool TileSet::loadFromJson(const Json::Value& node)
    {
        _tilesize.x = node.get("tilew", 0).asInt();
        _tilesize.y = node.get("tileh", 0).asInt();
        LOG_DEBUG(LOG_DUMP(_tilesize.x), ", ", LOG_DUMP(_tilesize.y));

        if (!_tilesize.x || !_tilesize.y)
        {
            LOG_ERROR("Invalid tile size");
            return false;
        }

        if (!node.isMember("tilesheet") || !_sheet.loadFromFile(node["tilesheet"].asString()))
        {
            LOG_ERROR("Failed to load tilesheet");
            return false;
        }

        if (!node.isMember("tiles"))
        {
            LOG_WARN("No tiles specified");
            return false;
        }

        const auto& tiles = node["tiles"];
        _tiles.resize(tiles.size());

        LOG_DEBUG("Loading tiles...");
        for (Json::ArrayIndex i = 0; i < tiles.size(); ++i)
        {
            const auto& t = tiles[i];
            auto& td = _tiles[i].texdata;

            LOG_DEBUG("Loading tile ", i, ":");
            if (t.isMember("name"))
            {
                _aliases[t["name"].asString()] = &_tiles[i];
            }

            if (t.isMember("flags"))
            {
                const auto& flags = t["flags"];
                const auto* flagnames = node.isMember("flags") ? &node["flags"] : 0;
                for (Json::ArrayIndex i = 0; i < flags.size(); ++i)
                {
                    if (flags[i].isString())
                    {
                        const auto& f = flags[i].asString();
                        if (flagnames && flagnames->isMember(f))
                            _tiles[i].flags |= (*flagnames)[f].asInt();
                        else
                            LOG_ERROR("Unknown flag ", f);
                    }
                    else
                    {
                        _tiles[i].flags |= flags[i].asInt();
                    }
                }
            }

            _tiles[i].id = i;
            td.index = t.get("index", 0).asInt();
            td.offset = t.get("offset", 0).asFloat();
            td.length = t.get("anilen", 1).asInt();
            td.speed = t.get("anispeed", 0).asFloat();
        }

        LOG("Tileset with ", _tiles.size(), " tiles loaded");
        return true;
    }

    void TileSet::destroy()
    {
        _tilesize.set(0);
        _sheet = sf::Texture();
        _tiles.clear();
        _aliases.clear();
        LOG_WARN("Tileset destroyed");
    }

    sf::Sprite TileSet::getSprite(TileID tileid, int offset) const
    {
        return sf::Sprite(_sheet, getTexRect(tileid, offset));
    }

    sf::Sprite TileSet::getSprite(int index) const
    {
        return sf::Sprite(_sheet, getTexRect(index));
    }

    sf::IntRect TileSet::getTexRect(TileID tileid, int offset) const
    {
        return getTexRect(_tiles[tileid].texdata.index + offset);
    }

    sf::IntRect TileSet::getTexRect(int index) const
    {
        return sf::IntRect( // left, top, width, height
            (index * _tilesize.x) % _sheet.getSize().x,
            ((index * _tilesize.x) / _sheet.getSize().x) * _tilesize.y,
            _tilesize.x,
            _tilesize.y
        );
    }

    bool TileSet::hasTile(TileID id) const
    {
        return id < _tiles.size();
    }

    bool TileSet::hasTile(const std::string& name) const
    {
        return _aliases.find(name) != _aliases.end();
    }

    const TileData& TileSet::getTile(TileID tileid) const
    {
        return _tiles[tileid];
    }

    const TileData& TileSet::getTile(const std::string& name) const
    {
        assert("Alias does not exist" && _aliases.count(name) > 0);
        return *_aliases.at(name);
    }

    TileID TileSet::getTileID(const std::string& name) const
    {
        auto it = _aliases.find(name);
        return it == _aliases.end() ? InvalidTile : it->second->id;
    }

    const sf::Texture& TileSet::getTexSheet() const
    {
        return _sheet;
    }

    const geometry::Vector2<int>& TileSet::getTileSize() const
    {
        return _tilesize;
    }

    size_t TileSet::size() const
    {
        return _tiles.size();
    }
}
<commit_msg>Use InvalidTile as default for texture index<commit_after>#include "engine/tile/TileSet.hpp"
#include "engine/utils/log.hpp"
#include <cassert>

namespace engine
{
    bool TileSet::loadFromJson(const Json::Value& node)
    {
        _tilesize.x = node.get("tilew", 0).asInt();
        _tilesize.y = node.get("tileh", 0).asInt();
        LOG_DEBUG(LOG_DUMP(_tilesize.x), ", ", LOG_DUMP(_tilesize.y));

        if (!_tilesize.x || !_tilesize.y)
        {
            LOG_ERROR("Invalid tile size");
            return false;
        }

        if (!node.isMember("tilesheet") || !_sheet.loadFromFile(node["tilesheet"].asString()))
        {
            LOG_ERROR("Failed to load tilesheet");
            return false;
        }

        if (!node.isMember("tiles"))
        {
            LOG_WARN("No tiles specified");
            return false;
        }

        const auto& tiles = node["tiles"];
        _tiles.resize(tiles.size());

        LOG_DEBUG("Loading tiles...");
        for (Json::ArrayIndex i = 0; i < tiles.size(); ++i)
        {
            const auto& t = tiles[i];
            auto& td = _tiles[i].texdata;

            LOG_DEBUG("Loading tile ", i, ":");
            if (t.isMember("name"))
            {
                _aliases[t["name"].asString()] = &_tiles[i];
            }

            if (t.isMember("flags"))
            {
                const auto& flags = t["flags"];
                const auto* flagnames = node.isMember("flags") ? &node["flags"] : 0;
                for (Json::ArrayIndex i = 0; i < flags.size(); ++i)
                {
                    if (flags[i].isString())
                    {
                        const auto& f = flags[i].asString();
                        if (flagnames && flagnames->isMember(f))
                            _tiles[i].flags |= (*flagnames)[f].asInt();
                        else
                            LOG_ERROR("Unknown flag ", f);
                    }
                    else
                    {
                        _tiles[i].flags |= flags[i].asInt();
                    }
                }
            }

            _tiles[i].id = i;
            td.index = t.get("index", InvalidTile).asInt();
            td.offset = t.get("offset", 0).asFloat();
            td.length = t.get("anilen", 1).asInt();
            td.speed = t.get("anispeed", 0).asFloat();
        }

        LOG("Tileset with ", _tiles.size(), " tiles loaded");
        return true;
    }

    void TileSet::destroy()
    {
        _tilesize.set(0);
        _sheet = sf::Texture();
        _tiles.clear();
        _aliases.clear();
        LOG_WARN("Tileset destroyed");
    }

    sf::Sprite TileSet::getSprite(TileID tileid, int offset) const
    {
        return sf::Sprite(_sheet, getTexRect(tileid, offset));
    }

    sf::Sprite TileSet::getSprite(int index) const
    {
        return sf::Sprite(_sheet, getTexRect(index));
    }

    sf::IntRect TileSet::getTexRect(TileID tileid, int offset) const
    {
        return getTexRect(_tiles[tileid].texdata.index + offset);
    }

    sf::IntRect TileSet::getTexRect(int index) const
    {
        return sf::IntRect( // left, top, width, height
            (index * _tilesize.x) % _sheet.getSize().x,
            ((index * _tilesize.x) / _sheet.getSize().x) * _tilesize.y,
            _tilesize.x,
            _tilesize.y
        );
    }

    bool TileSet::hasTile(TileID id) const
    {
        return id < _tiles.size();
    }

    bool TileSet::hasTile(const std::string& name) const
    {
        return _aliases.find(name) != _aliases.end();
    }

    const TileData& TileSet::getTile(TileID tileid) const
    {
        return _tiles[tileid];
    }

    const TileData& TileSet::getTile(const std::string& name) const
    {
        assert("Alias does not exist" && _aliases.count(name) > 0);
        return *_aliases.at(name);
    }

    TileID TileSet::getTileID(const std::string& name) const
    {
        auto it = _aliases.find(name);
        return it == _aliases.end() ? InvalidTile : it->second->id;
    }

    const sf::Texture& TileSet::getTexSheet() const
    {
        return _sheet;
    }

    const geometry::Vector2<int>& TileSet::getTileSize() const
    {
        return _tilesize;
    }

    size_t TileSet::size() const
    {
        return _tiles.size();
    }
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2018, University of Edinburgh
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  * Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *  * Neither the name of  nor the names of its contributors may be used to
 *    endorse or promote products derived from this software without specific
 *    prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <exotica_ik_solver/ik_solver.h>

REGISTER_MOTIONSOLVER_TYPE("IKSolver", exotica::IKSolver)

namespace exotica
{
IKSolver::IKSolver() = default;

IKSolver::~IKSolver() = default;

void IKSolver::Instantiate(IKSolverInitializer& init)
{
    parameters_ = init;
}

void IKSolver::specifyProblem(PlanningProblem_ptr pointer)
{
    if (pointer->type() != "exotica::UnconstrainedEndPoseProblem")
    {
        throw_named("This IKSolver can't solve problem of type '" << pointer->type() << "'!");
    }
    MotionSolver::specifyProblem(pointer);
    prob_ = std::static_pointer_cast<UnconstrainedEndPoseProblem>(pointer);

    if (parameters_.C < 0 || parameters_.C >= 1.0)
        throw_named("C must be from interval <0, 1)!");
    C_ = Eigen::MatrixXd::Identity(prob_->Cost.JN, prob_->Cost.JN) * parameters_.C;
    W_ = prob_->W;

    if (parameters_.Alpha.size() != 1 && prob_->N != parameters_.Alpha.size())
        throw_named("Alpha must have length of 1 or N.");
}

void IKSolver::Solve(Eigen::MatrixXd& solution)
{
    prob_->resetCostEvolution(getNumberOfMaxIterations() + 1);

    Timer timer;

    if (!prob_) throw_named("Solver has not been initialized!");
    const Eigen::VectorXd q0 = prob_->applyStartState();

    if (prob_->N != q0.rows()) throw_named("Wrong size q0 size=" << q0.rows() << ", required size=" << prob_->N);

    Eigen::VectorXd qd, qNominal;
    bool UseNullspace = false;
    if (prob_->qNominal.rows() == prob_->N)
    {
        qNominal = prob_->qNominal;
        UseNullspace = true;
    }
    else
    {
        qNominal = q0;
    }

    solution.resize(1, prob_->N);

    Eigen::VectorXd q = q0;
    double error = INFINITY;
    double C = C_(0, 0);
    Eigen::VectorXd yd;
    Eigen::MatrixXd J;
    if (C > 0)
    {
        yd = Eigen::VectorXd(prob_->JN + prob_->N);
        J = Eigen::MatrixXd(prob_->JN + prob_->N, prob_->N);
    }
    for (int i = 0; i < getNumberOfMaxIterations(); i++)
    {
        prob_->Update(q);

        error = prob_->getScalarCost();

        prob_->setCostEvolution(i, error);

        if (error < parameters_.Tolerance)
        {
            if (debug_)
                HIGHLIGHT_NAMED("IKSolver", "Reached tolerance (" << error << " < " << parameters_.Tolerance << ")");
            break;
        }

        if (C > 0)
        {
            yd.head(prob_->JN) = prob_->Cost.S * prob_->Cost.ydiff;
            yd.tail(prob_->N) = q - qNominal;
            J.topRows(prob_->JN) = prob_->Cost.S * prob_->Cost.J * W_ * (1.0 - C);
            J.bottomRows(prob_->N) = C_;
        }
        else
        {
            yd = prob_->Cost.S * prob_->Cost.ydiff;
            J = prob_->Cost.S * prob_->Cost.J * W_;
        }

#if EIGEN_VERSION_AT_LEAST(3, 3, 0)
        qd = J.completeOrthogonalDecomposition().solve(yd);
#else
        qd = J.householderQr().solve(yd);
#endif

        ScaleToStepSize(qd);

        if (parameters_.Alpha.size() == 1)
        {
            q -= qd * parameters_.Alpha[0];
        }
        else
        {
            q -= qd.cwiseProduct(parameters_.Alpha);
        }

        if (qd.norm() < parameters_.Convergence)
        {
            if (debug_)
                HIGHLIGHT_NAMED("IKSolver", "Reached convergence (" << qd.norm() << " < " << parameters_.Convergence
                                                                    << ")");
            break;
        }
    }

    solution.row(0) = q;

    planning_time_ = timer.getDuration();
}

void IKSolver::ScaleToStepSize(Eigen::VectorXdRef xd)
{
    double max_vel = xd.cwiseAbs().maxCoeff();
    if (max_vel > parameters_.MaxStep)
    {
        xd = xd * parameters_.MaxStep / max_vel;
    }
}
}
<commit_msg>[exotica_ik_solver] Review edits<commit_after>/*
 * Copyright (c) 2018, University of Edinburgh
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  * Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *  * Neither the name of  nor the names of its contributors may be used to
 *    endorse or promote products derived from this software without specific
 *    prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <exotica_ik_solver/ik_solver.h>

REGISTER_MOTIONSOLVER_TYPE("IKSolver", exotica::IKSolver)

namespace exotica
{
IKSolver::IKSolver() = default;

IKSolver::~IKSolver() = default;

void IKSolver::Instantiate(IKSolverInitializer& init)
{
    parameters_ = init;
}

void IKSolver::specifyProblem(PlanningProblem_ptr pointer)
{
    if (pointer->type() != "exotica::UnconstrainedEndPoseProblem")
    {
        throw_named("This IKSolver can't solve problem of type '" << pointer->type() << "'!");
    }
    MotionSolver::specifyProblem(pointer);
    prob_ = std::static_pointer_cast<UnconstrainedEndPoseProblem>(pointer);

    if (parameters_.C < 0 || parameters_.C >= 1.0)
        throw_named("C must be from interval <0, 1)!");
    C_ = Eigen::MatrixXd::Identity(prob_->Cost.JN, prob_->Cost.JN) * parameters_.C;
    W_ = prob_->W;

    if (parameters_.Alpha.size() != 1 && prob_->N != parameters_.Alpha.size())
        throw_named("Alpha must have length of 1 or N.");
}

void IKSolver::Solve(Eigen::MatrixXd& solution)
{
    prob_->resetCostEvolution(getNumberOfMaxIterations() + 1);

    Timer timer;

    if (!prob_) throw_named("Solver has not been initialized!");
    const Eigen::VectorXd q0 = prob_->applyStartState();

    if (prob_->N != q0.rows()) throw_named("Wrong size q0 size=" << q0.rows() << ", required size=" << prob_->N);

    Eigen::VectorXd qd, q_nominal;
    if (prob_->qNominal.rows() == prob_->N)
    {
        q_nominal = prob_->qNominal;
    }
    else
    {
        q_nominal = q0;
    }

    solution.resize(1, prob_->N);

    Eigen::VectorXd q = q0;
    double error = std::numeric_limits<double>::infinity();
    bool is_regularised = C_(0, 0) > 0.0;
    Eigen::VectorXd yd;
    Eigen::MatrixXd J;
    if (is_regularised)
    {
        yd = Eigen::VectorXd(prob_->JN + prob_->N);
        J = Eigen::MatrixXd(prob_->JN + prob_->N, prob_->N);
    }
    for (int i = 0; i < getNumberOfMaxIterations(); ++i)
    {
        prob_->Update(q);

        error = prob_->getScalarCost();

        prob_->setCostEvolution(i, error);

        if (error < parameters_.Tolerance)
        {
            if (debug_)
                HIGHLIGHT_NAMED("IKSolver", "Reached tolerance (" << error << " < " << parameters_.Tolerance << ")");
            break;
        }

        if (is_regularised)
        {
            yd.head(prob_->JN) = prob_->Cost.S * prob_->Cost.ydiff;
            yd.tail(prob_->N) = q - q_nominal;
            J.topRows(prob_->JN) = prob_->Cost.S * prob_->Cost.J * W_ * (1.0 - C_(0, 0));
            J.bottomRows(prob_->N) = C_;
        }
        else
        {
            yd = prob_->Cost.S * prob_->Cost.ydiff;
            J = prob_->Cost.S * prob_->Cost.J * W_;
        }

#if EIGEN_VERSION_AT_LEAST(3, 3, 0)
        qd = J.completeOrthogonalDecomposition().solve(yd);
#else
        qd = J.colPivHouseholderQr().solve(yd);
#endif

        ScaleToStepSize(qd);

        if (parameters_.Alpha.size() == 1)
        {
            q -= qd * parameters_.Alpha[0];
        }
        else
        {
            q -= qd.cwiseProduct(parameters_.Alpha);
        }

        if (qd.norm() < parameters_.Convergence)
        {
            if (debug_)
                HIGHLIGHT_NAMED("IKSolver", "Reached convergence (" << qd.norm() << " < " << parameters_.Convergence
                                                                    << ")");
            break;
        }
    }

    solution.row(0) = q;

    planning_time_ = timer.getDuration();
}

void IKSolver::ScaleToStepSize(Eigen::VectorXdRef xd)
{
    double max_vel = xd.cwiseAbs().maxCoeff();
    if (max_vel > parameters_.MaxStep)
    {
        xd = xd * parameters_.MaxStep / max_vel;
    }
}
}
<|endoftext|>


<commit_before>#include <faunus/faunus.h>
#include <faunus/multipole.h>
using namespace Faunus;                          // use Faunus namespace
using namespace Faunus::Move;
using namespace Faunus::Potential;

typedef Space<Geometry::Cuboid,DipoleParticle> Tspace;
typedef CombinedPairPotential<LennardJones,DipoleDipole> Tpair;

#ifdef POLARIZE
typedef Move::PolarizeMove<AtomicTranslation<Tspace> > TmoveTran;
typedef Move::PolarizeMove<AtomicRotation<Tspace> > TmoveRot;
#else
typedef Move::AtomicTranslation<Tspace> TmoveTran;
typedef Move::AtomicRotation<Tspace> TmoveRot;
#endif

int main() {
  //::atom.includefile("stockmayer.json");         // load atom properties
  InputMap in("stockmayer.input");               // open parameter file for user input
  Energy::NonbondedVector<Tspace,Tpair> pot(in); // non-bonded only
  EnergyDrift sys;                               // class for tracking system energy drifts
  Tspace spc(in);                // create simulation space, particles etc.
  Group sol;
  sol.addParticles(spc, in);                     // group for particles
  MCLoop loop(in);                               // class for mc loop counting
  TmoveTran trans(in,pot,spc);
  TmoveRot rot(in,pot,spc);
  trans.setGroup(sol);                                // tells move class to act on sol group
  rot.setGroup(sol);                                  // tells move class to act on sol group
  spc.load("state");
  spc.trial = spc.p;
  UnitTest test(in);               // class for unit testing
  Analysis::DipoleAnalysis dian(spc);
  DipoleWRL sdp;
  FormatXTC xtc(spc.geo.len.norm());
  sys.init( Energy::systemEnergy(spc,pot,spc.p)  );   // initial energy
  while ( loop.macroCnt() ) {                         // Markov chain
    while ( loop.microCnt() ) {
      if (slp_global() > 0.5)
        sys+=trans.move( sol.size() );                // translate
      else
        sys+=rot.move( sol.size() );                  // rotate

      if (slp_global()<0.5)
        dian.sampleMuCorrelationAndKirkwood(spc);
      if (slp_global()>0.99)
        xtc.save(textio::prefix+"out.xtc", spc.p);
      dian.sampleDP(spc);
    }
    sys.checkDrift(Energy::systemEnergy(spc,pot,spc.p)); // compare energy sum with current
    cout << loop.timing();
  }

  // perform unit tests
  trans.test(test);
  rot.test(test);
  sys.test(test);
  sdp.saveDipoleWRL("stockmayer.wrl",spc,sol);
  FormatPQR().save("confout.pqr", spc.p);
  std::cout << spc.info() + pot.info() + trans.info()
    + rot.info() + sys.info() + test.info() + dian.info(); // final info
  dian.save();
  spc.save("state");

  return test.numFailed();
}
/**  @page example_stockmayer Example: Stockmayer potential

 This will simulate a Stockmayer potential in a cubic box.

 Run this example from the `examples` directory:

 ~~~~~~~~~~~~~~~~~~~
 $ make
 $ cd src/examples
 $ ./stockmayer.run
 ~~~~~~~~~~~~~~~~~~~

 stockmayer.cpp
 ============

 @includelineno examples/stockmayer.cpp

*/
<commit_msg>Further updates<commit_after>#include <faunus/faunus.h>
#include <faunus/multipole.h>
using namespace Faunus;                          // use Faunus namespace
using namespace Faunus::Move;
using namespace Faunus::Potential;

typedef Space<Geometry::Cuboid,DipoleParticle> Tspace;
typedef CombinedPairPotential<LennardJones,DipoleDipole> Tpair;

#ifdef POLARIZE
typedef Move::PolarizeMove<AtomicTranslation<Tspace> > TmoveTran;
typedef Move::PolarizeMove<AtomicRotation<Tspace> > TmoveRot;
#else
typedef Move::AtomicTranslation<Tspace> TmoveTran;
typedef Move::AtomicRotation<Tspace> TmoveRot;
#endif

int main() {
  //::atom.includefile("stockmayer.json");         // load atom properties
  InputMap in("stockmayer.input");               // open parameter file for user input
  Energy::NonbondedVector<Tspace,Tpair> pot(in); // non-bonded only
  EnergyDrift sys;                               // class for tracking system energy drifts
  Tspace spc(in);                // create simulation space, particles etc.
  Group sol;
  sol.addParticles(spc, in);                     // group for particles
  MCLoop loop(in);                               // class for mc loop counting
  TmoveTran trans(in,pot,spc);
  TmoveRot rot(in,pot,spc);
  trans.setGroup(sol);                                // tells move class to act on sol group
  rot.setGroup(sol);                                  // tells move class to act on sol group
  spc.load("state");
  spc.trial = spc.p;
  UnitTest test(in);               // class for unit testing
  Analysis::DipoleAnalysis dian(spc,in);
  DipoleWRL sdp;
  FormatXTC xtc(spc.geo.len.norm());
  sys.init( Energy::systemEnergy(spc,pot,spc.p)  );   // initial energy
  while ( loop.macroCnt() ) {                         // Markov chain
    while ( loop.microCnt() ) {
      if (slp_global() > 0.5)
        sys+=trans.move( sol.size() );                // translate
      else
        sys+=rot.move( sol.size() );                  // rotate

      if (slp_global()<0.5)
        dian.sampleMuCorrelationAndKirkwood(spc);
      if (slp_global()>0.99)
        xtc.save(textio::prefix+"out.xtc", spc.p);
      dian.sampleDP(spc);
    }
    sys.checkDrift(Energy::systemEnergy(spc,pot,spc.p)); // compare energy sum with current
    cout << loop.timing();
  }

  // perform unit tests
  trans.test(test);
  rot.test(test);
  sys.test(test);
  sdp.saveDipoleWRL("stockmayer.wrl",spc,sol);
  FormatPQR().save("confout.pqr", spc.p);
  std::cout << spc.info() + pot.info() + trans.info()
    + rot.info() + sys.info() + test.info() + dian.info(); // final info
  dian.save();
  spc.save("state");

  return test.numFailed();
}
/**  @page example_stockmayer Example: Stockmayer potential

 This will simulate a Stockmayer potential in a cubic box.

 Run this example from the `examples` directory:

 ~~~~~~~~~~~~~~~~~~~
 $ make
 $ cd src/examples
 $ ./stockmayer.run
 ~~~~~~~~~~~~~~~~~~~

 stockmayer.cpp
 ============

 @includelineno examples/stockmayer.cpp

*/
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2012 - 2015  Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#include "fileoperationdialog.h"
#include "fileoperation.h"
#include "renamedialog.h"
#include <QLabel>
#include <QMessageBox>
#include <libfm/fm-config.h>
#include "utilities.h"
#include "ui_file-operation-dialog.h"

#include "core/legacy/fm-config.h"

namespace Fm {

FileOperationDialog::FileOperationDialog(FileOperation* _operation):
    QDialog(nullptr),
    operation(_operation),
    defaultOption(-1),
    ignoreNonCriticalErrors_(false) {

    ui = new Ui::FileOperationDialog();
    ui->setupUi(this);

    QString title;
    QString message;
    switch(_operation->type()) {
    case FileOperation::Move:
        title = tr("Move files");
        message = tr("Moving the following files to destination folder:");
        break;
    case FileOperation::Copy:
        title = tr("Copy Files");
        message = tr("Copying the following files to destination folder:");
        break;
    case FileOperation::Trash:
        title = tr("Trash Files");
        message = tr("Moving the following files to trash can:");
        break;
    case FileOperation::Delete:
        title = tr("Delete Files");
        message = tr("Deleting the following files:");
        ui->dest->hide();
        ui->destLabel->hide();
        break;
    case FileOperation::Link:
        title = tr("Create Symlinks");
        message = tr("Creating symlinks for the following files:");
        break;
    case FileOperation::ChangeAttr:
        title = tr("Change Attributes");
        message = tr("Changing attributes of the following files:");
        ui->dest->hide();
        ui->destLabel->hide();
        break;
    case FileOperation::UnTrash:
        title = tr("Restore Trashed Files");
        message = tr("Restoring the following files from trash can:");
        ui->dest->hide();
        ui->destLabel->hide();
        break;
    }
    ui->message->setText(message);
    setWindowTitle(title);
}

FileOperationDialog::~FileOperationDialog() {
    delete ui;
}

void FileOperationDialog::setDestPath(const Fm::FilePath &dest) {
    ui->dest->setText(dest.displayName().get());
}

void FileOperationDialog::setSourceFiles(const Fm::FilePathList &srcFiles) {
    for(auto& srcFile : srcFiles) {
        ui->sourceFiles->addItem(srcFile.displayName().get());
    }
}

int FileOperationDialog::ask(QString /*question*/, char* const* /*options*/) {
    // TODO: implement FileOperationDialog::ask()
    return 0;
}

FileOperationJob::FileExistsAction FileOperationDialog::askRename(const FileInfo &src, const FileInfo &dest, FilePath &newDest) {
    FileOperationJob::FileExistsAction ret;
    if(defaultOption == -1) { // default action is not set, ask the user
        RenameDialog dlg(src, dest, this);
        dlg.exec();
        switch(dlg.action()) {
        case RenameDialog::ActionOverwrite:
            ret = FileOperationJob::OVERWRITE;
            if(dlg.applyToAll()) {
                defaultOption = ret;
            }
            break;
        case RenameDialog::ActionRename: {
            ret = FileOperationJob::RENAME;
            auto newName = dlg.newName();
            if(!newName.isEmpty()) {
                auto destDirPath = dest.path().parent();
                newDest = destDirPath.child(newName.toUtf8().constData());
            }
            break;
        }
        case RenameDialog::ActionIgnore:
            ret = FileOperationJob::SKIP;
            if(dlg.applyToAll()) {
                defaultOption = ret;
            }
            break;
        default:
            ret = FileOperationJob::CANCEL;
            break;
        }
    }
    else {
        ret = (FileOperationJob::FileExistsAction)defaultOption;
    }
    return ret;
}

Job::ErrorAction FileOperationDialog::error(GError* err, Job::ErrorSeverity severity) {
    if(severity >= Job::ErrorSeverity::MODERATE) {
        if(severity == Job::ErrorSeverity::CRITICAL) {
            QMessageBox::critical(this, tr("Error"), QString::fromUtf8(err->message));
            return Job::ErrorAction::ABORT;
        }
        if (ignoreNonCriticalErrors_) {
            return Job::ErrorAction::CONTINUE;
        }
        QMessageBox::StandardButton stb = QMessageBox::critical(this, tr("Error"), QString::fromUtf8(err->message),
                                                                QMessageBox::Ok | QMessageBox::Ignore);
        if (stb == QMessageBox::Ignore) {
            ignoreNonCriticalErrors_ = true;
        }
    }
    return Job::ErrorAction::CONTINUE;
}

void FileOperationDialog::setCurFile(QString cur_file) {
    ui->curFile->setText(cur_file);
}

void FileOperationDialog::setDataTransferred(uint64_t finishedSize, std::uint64_t totalSize) {
    ui->filesProcessed->setText(QString("%1 / %2")
                                 .arg(formatFileSize(finishedSize, fm_config->si_unit))
                                 .arg(formatFileSize(totalSize, fm_config->si_unit)));
}

void FileOperationDialog::setFilesProcessed(uint64_t finishedCount, uint64_t totalCount) {
    ui->filesProcessed->setText(QString("%1 / %2")
                                 .arg(finishedCount)
                                 .arg(totalCount));
}

void FileOperationDialog::setPercent(unsigned int percent) {
    ui->progressBar->setValue(percent);
}

void FileOperationDialog::setRemainingTime(unsigned int sec) {
    unsigned int min = 0;
    unsigned int hr = 0;
    if(sec > 60) {
        min = sec / 60;
        sec %= 60;
        if(min > 60) {
            hr = min / 60;
            min %= 60;
        }
    }
    ui->timeRemaining->setText(QString("%1:%2:%3")
                               .arg(hr, 2, 10, QChar('0'))
                               .arg(min, 2, 10, QChar('0'))
                               .arg(sec, 2, 10, QChar('0')));
}

void FileOperationDialog::setPrepared() {
}

void FileOperationDialog::reject() {
    operation->cancel();
    QDialog::reject();
}

} // namespace Fm
<commit_msg>Fix a FTBFS due to libfm header inclusion<commit_after>/*
 * Copyright (C) 2012 - 2015  Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#include "fileoperationdialog.h"
#include "fileoperation.h"
#include "renamedialog.h"
#include <QLabel>
#include <QMessageBox>
#include "utilities.h"
#include "ui_file-operation-dialog.h"

#include "core/legacy/fm-config.h"

namespace Fm {

FileOperationDialog::FileOperationDialog(FileOperation* _operation):
    QDialog(nullptr),
    operation(_operation),
    defaultOption(-1),
    ignoreNonCriticalErrors_(false) {

    ui = new Ui::FileOperationDialog();
    ui->setupUi(this);

    QString title;
    QString message;
    switch(_operation->type()) {
    case FileOperation::Move:
        title = tr("Move files");
        message = tr("Moving the following files to destination folder:");
        break;
    case FileOperation::Copy:
        title = tr("Copy Files");
        message = tr("Copying the following files to destination folder:");
        break;
    case FileOperation::Trash:
        title = tr("Trash Files");
        message = tr("Moving the following files to trash can:");
        break;
    case FileOperation::Delete:
        title = tr("Delete Files");
        message = tr("Deleting the following files:");
        ui->dest->hide();
        ui->destLabel->hide();
        break;
    case FileOperation::Link:
        title = tr("Create Symlinks");
        message = tr("Creating symlinks for the following files:");
        break;
    case FileOperation::ChangeAttr:
        title = tr("Change Attributes");
        message = tr("Changing attributes of the following files:");
        ui->dest->hide();
        ui->destLabel->hide();
        break;
    case FileOperation::UnTrash:
        title = tr("Restore Trashed Files");
        message = tr("Restoring the following files from trash can:");
        ui->dest->hide();
        ui->destLabel->hide();
        break;
    }
    ui->message->setText(message);
    setWindowTitle(title);
}

FileOperationDialog::~FileOperationDialog() {
    delete ui;
}

void FileOperationDialog::setDestPath(const Fm::FilePath &dest) {
    ui->dest->setText(dest.displayName().get());
}

void FileOperationDialog::setSourceFiles(const Fm::FilePathList &srcFiles) {
    for(auto& srcFile : srcFiles) {
        ui->sourceFiles->addItem(srcFile.displayName().get());
    }
}

int FileOperationDialog::ask(QString /*question*/, char* const* /*options*/) {
    // TODO: implement FileOperationDialog::ask()
    return 0;
}

FileOperationJob::FileExistsAction FileOperationDialog::askRename(const FileInfo &src, const FileInfo &dest, FilePath &newDest) {
    FileOperationJob::FileExistsAction ret;
    if(defaultOption == -1) { // default action is not set, ask the user
        RenameDialog dlg(src, dest, this);
        dlg.exec();
        switch(dlg.action()) {
        case RenameDialog::ActionOverwrite:
            ret = FileOperationJob::OVERWRITE;
            if(dlg.applyToAll()) {
                defaultOption = ret;
            }
            break;
        case RenameDialog::ActionRename: {
            ret = FileOperationJob::RENAME;
            auto newName = dlg.newName();
            if(!newName.isEmpty()) {
                auto destDirPath = dest.path().parent();
                newDest = destDirPath.child(newName.toUtf8().constData());
            }
            break;
        }
        case RenameDialog::ActionIgnore:
            ret = FileOperationJob::SKIP;
            if(dlg.applyToAll()) {
                defaultOption = ret;
            }
            break;
        default:
            ret = FileOperationJob::CANCEL;
            break;
        }
    }
    else {
        ret = (FileOperationJob::FileExistsAction)defaultOption;
    }
    return ret;
}

Job::ErrorAction FileOperationDialog::error(GError* err, Job::ErrorSeverity severity) {
    if(severity >= Job::ErrorSeverity::MODERATE) {
        if(severity == Job::ErrorSeverity::CRITICAL) {
            QMessageBox::critical(this, tr("Error"), QString::fromUtf8(err->message));
            return Job::ErrorAction::ABORT;
        }
        if (ignoreNonCriticalErrors_) {
            return Job::ErrorAction::CONTINUE;
        }
        QMessageBox::StandardButton stb = QMessageBox::critical(this, tr("Error"), QString::fromUtf8(err->message),
                                                                QMessageBox::Ok | QMessageBox::Ignore);
        if (stb == QMessageBox::Ignore) {
            ignoreNonCriticalErrors_ = true;
        }
    }
    return Job::ErrorAction::CONTINUE;
}

void FileOperationDialog::setCurFile(QString cur_file) {
    ui->curFile->setText(cur_file);
}

void FileOperationDialog::setDataTransferred(uint64_t finishedSize, std::uint64_t totalSize) {
    ui->filesProcessed->setText(QString("%1 / %2")
                                 .arg(formatFileSize(finishedSize, fm_config->si_unit))
                                 .arg(formatFileSize(totalSize, fm_config->si_unit)));
}

void FileOperationDialog::setFilesProcessed(uint64_t finishedCount, uint64_t totalCount) {
    ui->filesProcessed->setText(QString("%1 / %2")
                                 .arg(finishedCount)
                                 .arg(totalCount));
}

void FileOperationDialog::setPercent(unsigned int percent) {
    ui->progressBar->setValue(percent);
}

void FileOperationDialog::setRemainingTime(unsigned int sec) {
    unsigned int min = 0;
    unsigned int hr = 0;
    if(sec > 60) {
        min = sec / 60;
        sec %= 60;
        if(min > 60) {
            hr = min / 60;
            min %= 60;
        }
    }
    ui->timeRemaining->setText(QString("%1:%2:%3")
                               .arg(hr, 2, 10, QChar('0'))
                               .arg(min, 2, 10, QChar('0'))
                               .arg(sec, 2, 10, QChar('0')));
}

void FileOperationDialog::setPrepared() {
}

void FileOperationDialog::reject() {
    operation->cancel();
    QDialog::reject();
}

} // namespace Fm
<|endoftext|>


<commit_before>#include "../include/hmc.hpp"
#include "../include/all_hamils.hpp"
#include "../include/leapfrog.hpp"
#include "../include/mklrand.hpp"
#include "../include/constants.hpp"
#include <cmath>
#include <exception>
#include <iostream>
#define _USE_MATH_DEFINES

bool hmc::accept_trial( const double e, const double e_trial,
                         mklrand::mkl_drand &rng )
{
    double e_diff = e_trial - e;
    double acceptance_threshold = std::exp( -e_diff );
    return ( rng.gen() < acceptance_threshold );
}

double hmc::kinetic_energy(
    const std::valarray<double> velocity )
{
    double energy=0;
    for( auto &v : velocity )
        energy += v * v;
    return energy/2.0;
}

std::vector<std::valarray<double> > hmc::hmc(
    std::valarray<double> &energy,
    const std::valarray<double> &initial_state,
    const double leapfrog_eps,
    const size_t leapfrog_steps,
    const size_t samples,
    const std::function<double(const std::valarray<double>&)> &f_energy,
    const std::function<void(std::valarray<double>&, const std::valarray<double>&)> &f_energy_grad,
    const std::function<std::valarray<double>(const std::valarray<double>&)> &reduce )
{
    // system size
    size_t system_size = initial_state.size();

    // initialise vector of results
    std::vector<std::valarray<double> > trace;

    // allocate memory for work
    std::valarray<double> current_state( initial_state );
    std::valarray<double> current_velocity( system_size );
    std::valarray<double> temp_state( system_size );
    std::valarray<double> temp_velocity( system_size );
    std::valarray<double> trial_state( system_size );
    std::valarray<double> trial_velocity( system_size );
    std::valarray<double> work( system_size );

    // Allocate RNGs
    mklrand::mkl_drand uniform_rng( 100000, 1001 );
    mklrand::mkl_nrand normal_rng( 0, 1, 100000, 555555 );

    // Total energy
    std::function<double(const std::valarray<double>&, const std::valarray<double>&)>
        total_energy = [&f_energy](const std::valarray<double>& state, const std::valarray<double>& velocities)
        { return f_energy( state ) + kinetic_energy( velocities ); };

    // Run a monte carlo step until we get specific number of samples
    for( unsigned int sample=0; sample<samples; sample++ )
    {
        // Get the initial state and a random choice of velocity
        temp_state = current_state;
        for( unsigned int i=0; i<system_size; i++ )
            temp_velocity[i] = normal_rng.gen();
        current_velocity = temp_velocity;

        // Run a number of leapfrog steps
        for( unsigned int n=0; n<leapfrog_steps; n++ )
        {
            leapfrog::lfs( trial_state, trial_velocity, work,
                           temp_state, temp_velocity,
                           f_energy_grad,
                           leapfrog_eps );

            // Update arrays
            temp_state = trial_state;
            temp_velocity = trial_velocity;
        }

        // Compute energies
        double current_energy = total_energy( current_state, current_velocity );
        double trial_energy = total_energy( trial_state, trial_velocity );

        // check acceptance
        bool accept = accept_trial( current_energy, trial_energy, uniform_rng );
        if( accept )
        {
            current_state = trial_state;
            current_energy = trial_energy;
        }

        // Store the energy
        energy[sample] = current_energy;

        // Store the reduced parameters
        trace.push_back( reduce( current_state ) );
    }

    return trace;
}

std::vector<std::valarray<double> > hmc::nuts(
    std::valarray<double> &sample_energy,
    const std::valarray<double> &initial_state,
    const double leapfrog_eps,
    const size_t samples,
    const std::function<double(const std::valarray<double>&)> &f_energy,
    const std::function<void(std::valarray<double>&, const std::valarray<double>&)> &f_energy_grad,
    const std::function<std::valarray<double>(const std::valarray<double>&)> &reduce
)
{
    // system size
    size_t system_size = initial_state.size();

    // initialise vector of results
    std::vector<std::valarray<double> > trace;

    // allocate memory for work
    std::valarray<double> current_state( initial_state );
    std::valarray<double> current_velocity( system_size );
    std::valarray<double> temp_state( system_size );
    std::valarray<double> temp_velocity( system_size );
    std::valarray<double> work( system_size );
    std::vector<std::valarray<double> > state_tree(100, std::valarray<double>(system_size));
    std::vector<std::valarray<double> > velocity_tree(100, std::valarray<double>(system_size));
    std::vector<std::valarray<double> > fb_state(2, std::valarray<double>(system_size));
    std::vector<std::valarray<double> > fb_velocity(2, std::valarray<double>(system_size));
    fb_state[0] = current_state;
    fb_state[1] = current_state;
    fb_velocity[0] = current_velocity;
    fb_velocity[1] = current_velocity;

    // Allocate RNGs
    mklrand::mkl_irand int_rng(100000, 666);
    mklrand::mkl_drand uniform_rng( 100000, 1001 );
    mklrand::mkl_nrand normal_rng( 0, 1, 100000, 555555 );

    // Total energy
    std::function<double(const std::valarray<double>&, const std::valarray<double>&)>
        total_energy = [&f_energy](const std::valarray<double>& state, const std::valarray<double>& velocities)
        { return f_energy( state ) + kinetic_energy( velocities ); };

    // Run a monte carlo step until we get specific number of samples
    for( unsigned int sample=0; sample<samples; sample++ )
    {
        // Get the initial state and a random choice of velocity
        for( unsigned int i=0; i<system_size; i++ )
            current_velocity[i] = normal_rng.gen();
        fb_velocity[0] = current_velocity;
        fb_velocity[1] = current_velocity;

        // Init tree size
        int tree_size = 1;
        int tree_count = 1;
        state_tree[0] = current_state;
        velocity_tree[0] = current_velocity;
        int tree_height = 1;

        // Find acceptance slice
        double current_energy = total_energy( current_state, current_velocity );
        int u = uniform_rng.gen() * std::exp( -current_energy );

        bool check1 = true, check2 = true;
        // Begin building tree
        while(check1 && check2)
        {
            // Pick random direction
            int dir_choice = int_rng.gen();
            int other_choice = (dir_choice+1)%2;
            temp_state = fb_state[dir_choice];
            temp_velocity = fb_state[dir_choice];
            int dir = dir_choice*2 - 1;

            // Run leapfrog in that direction
            for (int i=0; i < tree_height; i++)
            {
                leapfrog::lfs( state_tree[tree_count],
                               velocity_tree[tree_count], work,
                               temp_state, temp_velocity,
                               f_energy_grad,
                               dir*leapfrog_eps );

                // Update arrays
                temp_state = state_tree[tree_count];
                temp_velocity = velocity_tree[tree_count];
                tree_count++;

                // Check break
                if(i == tree_height - 1) {continue;}
                check1 *= -total_energy(temp_state, temp_velocity) > u - 1000;
                check2 *= dir * ((temp_state - fb_state[other_choice]) *
                         temp_velocity).sum() >= 0;
                check2 *= dir * ((temp_state - fb_state[other_choice]) *
                         fb_velocity[other_choice]).sum() >= 0;
            }

            if (check1 && check2)
            {
                // Add to tree size
                tree_size += tree_height;
                tree_height *= 2;

                fb_state[dir_choice] = temp_state;
                fb_velocity[dir_choice] = temp_velocity;

                check1 *= -total_energy(temp_state, temp_velocity) > u - 1000;
                check2 *= ((fb_state[0] - fb_state[1]) * fb_velocity[0]).sum() >= 0;
                check2 *= ((fb_state[0] - fb_state[1]) * fb_velocity[1]).sum() >= 0;
            }
        }

        // Randomly Sample from the tree
        int choice = int(uniform_rng.gen()*tree_size);
        current_state = state_tree[choice];
        current_velocity = velocity_tree[choice];
        fb_state[0] = current_state;
        fb_state[1] = current_state;

        // Store the energy
        sample_energy[sample] = f_energy(current_state);

        // Store the reduced parameters
        trace.push_back( reduce( current_state ) );
    }

    return trace;
}

/// Interface to Heisenberg hmc
void hmc::heisenberg_model(
    std::valarray<double> &sample_energy,
    std::valarray<double> &sample_magnetisation,
    const std::vector<size_t> system_dimensions,
    const HamiltonianOptions options,
    const double beta,
    const double leapfrog_eps,
    const size_t leapfrog_steps,
    const size_t nsamples,
    const long initial_state_seed )
{
    // Compute the size of the state vector
    // theta and phi for every element in system
    const double state_size = 2 * std::accumulate(
        system_dimensions.begin(),
        system_dimensions.end(),
        1, std::multiplies<double>() );

    // Random initial state is controlled with the initial_state_seed
    std::valarray<double> initial_state( state_size );
    mklrand::mkl_drand rng( initial_state_seed );
    for( unsigned int i=0; i<state_size; i++ )
        initial_state[i] = rng.gen() * 2 * M_PI;

    // Get the Hamiltonian and gradient functions
    size_t ndim = system_dimensions.size();
    auto energy_function = gen_total_energy( options, beta, ndim );
    auto grad_function = gen_total_grad( options, ndim );

    // Reduction to compute the magnetisation
    std::function<std::valarray<double>(const std::valarray<double>&)>
        reduce = []( const std::valarray<double>& state )
        {
            std::valarray<double> res = { magnetisation( state ) };
            return res;
        };

    // EXECUTE HMC
    auto trace = hmc::hmc( sample_energy, initial_state, leapfrog_eps, leapfrog_steps, nsamples,
                           energy_function, grad_function, reduce );

    // Energy is returned normalised so we turn it into real energy
    sample_energy = sample_energy / beta;

    // Magnetisation is stored in the trace
    for( size_t n=0; n<nsamples; n++ )
        sample_magnetisation[n] = trace[n][0];
}

double hmc::magnetisation( const std::valarray<double>& state )
{
    int halfsize = state.size() / 2;
    std::slice tslice(0, halfsize, 1);
    std::slice pslice(halfsize, halfsize, 1);
    double x = ( cos( state[tslice] ) * sin( state[pslice] ) ).sum();
    double y = ( sin( state[tslice] ) * sin( state[pslice] ) ).sum();
    double z = cos( state[pslice] ).sum();
    return std::sqrt( x*x + y*y + z*z );
}
<commit_msg>Tweeks, still not working<commit_after>#include "../include/hmc.hpp"
#include "../include/all_hamils.hpp"
#include "../include/leapfrog.hpp"
#include "../include/mklrand.hpp"
#include "../include/constants.hpp"
#include <cmath>
#include <exception>
#include <iostream>
#define _USE_MATH_DEFINES

bool hmc::accept_trial( const double e, const double e_trial,
                         mklrand::mkl_drand &rng )
{
    double e_diff = e_trial - e;
    double acceptance_threshold = std::exp( -e_diff );
    return ( rng.gen() < acceptance_threshold );
}

double hmc::kinetic_energy(
    const std::valarray<double> velocity )
{
    double energy=0;
    for( auto &v : velocity )
        energy += v * v;
    return energy/2.0;
}

std::vector<std::valarray<double> > hmc::hmc(
    std::valarray<double> &energy,
    const std::valarray<double> &initial_state,
    const double leapfrog_eps,
    const size_t leapfrog_steps,
    const size_t samples,
    const std::function<double(const std::valarray<double>&)> &f_energy,
    const std::function<void(std::valarray<double>&, const std::valarray<double>&)> &f_energy_grad,
    const std::function<std::valarray<double>(const std::valarray<double>&)> &reduce )
{
    // system size
    size_t system_size = initial_state.size();

    // initialise vector of results
    std::vector<std::valarray<double> > trace;

    // allocate memory for work
    std::valarray<double> current_state( initial_state );
    std::valarray<double> current_velocity( system_size );
    std::valarray<double> temp_state( system_size );
    std::valarray<double> temp_velocity( system_size );
    std::valarray<double> trial_state( system_size );
    std::valarray<double> trial_velocity( system_size );
    std::valarray<double> work( system_size );

    // Allocate RNGs
    mklrand::mkl_drand uniform_rng( 100000, 1001 );
    mklrand::mkl_nrand normal_rng( 0, 1, 100000, 555555 );

    // Total energy
    std::function<double(const std::valarray<double>&, const std::valarray<double>&)>
        total_energy = [&f_energy](const std::valarray<double>& state, const std::valarray<double>& velocities)
        { return f_energy( state ) + kinetic_energy( velocities ); };

    // Run a monte carlo step until we get specific number of samples
    for( unsigned int sample=0; sample<samples; sample++ )
    {
        // Get the initial state and a random choice of velocity
        temp_state = current_state;
        for( unsigned int i=0; i<system_size; i++ )
            temp_velocity[i] = normal_rng.gen();
        current_velocity = temp_velocity;

        // Run a number of leapfrog steps
        for( unsigned int n=0; n<leapfrog_steps; n++ )
        {
            leapfrog::lfs( trial_state, trial_velocity, work,
                           temp_state, temp_velocity,
                           f_energy_grad,
                           leapfrog_eps );

            // Update arrays
            temp_state = trial_state;
            temp_velocity = trial_velocity;
        }

        // Compute energies
        double current_energy = total_energy( current_state, current_velocity );
        double trial_energy = total_energy( trial_state, trial_velocity );

        // check acceptance
        bool accept = accept_trial( current_energy, trial_energy, uniform_rng );
        if( accept )
        {
            current_state = trial_state;
            current_energy = trial_energy;
        }

        // Store the energy
        energy[sample] = f_energy(current_state);

        // Store the reduced parameters
        trace.push_back( reduce( current_state ) );
    }

    return trace;
}

std::vector<std::valarray<double> > hmc::nuts(
    std::valarray<double> &sample_energy,
    const std::valarray<double> &initial_state,
    const double leapfrog_eps,
    const size_t samples,
    const std::function<double(const std::valarray<double>&)> &f_energy,
    const std::function<void(std::valarray<double>&, const std::valarray<double>&)> &f_energy_grad,
    const std::function<std::valarray<double>(const std::valarray<double>&)> &reduce
)
{
    // system size
    size_t system_size = initial_state.size();

    // initialise vector of results
    std::vector<std::valarray<double> > trace;

    // allocate memory for work
    std::valarray<double> current_state( initial_state );
    std::valarray<double> current_velocity( system_size );
    std::valarray<double> temp_state( system_size );
    std::valarray<double> temp_velocity( system_size );
    std::valarray<double> work( system_size );
    std::vector<std::valarray<double> > state_tree(100, std::valarray<double>(system_size));
    std::vector<std::valarray<double> > velocity_tree(100, std::valarray<double>(system_size));
    std::vector<std::valarray<double> > fb_state(2, std::valarray<double>(system_size));
    std::vector<std::valarray<double> > fb_velocity(2, std::valarray<double>(system_size));
    fb_state[0] = current_state;
    fb_state[1] = current_state;
    fb_velocity[0] = current_velocity;
    fb_velocity[1] = current_velocity;

    // Allocate RNGs
    mklrand::mkl_irand int_rng(100000, 666);
    mklrand::mkl_drand uniform_rng( 100000, 1001 );
    mklrand::mkl_nrand normal_rng( 0, 1, 100000, 555555 );

    // Total energy
    std::function<double(const std::valarray<double>&, const std::valarray<double>&)>
        total_energy = [&f_energy](const std::valarray<double>& state, const std::valarray<double>& velocities)
        { return f_energy( state ) + kinetic_energy( velocities ); };

    // Run a monte carlo step until we get specific number of samples
    for( unsigned int sample=0; sample<samples; sample++ )
    {
        // Get the initial state and a random choice of velocity
        for( unsigned int i=0; i<system_size; i++ )
            current_velocity[i] = normal_rng.gen();
        fb_velocity[0] = current_velocity;
        fb_velocity[1] = current_velocity;

        // Init tree size
        int tree_size = 1;
        int tree_count = 1;
        state_tree[0] = current_state;
        velocity_tree[0] = current_velocity;
        int tree_height = 1;

        // Find acceptance slice
        double current_energy = total_energy( current_state, current_velocity );
        double u = uniform_rng.gen() * std::exp( -current_energy );
        double lu = std::log(u);

        bool check1 = true, check2 = true;
        // Begin building tree
        while(check1 && check2)
        {
            // Pick random direction
            int dir_choice = int_rng.gen();
            int other_choice = (dir_choice+1)%2;
            temp_state = fb_state[dir_choice];
            temp_velocity = fb_state[dir_choice];
            int dir = dir_choice*2 - 1;

            // Run leapfrog in that direction
            int tree_added = 0;
            for (int i=0; i < tree_height; i++)
            {
                leapfrog::lfs( state_tree[tree_count],
                               velocity_tree[tree_count], work,
                               temp_state, temp_velocity,
                               f_energy_grad,
                               dir*leapfrog_eps );

                // Update arrays
                temp_state = state_tree[tree_count];
                temp_velocity = velocity_tree[tree_count];
                double temp_E = total_energy(temp_state, temp_velocity);
                if (temp_E >= lu)
                {
                    tree_count++;
                    tree_added++;
                }

                // Check break
                if(i == tree_height - 1) {continue;}
                // check1 *= -total_energy(temp_state, temp_velocity) > lu - 1000;
                check2 *= dir * ((temp_state - fb_state[other_choice]) *
                         temp_velocity).sum() >= 0;
                check2 *= dir * ((temp_state - fb_state[other_choice]) *
                         fb_velocity[other_choice]).sum() >= 0;
            }

            if (check1 && check2)
            {
                // Add to tree size
                tree_size += tree_added;
                tree_height *= 2;

                fb_state[dir_choice] = temp_state;
                fb_velocity[dir_choice] = temp_velocity;

                // check1 *= -total_energy(temp_state, temp_velocity) > std::log(u) - 1000;
                check2 *= ((fb_state[0] - fb_state[1]) * fb_velocity[0]).sum() >= 0;
                check2 *= ((fb_state[0] - fb_state[1]) * fb_velocity[1]).sum() >= 0;
            }
        }

        // Randomly Sample from the tree
        int choice = int(uniform_rng.gen()*tree_size);
        current_state = state_tree[choice];
        current_velocity = velocity_tree[choice];
        fb_state[0] = current_state;
        fb_state[1] = current_state;

        // Store the energy
        sample_energy[sample] = f_energy(current_state);

        // Store the reduced parameters
        trace.push_back( reduce( current_state ) );
    }

    return trace;
}

/// Interface to Heisenberg hmc
void hmc::heisenberg_model(
    std::valarray<double> &sample_energy,
    std::valarray<double> &sample_magnetisation,
    const std::vector<size_t> system_dimensions,
    const HamiltonianOptions options,
    const double beta,
    const double leapfrog_eps,
    const size_t leapfrog_steps,
    const size_t nsamples,
    const long initial_state_seed )
{
    // Compute the size of the state vector
    // theta and phi for every element in system
    const double state_size = 2 * std::accumulate(
        system_dimensions.begin(),
        system_dimensions.end(),
        1, std::multiplies<double>() );

    // Random initial state is controlled with the initial_state_seed
    std::valarray<double> initial_state( state_size );
    mklrand::mkl_drand rng( initial_state_seed );
    for( unsigned int i=0; i<state_size; i++ )
        initial_state[i] = rng.gen() * 2 * M_PI;

    // Get the Hamiltonian and gradient functions
    size_t ndim = system_dimensions.size();
    auto energy_function = gen_total_energy( options, beta, ndim );
    auto grad_function = gen_total_grad( options, ndim );

    // Reduction to compute the magnetisation
    std::function<std::valarray<double>(const std::valarray<double>&)>
        reduce = []( const std::valarray<double>& state )
        {
            std::valarray<double> res = { magnetisation( state ) };
            return res;
        };

    // EXECUTE HMC
    auto trace = hmc::hmc( sample_energy, initial_state, leapfrog_eps, leapfrog_steps, nsamples,
                           energy_function, grad_function, reduce );

    // Energy is returned normalised so we turn it into real energy
    sample_energy = sample_energy / beta;

    // Magnetisation is stored in the trace
    for( size_t n=0; n<nsamples; n++ )
        sample_magnetisation[n] = trace[n][0];
}

double hmc::magnetisation( const std::valarray<double>& state )
{
    int halfsize = state.size() / 2;
    std::slice tslice(0, halfsize, 1);
    std::slice pslice(halfsize, halfsize, 1);
    double x = ( cos( state[tslice] ) * sin( state[pslice] ) ).sum();
    double y = ( sin( state[tslice] ) * sin( state[pslice] ) ).sum();
    double z = cos( state[pslice] ).sum();
    return std::sqrt( x*x + y*y + z*z );
}
<|endoftext|>


<commit_before>/*
**  Copyright (C) 2012 Aldebaran Robotics
**  See COPYING for the license
*/
#include "servicedirectoryclient.hpp"
#include <qitype/objecttypebuilder.hpp>
#include "servicedirectory_p.hpp"
#include "tcptransportsocket.hpp"

qiLogCategory("qimessaging.servicedirectoryclient");

namespace qi {

  ServiceDirectoryClient::ServiceDirectoryClient()
    : _remoteObject(qi::Message::Service_ServiceDirectory)
    , _addLink(0)
    , _removeLink(0)
  {
    _object = makeDynamicObjectPtr(&_remoteObject, false);
  }

  ServiceDirectoryClient::~ServiceDirectoryClient()
  {
    close();
  }

 void ServiceDirectoryClient::onSDEventConnected(qi::Future<unsigned int> ret,
   qi::Promise<bool> fco, bool isAdd)
 {
   if (fco.future().wait(-1))
     return;
   if (ret.hasError())
   {
     fco.setError(ret.error());
     return;
   }
   if (isAdd)
     _addLink = ret.value();
   else
     _removeLink = ret.value();
   if (_addLink && _removeLink)
   {
     fco.setValue(true);
     connected();
   }
 }

  void ServiceDirectoryClient::onMetaObjectFetched(qi::Future<void> future, qi::Promise<bool> promise) {
    if (future.hasError()) {
      promise.setError(future.error());
      return;
    }
    boost::function<void (unsigned int, std::string)> f;

    f = boost::bind<void>(&ServiceDirectoryClient::onServiceAdded, this, _1, _2);
    qi::Future<unsigned int> fut1 = _object->connect("serviceAdded", f);

    f = boost::bind<void>(&ServiceDirectoryClient::onServiceRemoved, this, _1, _2);
    qi::Future<unsigned int> fut2 = _object->connect("serviceRemoved", f);

    fut1.connect(boost::bind<void>(&ServiceDirectoryClient::onSDEventConnected, this, _1, promise, true));
    fut2.connect(boost::bind<void>(&ServiceDirectoryClient::onSDEventConnected, this, _1, promise, false));
  }

  void ServiceDirectoryClient::onSocketConnected(qi::FutureSync<bool> future, qi::Promise<bool> promise) {
    if (future.hasError()) {
      promise.setError(future.error());
      return;
    }
    if (future.value() == false) {
      promise.setValue(false);
      return;
    }
    qi::Future<void> fut = _remoteObject.fetchMetaObject();
    fut.connect(boost::bind<void>(&ServiceDirectoryClient::onMetaObjectFetched, this, _1, promise));
  }

  //we ensure in that function that connect to all events are already setup when we said we are connect.
  //that way we cant be connected without being fully ready.
  qi::FutureSync<bool> ServiceDirectoryClient::connect(const qi::Url &serviceDirectoryURL) {
    if (isConnected()) {
      qiLogInfo() << "Session is already connected";
      return qi::Future<bool>(false);
    }
    _sdSocket = qi::makeTransportSocket(serviceDirectoryURL.protocol());
    if (!_sdSocket)
      return qi::Future<bool>(false);
    _sdSocketDisconnectedLink = _sdSocket->disconnected.connect(boost::bind<void>(&ServiceDirectoryClient::onSocketDisconnected, this, _1));
    _remoteObject.setTransportSocket(_sdSocket);

    qi::Promise<bool> promise;
    qi::Future<bool> fut = _sdSocket->connect(serviceDirectoryURL);
    fut.connect(boost::bind<void>(&ServiceDirectoryClient::onSocketConnected, this, _1, promise));
    return promise.future();
  }

  static void sharedPtrHolder(TransportSocketPtr ptr)
  {
  }

  qi::FutureSync<void> ServiceDirectoryClient::close() {
    if (!_sdSocket)
      return qi::Future<void>(0);
    qi::Future<void> fut = _sdSocket->disconnect();
    // Hold the socket shared ptr alive until the future returns.
    // otherwise, the destructor will block us until disconnect terminates
    fut.connect(boost::bind(&sharedPtrHolder, _sdSocket));
    _sdSocket->disconnected.disconnect(_sdSocketDisconnectedLink);
    _sdSocket.reset();
    return fut;
  }

  bool                 ServiceDirectoryClient::isConnected() const {
    return _sdSocket == 0 ? false : _sdSocket->isConnected();
  }

  qi::Url              ServiceDirectoryClient::url() const {
    return _sdSocket->url();
  }

  void ServiceDirectoryClient::onServiceRemoved(unsigned int idx, const std::string &name) {
    qiLogVerbose() << "ServiceDirectory: Service Removed #" << idx << ": " << name << std::endl;
    serviceRemoved(idx, name);
  }

  void ServiceDirectoryClient::onServiceAdded(unsigned int idx, const std::string &name) {
    qiLogVerbose() << "ServiceDirectory: Service Added #" << idx << ": " << name << std::endl;
    serviceAdded(idx, name);
  }

  void ServiceDirectoryClient::onSocketDisconnected(int error) {
    disconnected(error);
    _object->disconnect(_addLink);
    _object->disconnect(_removeLink);
    _addLink = _removeLink = 0;
  }

  qi::Future< std::vector<ServiceInfo> > ServiceDirectoryClient::services() {
    return _object->call< std::vector<ServiceInfo> >("services");
  }

  qi::Future<ServiceInfo>              ServiceDirectoryClient::service(const std::string &name) {
    return _object->call< ServiceInfo >("service", name);
  }

  qi::Future<unsigned int>             ServiceDirectoryClient::registerService(const ServiceInfo &svcinfo) {
    return _object->call< unsigned int >("registerService", svcinfo);
  }

  qi::Future<void>                     ServiceDirectoryClient::unregisterService(const unsigned int &idx) {
    return _object->call<void>("unregisterService", idx);
  }

  qi::Future<void>                     ServiceDirectoryClient::serviceReady(const unsigned int &idx) {
    return _object->call<void>("serviceReady", idx);
  }

}
<commit_msg>ServiceDirectoryClient: Fix shared_ptr loop preventing socket destruction.<commit_after>/*
**  Copyright (C) 2012 Aldebaran Robotics
**  See COPYING for the license
*/
#include "servicedirectoryclient.hpp"
#include <qitype/objecttypebuilder.hpp>
#include "servicedirectory_p.hpp"
#include "tcptransportsocket.hpp"

qiLogCategory("qimessaging.servicedirectoryclient");

namespace qi {

  ServiceDirectoryClient::ServiceDirectoryClient()
    : _remoteObject(qi::Message::Service_ServiceDirectory)
    , _addLink(0)
    , _removeLink(0)
  {
    _object = makeDynamicObjectPtr(&_remoteObject, false);
  }

  ServiceDirectoryClient::~ServiceDirectoryClient()
  {
    close();
  }

 void ServiceDirectoryClient::onSDEventConnected(qi::Future<unsigned int> ret,
   qi::Promise<bool> fco, bool isAdd)
 {
   if (fco.future().wait(-1))
     return;
   if (ret.hasError())
   {
     fco.setError(ret.error());
     return;
   }
   if (isAdd)
     _addLink = ret.value();
   else
     _removeLink = ret.value();
   if (_addLink && _removeLink)
   {
     fco.setValue(true);
     connected();
   }
 }

  void ServiceDirectoryClient::onMetaObjectFetched(qi::Future<void> future, qi::Promise<bool> promise) {
    if (future.hasError()) {
      promise.setError(future.error());
      return;
    }
    boost::function<void (unsigned int, std::string)> f;

    f = boost::bind<void>(&ServiceDirectoryClient::onServiceAdded, this, _1, _2);
    qi::Future<unsigned int> fut1 = _object->connect("serviceAdded", f);

    f = boost::bind<void>(&ServiceDirectoryClient::onServiceRemoved, this, _1, _2);
    qi::Future<unsigned int> fut2 = _object->connect("serviceRemoved", f);

    fut1.connect(boost::bind<void>(&ServiceDirectoryClient::onSDEventConnected, this, _1, promise, true));
    fut2.connect(boost::bind<void>(&ServiceDirectoryClient::onSDEventConnected, this, _1, promise, false));
  }

  void ServiceDirectoryClient::onSocketConnected(qi::FutureSync<bool> future, qi::Promise<bool> promise) {
    if (future.hasError()) {
      promise.setError(future.error());
      return;
    }
    if (future.value() == false) {
      promise.setValue(false);
      return;
    }
    qi::Future<void> fut = _remoteObject.fetchMetaObject();
    fut.connect(boost::bind<void>(&ServiceDirectoryClient::onMetaObjectFetched, this, _1, promise));
  }

  //we ensure in that function that connect to all events are already setup when we said we are connect.
  //that way we cant be connected without being fully ready.
  qi::FutureSync<bool> ServiceDirectoryClient::connect(const qi::Url &serviceDirectoryURL) {
    if (isConnected()) {
      qiLogInfo() << "Session is already connected";
      return qi::Future<bool>(false);
    }
    _sdSocket = qi::makeTransportSocket(serviceDirectoryURL.protocol());
    if (!_sdSocket)
      return qi::Future<bool>(false);
    _sdSocketDisconnectedLink = _sdSocket->disconnected.connect(boost::bind<void>(&ServiceDirectoryClient::onSocketDisconnected, this, _1));
    _remoteObject.setTransportSocket(_sdSocket);

    qi::Promise<bool> promise;
    qi::Future<bool> fut = _sdSocket->connect(serviceDirectoryURL);
    fut.connect(boost::bind<void>(&ServiceDirectoryClient::onSocketConnected, this, _1, promise));
    return promise.future();
  }

  static void sharedPtrHolder(TransportSocketPtr* ptr)
  {
    delete ptr;
  }

  qi::FutureSync<void> ServiceDirectoryClient::close() {
    if (!_sdSocket)
      return qi::Future<void>(0);
    qi::Future<void> fut = _sdSocket->disconnect();
    // Hold the socket shared ptr alive until the future returns.
    // otherwise, the destructor will block us until disconnect terminates
    // Nasty glitch: socket is reusing promises, so this future hook will stay
    // So pass shared pointer by pointer: that way a single delete statement
    // will end all copies.
    fut.connect(boost::bind(&sharedPtrHolder, new TransportSocketPtr(_sdSocket)));
    _sdSocket->disconnected.disconnect(_sdSocketDisconnectedLink);
    _sdSocket.reset();
    return fut;
  }

  bool                 ServiceDirectoryClient::isConnected() const {
    return _sdSocket == 0 ? false : _sdSocket->isConnected();
  }

  qi::Url              ServiceDirectoryClient::url() const {
    return _sdSocket->url();
  }

  void ServiceDirectoryClient::onServiceRemoved(unsigned int idx, const std::string &name) {
    qiLogVerbose() << "ServiceDirectory: Service Removed #" << idx << ": " << name << std::endl;
    serviceRemoved(idx, name);
  }

  void ServiceDirectoryClient::onServiceAdded(unsigned int idx, const std::string &name) {
    qiLogVerbose() << "ServiceDirectory: Service Added #" << idx << ": " << name << std::endl;
    serviceAdded(idx, name);
  }

  void ServiceDirectoryClient::onSocketDisconnected(int error) {
    disconnected(error);
    _object->disconnect(_addLink);
    _object->disconnect(_removeLink);
    _addLink = _removeLink = 0;
  }

  qi::Future< std::vector<ServiceInfo> > ServiceDirectoryClient::services() {
    return _object->call< std::vector<ServiceInfo> >("services");
  }

  qi::Future<ServiceInfo>              ServiceDirectoryClient::service(const std::string &name) {
    return _object->call< ServiceInfo >("service", name);
  }

  qi::Future<unsigned int>             ServiceDirectoryClient::registerService(const ServiceInfo &svcinfo) {
    return _object->call< unsigned int >("registerService", svcinfo);
  }

  qi::Future<void>                     ServiceDirectoryClient::unregisterService(const unsigned int &idx) {
    return _object->call<void>("unregisterService", idx);
  }

  qi::Future<void>                     ServiceDirectoryClient::serviceReady(const unsigned int &idx) {
    return _object->call<void>("serviceReady", idx);
  }

}
<|endoftext|>


<commit_before>#pragma once

#include <functional>
#include <map>
#include <mutex>
#include <typeindex>
#include <vector>

#include "Event.hh"

#include <iostream>

namespace corniflex {

typedef std::function<void(Event *)>	t_fptr;

class EventManager {

private:
  std::map<std::type_index, std::vector<t_fptr > >	_eventHandlers;
  std::vector<std::pair<Event*, t_fptr > >		_events;
  std::mutex	_mutexHandlers;
  std::mutex	_mutexEvents;
  bool		_synchronous = false;

  unsigned long long	_nbProcessedEvent = 0;

public:
  // ----- ----- Getters ----- ----- //
  unsigned long long	getNbProcessedEvent() const;

  // ----- ----- Public Members ----- ----- //
  bool		hasHandler(const Event &event);
  void		addHandler(const Event &event, t_fptr handler);
  void		sendEvent(Event *event, t_fptr func);
  void		processLastEvent();
  void		processFirstEvent();
  void		setSynchronous(bool synchronous);

private:
  // ----- ----- Private Members ----- ----- //
  void		processEvent(Event *event, t_fptr func);
};

}
<commit_msg>Callback of sendEvent function is now optional<commit_after>#pragma once

#include <functional>
#include <map>
#include <mutex>
#include <typeindex>
#include <vector>

#include "Event.hh"

#include <iostream>

namespace corniflex {

typedef std::function<void(Event *)>	t_fptr;

class EventManager {

private:
  std::map<std::type_index, std::vector<t_fptr > >	_eventHandlers;
  std::vector<std::pair<Event*, t_fptr > >		_events;
  std::mutex	_mutexHandlers;
  std::mutex	_mutexEvents;
  bool		_synchronous = false;

  unsigned long long	_nbProcessedEvent = 0;

public:
  // ----- ----- Getters ----- ----- //
  unsigned long long	getNbProcessedEvent() const;

  // ----- ----- Public Members ----- ----- //
  bool		hasHandler(const Event &event);
  void		addHandler(const Event &event, t_fptr handler);
  void		sendEvent(Event *event, t_fptr func = nullptr);
  void		processLastEvent();
  void		processFirstEvent();
  void		setSynchronous(bool synchronous);

private:
  // ----- ----- Private Members ----- ----- //
  void		processEvent(Event *event, t_fptr func);
};

}
<|endoftext|>


<commit_before>//=======================================================================
// Copyright Baptiste Wicht 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#ifndef SPIRIT_LEXER_H
#define SPIRIT_LEXER_H

#include <fstream>
#include <string>
#include <utility>
#include <stack>

#include <boost/spirit/include/lex_lexertl.hpp>

namespace eddic {

namespace spirit = boost::spirit;
namespace lex = boost::spirit::lex;

typedef std::string::iterator base_iterator_type;
typedef lex::lexertl::token<base_iterator_type, boost::mpl::vector<unsigned int, std::string>, boost::mpl::false_> Tok;
typedef lex::lexertl::actor_lexer<Tok> lexer_type;

template<typename L>
class SimpleLexer : public lex::lexer<L> {
    private:

    public:
        SimpleLexer() {
            keyword_for = ("for");
            keyword_while = ("while");
            keyword_if = ("if");
            keyword_else = ("else");
            keyword_false = ("false");
            keyword_true = ("true");
            keyword_from = ("from");
            keyword_to = ("to");
            keyword_foreach = ("foreach");

            word = ("[a-zA-Z]*");
            integer = ("[0-9]*");
            litteral = ("\"[.]*\"");

            left_parenth = ("\\(");
            right_parenth = ("\\)");
            left_brace = ("\\{");
            right_brace = ("\\}");

            stop = (";");
            comma = (",");

            assign = ("=");
            swap = ("<>");
            addition = ("\\+");
            subtraction = ("-");
            multiplication = ("\\*");
            division = ("\\/");
            modulo = ("%");

            whitespaces = ("[ \\t\\n]+");
            comments = ("\\/\\*[^*]*\\*+([^/*][^*]*\\*+)*\\/");

            //Add keywords
            this->self = keyword_for | keyword_while | keyword_true | keyword_false | keyword_if | keyword_else | keyword_from | keyword_to | keyword_foreach;

            this->self += equals | not_equals | greater | less | greater_equals | less_equals;
            this->self += left_parenth | right_parenth | left_brace | right_brace;
            this->self += comma | stop;
            this->self += assign | swap | addition | subtraction | multiplication | division | modulo;
            this->self += integer | litteral | word;

            //Ignore whitespaces and comments
            this->self += whitespaces [lex::_pass = lex::pass_flags::pass_ignore];
            this->self += comments [lex::_pass = lex::pass_flags::pass_ignore];
        }

        lex::token_def<std::string> word, litteral, integer;

        lex::token_def<> left_parenth, right_parenth, left_brace, right_brace;

        lex::token_def<> stop, comma;

        lex::token_def<> assign, swap, addition, subtraction, multiplication, division, modulo;
        lex::token_def<> equals, not_equals, greater, less, greater_equals, less_equals;

        //Keywords
        lex::token_def<> keyword_if, keyword_else, keyword_for, keyword_while, keyword_from, keyword_to, keyword_foreach;
        lex::token_def<> keyword_true, keyword_false;

        //Ignored tokens
        lex::token_def<> whitespaces;
        lex::token_def<> comments;
};

class SpiritLexer {
    private:
        std::ifstream stream;

        SimpleLexer<lexer_type> lexer;

        lexer_type::iterator_type iter;
        lexer_type::iterator_type end;

        Tok current;
        Tok defaultToken;

        std::stack<Tok> buffer;

        bool readNext();

    public:
        SpiritLexer();

        void lex(const std::string& file);
        bool next();
        void pushBack(Tok token);

        Tok getCurrentToken() const;
        const Tok& getDefaultToken() const;

        bool isWord() const;
        bool isAssign() const;
        bool isSwap() const;
        bool isLitteral() const;
        bool isLeftParenth() const;
        bool isRightParenth() const;
        bool isLeftBrace() const;
        bool isRightBrace() const;
        bool isStop() const;
        bool isInteger() const;
        bool isAddition() const;
        bool isSubtraction() const;
        bool isMultiplication() const;
        bool isDivision() const;
        bool isModulo() const;
        bool isEquals() const;
        bool isNotEquals() const;
        bool isGreater() const;
        bool isLess() const;
        bool isGreaterOrEquals() const;
        bool isLessOrEquals() const;
        bool isIf() const;
        bool isElse() const;
        bool isWhile() const;
        bool isFor() const;
        bool isForeach() const;
        bool isFrom() const;
        bool isTo() const;
        bool isTrue() const;
        bool isFalse() const;
        bool isComma() const;

};

} //end of eddic

#endif
<commit_msg>Complete the lexer syntax<commit_after>//=======================================================================
// Copyright Baptiste Wicht 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#ifndef SPIRIT_LEXER_H
#define SPIRIT_LEXER_H

#include <fstream>
#include <string>
#include <utility>
#include <stack>

#include <boost/spirit/include/lex_lexertl.hpp>

namespace eddic {

namespace spirit = boost::spirit;
namespace lex = boost::spirit::lex;

typedef std::string::iterator base_iterator_type;
typedef lex::lexertl::token<base_iterator_type, boost::mpl::vector<unsigned int, std::string>, boost::mpl::false_> Tok;
typedef lex::lexertl::actor_lexer<Tok> lexer_type;

template<typename L>
class SimpleLexer : public lex::lexer<L> {
    private:

    public:
        SimpleLexer() {
            keyword_for = ("for");
            keyword_while = ("while");
            keyword_if = ("if");
            keyword_else = ("else");
            keyword_false = ("false");
            keyword_true = ("true");
            keyword_from = ("from");
            keyword_to = ("to");
            keyword_foreach = ("foreach");

            word = ("[a-zA-Z]*");
            integer = ("[0-9]*");
            litteral = ("\"[.]*\"");

            left_parenth = ("\\(");
            right_parenth = ("\\)");
            left_brace = ("\\{");
            right_brace = ("\\}");

            stop = (";");
            comma = (",");

            assign = ("=");
            swap = ("<>");
            addition = ("\\+");
            subtraction = ("-");
            multiplication = ("\\*");
            division = ("\\/");
            modulo = ("%");

            equals = ("==");
            not_equals = ("!=");
            greater = (">");
            less = ("<");
            greater_equals = (">=");
            less_equals = ("<=");

            whitespaces = ("[ \\t\\n]+");
            comments = ("\\/\\*[^*]*\\*+([^/*][^*]*\\*+)*\\/");

            //Add keywords
            this->self = keyword_for | keyword_while | keyword_true | keyword_false | keyword_if | keyword_else | keyword_from | keyword_to | keyword_foreach;

            this->self += equals | not_equals | greater | less | greater_equals | less_equals;
            this->self += left_parenth | right_parenth | left_brace | right_brace;
            this->self += comma | stop;
            this->self += assign | swap | addition | subtraction | multiplication | division | modulo;
            this->self += integer | litteral | word;

            //Ignore whitespaces and comments
            this->self += whitespaces [lex::_pass = lex::pass_flags::pass_ignore];
            this->self += comments [lex::_pass = lex::pass_flags::pass_ignore];
        }

        lex::token_def<std::string> word, litteral, integer;

        lex::token_def<> left_parenth, right_parenth, left_brace, right_brace;

        lex::token_def<> stop, comma;

        lex::token_def<> assign, swap, addition, subtraction, multiplication, division, modulo;
        lex::token_def<> equals, not_equals, greater, less, greater_equals, less_equals;

        //Keywords
        lex::token_def<> keyword_if, keyword_else, keyword_for, keyword_while, keyword_from, keyword_to, keyword_foreach;
        lex::token_def<> keyword_true, keyword_false;

        //Ignored tokens
        lex::token_def<> whitespaces;
        lex::token_def<> comments;
};

class SpiritLexer {
    private:
        std::ifstream stream;

        SimpleLexer<lexer_type> lexer;

        lexer_type::iterator_type iter;
        lexer_type::iterator_type end;

        Tok current;
        Tok defaultToken;

        std::stack<Tok> buffer;

        bool readNext();

    public:
        SpiritLexer();

        void lex(const std::string& file);
        bool next();
        void pushBack(Tok token);

        Tok getCurrentToken() const;
        const Tok& getDefaultToken() const;

        bool isWord() const;
        bool isAssign() const;
        bool isSwap() const;
        bool isLitteral() const;
        bool isLeftParenth() const;
        bool isRightParenth() const;
        bool isLeftBrace() const;
        bool isRightBrace() const;
        bool isStop() const;
        bool isInteger() const;
        bool isAddition() const;
        bool isSubtraction() const;
        bool isMultiplication() const;
        bool isDivision() const;
        bool isModulo() const;
        bool isEquals() const;
        bool isNotEquals() const;
        bool isGreater() const;
        bool isLess() const;
        bool isGreaterOrEquals() const;
        bool isLessOrEquals() const;
        bool isIf() const;
        bool isElse() const;
        bool isWhile() const;
        bool isFor() const;
        bool isForeach() const;
        bool isFrom() const;
        bool isTo() const;
        bool isTrue() const;
        bool isFalse() const;
        bool isComma() const;

};

} //end of eddic

#endif
<|endoftext|>


<commit_before>// This file is part of the ustl library, an STL implementation.
//
// Copyright (C) 2005 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
//
// memblock.cc
//
//	Allocated memory block.
//

#include "mistream.h"
#include "memblock.h"
#include "ualgo.h"
#include "umemory.h"
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>

namespace ustl {

/// Allocates 0 bytes for the internal block.
memblock::memblock (void)
: memlink (),
  m_Capacity (0)
{
}

/// Allocates \p n bytes for the internal block.
memblock::memblock (size_type n)
: memlink (),
  m_Capacity (0)
{
    resize (n);
}

/// links to \p p, \p n. Data can not be modified and will not be freed.
memblock::memblock (const void* p, size_type n)
: memlink (),
  m_Capacity (0)
{
    assign (p, n);
}

/// Links to what \p b is linked to.
memblock::memblock (const cmemlink& b)
: memlink (),
  m_Capacity (0)
{
    assign (b);
}

/// Links to what \p b is linked to.
memblock::memblock (const memlink& b)
: memlink (),
  m_Capacity (0)
{
    assign (b);
}

/// Links to what \p b is linked to.
memblock::memblock (const memblock& b)
: memlink (),
  m_Capacity (0)
{
    assign (b);
}

/// Frees internal data, if appropriate
/// Only if the block was allocated using resize, or linked to using Manage,
/// will it be freed. Also, Derived classes should call DestructBlock from
/// their destructor, because upstream virtual functions are unavailable at
/// this point and will not be called automatically.
///
memblock::~memblock (void)
{
    if (!is_linked())
	deallocate();
}

/// resizes the block to \p newSize bytes, reallocating if necessary.
void memblock::resize (size_type newSize, bool bExact)
{
    if (m_Capacity < newSize + minimumFreeCapacity())
	reserve (newSize, bExact);
    memlink::resize (newSize);
}

/// Frees internal data.
void memblock::deallocate (void) throw()
{
    if (m_Capacity) {
	assert (cdata() && "Internal error: space allocated, but the pointer is NULL");
	assert (data() && "Internal error: read-only block is marked as allocated space");
	free (data());
    }
    memblock::unlink();
}

/// Assumes control of the memory block \p p of size \p n.
/// The block assigned using this function will be freed in the destructor.
void memblock::manage (void* p, size_type n)
{
    assert (p || !n);
    assert (!data() || !m_Capacity);	// Can't link to an allocated block.
    link (p, n);
    m_Capacity = n;
}

/// Copies data from \p p, \p n.
void memblock::assign (const void* p, size_type n)
{
    assert ((p != (const void*) cdata() || size() == n) && "Self-assignment can not resize");
    resize (n);
    copy (p, n);
}

/// \brief Reallocates internal block to hold at least \p newSize bytes.
///
/// Additional memory may be allocated, but for efficiency it is a very
/// good idea to call reserve before doing byte-by-byte edit operations.
/// The block size as returned by size() is not altered. reserve will not
/// reduce allocated memory. If you think you are wasting space, call
/// deallocate and start over. To avoid wasting space, use the block for
/// only one purpose, and try to get that purpose to use similar amounts
/// of memory on each iteration.
///
void memblock::reserve (size_type newSize, bool bExact)
{
    if ((newSize += minimumFreeCapacity()) <= m_Capacity)
	return;
    void* oldBlock (is_linked() ? NULL : data());
    if (!bExact)
	newSize = Align (newSize, c_PageSize);
    pointer newBlock = (pointer) realloc (oldBlock, newSize);
    if (!newBlock)
	throw bad_alloc (newSize);
    if (!oldBlock && cdata())
	copy_n (cdata(), min (size() + 1, newSize), newBlock);
    link (newBlock, size());
    m_Capacity = newSize;
}

/// \warning Do not use or override this! It exists only for implementing #string
memblock::size_type memblock::minimumFreeCapacity (void) const
{
    return (0);
}

/// Swaps the contents with \p l
void memblock::swap (memblock& l)
{
    memlink::swap (l);
    ::ustl::swap (m_Capacity, l.m_Capacity);
}

/// Shifts the data in the linked block from \p start to \p start + \p n.
memblock::iterator memblock::insert (iterator start, size_type n)
{
    const uoff_t ip = start - begin();
    assert (ip <= size());
    resize (size() + n, false);
    memlink::insert (begin() + ip, n);
    return (begin() + ip);
}

/// Shifts the data in the linked block from \p start + \p n to \p start.
memblock::iterator memblock::erase (iterator start, size_type n)
{
    const uoff_t ep = start - begin();
    assert (ep + n <= size());
    memlink::erase (begin() + ep, n);
    memlink::resize (size() - n);
    return (begin() + ep);
}

/// Unlinks object.
void memblock::unlink (void)
{
    memlink::unlink();
    m_Capacity = 0;
}

/// Reads the object from stream \p s
void memblock::read (istream& is)
{
    size_type n;
    is >> n;
    if (is.remaining() < n)
	throw stream_bounds_exception ("read", "ustl::memblock", is.pos(), n, is.remaining());
    resize (n);
    is.read (data(), writable_size());
    is.align();
}

/// Reads the entire file \p "filename".
void memblock::read_file (const char* filename)
{
    struct stat st;
    if (stat (filename, &st))
	throw file_exception ("stat", filename);
    resize (st.st_size);
    int fd = open (filename, O_RDONLY);
    if (fd < 0)
	throw file_exception ("open", filename);
    const size_type btr = writable_size();
    ssize_t br = ::read (fd, data(), btr);
    if (size_type(br) != btr) {
	close (fd);
	throw file_exception ("read", filename);
    }
    close (fd);
}

} // namespace ustl

<commit_msg>Removed unneeded addition<commit_after>// This file is part of the ustl library, an STL implementation.
//
// Copyright (C) 2005 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
//
// memblock.cc
//
//	Allocated memory block.
//

#include "mistream.h"
#include "memblock.h"
#include "ualgo.h"
#include "umemory.h"
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>

namespace ustl {

/// Allocates 0 bytes for the internal block.
memblock::memblock (void)
: memlink (),
  m_Capacity (0)
{
}

/// Allocates \p n bytes for the internal block.
memblock::memblock (size_type n)
: memlink (),
  m_Capacity (0)
{
    resize (n);
}

/// links to \p p, \p n. Data can not be modified and will not be freed.
memblock::memblock (const void* p, size_type n)
: memlink (),
  m_Capacity (0)
{
    assign (p, n);
}

/// Links to what \p b is linked to.
memblock::memblock (const cmemlink& b)
: memlink (),
  m_Capacity (0)
{
    assign (b);
}

/// Links to what \p b is linked to.
memblock::memblock (const memlink& b)
: memlink (),
  m_Capacity (0)
{
    assign (b);
}

/// Links to what \p b is linked to.
memblock::memblock (const memblock& b)
: memlink (),
  m_Capacity (0)
{
    assign (b);
}

/// Frees internal data, if appropriate
/// Only if the block was allocated using resize, or linked to using Manage,
/// will it be freed. Also, Derived classes should call DestructBlock from
/// their destructor, because upstream virtual functions are unavailable at
/// this point and will not be called automatically.
///
memblock::~memblock (void)
{
    if (!is_linked())
	deallocate();
}

/// resizes the block to \p newSize bytes, reallocating if necessary.
void memblock::resize (size_type newSize, bool bExact)
{
    if (m_Capacity < newSize + minimumFreeCapacity())
	reserve (newSize, bExact);
    memlink::resize (newSize);
}

/// Frees internal data.
void memblock::deallocate (void) throw()
{
    if (m_Capacity) {
	assert (cdata() && "Internal error: space allocated, but the pointer is NULL");
	assert (data() && "Internal error: read-only block is marked as allocated space");
	free (data());
    }
    memblock::unlink();
}

/// Assumes control of the memory block \p p of size \p n.
/// The block assigned using this function will be freed in the destructor.
void memblock::manage (void* p, size_type n)
{
    assert (p || !n);
    assert (!data() || !m_Capacity);	// Can't link to an allocated block.
    link (p, n);
    m_Capacity = n;
}

/// Copies data from \p p, \p n.
void memblock::assign (const void* p, size_type n)
{
    assert ((p != (const void*) cdata() || size() == n) && "Self-assignment can not resize");
    resize (n);
    copy (p, n);
}

/// \brief Reallocates internal block to hold at least \p newSize bytes.
///
/// Additional memory may be allocated, but for efficiency it is a very
/// good idea to call reserve before doing byte-by-byte edit operations.
/// The block size as returned by size() is not altered. reserve will not
/// reduce allocated memory. If you think you are wasting space, call
/// deallocate and start over. To avoid wasting space, use the block for
/// only one purpose, and try to get that purpose to use similar amounts
/// of memory on each iteration.
///
void memblock::reserve (size_type newSize, bool bExact)
{
    if ((newSize += minimumFreeCapacity()) <= m_Capacity)
	return;
    void* oldBlock (is_linked() ? NULL : data());
    if (!bExact)
	newSize = Align (newSize, c_PageSize);
    pointer newBlock = (pointer) realloc (oldBlock, newSize);
    if (!newBlock)
	throw bad_alloc (newSize);
    if (!oldBlock && cdata())
	copy_n (cdata(), min (size() + 1, newSize), newBlock);
    link (newBlock, size());
    m_Capacity = newSize;
}

/// \warning Do not use or override this! It exists only for implementing #string
memblock::size_type memblock::minimumFreeCapacity (void) const
{
    return (0);
}

/// Swaps the contents with \p l
void memblock::swap (memblock& l)
{
    memlink::swap (l);
    ::ustl::swap (m_Capacity, l.m_Capacity);
}

/// Shifts the data in the linked block from \p start to \p start + \p n.
memblock::iterator memblock::insert (iterator start, size_type n)
{
    const uoff_t ip = start - begin();
    assert (ip <= size());
    resize (size() + n, false);
    memlink::insert (begin() + ip, n);
    return (begin() + ip);
}

/// Shifts the data in the linked block from \p start + \p n to \p start.
memblock::iterator memblock::erase (iterator start, size_type n)
{
    const uoff_t ep = start - begin();
    assert (ep + n <= size());
    memlink::erase (start, n);
    memlink::resize (size() - n);
    return (begin() + ep);
}

/// Unlinks object.
void memblock::unlink (void)
{
    memlink::unlink();
    m_Capacity = 0;
}

/// Reads the object from stream \p s
void memblock::read (istream& is)
{
    size_type n;
    is >> n;
    if (is.remaining() < n)
	throw stream_bounds_exception ("read", "ustl::memblock", is.pos(), n, is.remaining());
    resize (n);
    is.read (data(), writable_size());
    is.align();
}

/// Reads the entire file \p "filename".
void memblock::read_file (const char* filename)
{
    struct stat st;
    if (stat (filename, &st))
	throw file_exception ("stat", filename);
    resize (st.st_size);
    int fd = open (filename, O_RDONLY);
    if (fd < 0)
	throw file_exception ("open", filename);
    const size_type btr = writable_size();
    ssize_t br = ::read (fd, data(), btr);
    if (size_type(br) != btr) {
	close (fd);
	throw file_exception ("read", filename);
    }
    close (fd);
}

} // namespace ustl

<|endoftext|>