<commit_before>#ifndef BULL_CORE_PREREQUISITES_HPP
#define BULL_CORE_PREREQUISITES_HPP

#include <cstdint>

#define BULL_COMPILER_MSC      1
#define BULL_COMPILER_GCC      2
#define BULL_COMPILER_INTEL    3
#define BULL_COMPILER_CLANG    4
#define BULL_COMPILER_MINGW_32 5
#define BULL_COMPILER_MINGW_64 6

#if defined _MSC_VER
    #define BULL_COMPILER BULL_COMPILER_MSC
#elif defined __GNUC__
    #define BULL_COMPILER BULL_COMPILER_GCC
    #define BULL_COMPILER_VERSION __GNUC__
#elif defined __MINGW32__
    #define BULL_COMPILER BULL_COMPILER_MINGW_32
#elif defined __MINGW64__
	#define BULL_COMPILER BULL_COMPILER_MINGW_64
#else
	#error Unsupported compiler
#endif
#if defined _WIN32
    #define BULL_OS_WINDOWS

    #define BULL_WINDOWS_8     0x0602
    #define BULL_WINDOWS_7     0x0601
    #define BULL_WINDOWS_VISTA 0x0600
    #define BULL_WINDOWS_XP    0x0501 // Defined but not planed to be used

    #if defined BULL_BUILD_WINDOWS_8
        #define BULL_WINDOWS_VERSION BULL_WINDOWS_8
    #elif defined BULL_BUILD_WINDOWS_7
        #define BULL_WINDOWS_VERSION BULL_WINDOWS_7
    #elif defined BULL_BUILD_WINDOWS_VISTA
        #define BULL_WINDOWS_VERSION BULL_WINDOWS_VISTA
    #else
        #error Windows XP is not supported
    #endif
#elif defined __FreeBSD__
    #define BULL_OS_FREEBSD
    #define BULL_OS_UNIX
#elif defined __gnu_linux__
    #define BULL_OS_UNIX
    #define BULL_OS_GNU_LINUX
#elif defined __APPLE__ && __MACH__
    #define BULL_OS_OSX
    #define BULL_OS_UNIX
#else
    #error Your system is not supported by Bull
#endif

#if defined BULL_DYNAMIC
    #if defined BULL_OS_WINDOWS
        #define BULL_API_EXPORT __declspec(dllexport)
        #define BULL_API_IMPORT __declspec(dllimport)
    #else
        #if BULL_COMPLER == BULL_COMPILER_GCC
            #if BULL_COMPILER_VERSION >= 4
                #define BULL_API_EXPORT __attribute__ ((__visibility__ ("default")))
                #define BULL_API_IMPORT __attribute__ ((__visibility__ ("default")))
            #else
                #define BULL_API_EXPORT
                #define BULL_API_IMPORT
            #endif
        #endif
     #endif
#else
    #define BULL_API_EXPORT
    #define BULL_API_IMPORT
#endif

#ifndef BULL_ZERO_MEMORY
    #ifndef BULL_HAS_CSTRING
        #include <cstring>
        #define BULL_HAS_CSTRING
    #endif
    #define BULL_ZERO_MEMORY(Object) std::memset(&(Object), 0, sizeof(decltype(Object)))
#endif

#ifndef BULL_ZERO_MEMORY_PTR
    #ifndef BULL_HAS_CSTRING
        #include <cstring>
        #define BULL_HAS_CSTRING
    #endif
    #define BULL_ZERO_MEMORY_PTR(Pointer, Length) std::memset(Pointer, 0, Length)
#endif

#ifndef BULL_UNUSED
    #define BULL_UNUSED(Variable) (void)Variable
#endif

namespace Bull
{
    typedef int8_t   Int8;
    typedef int16_t  Int16;
    typedef int32_t  Int32;
    typedef int64_t  Int64;
    typedef uint8_t  Uint8;
    typedef uint16_t Uint16;
    typedef uint32_t Uint32;
    typedef uint64_t Uint64;
}

#endif // BULL_CORE_PREREQUISITES_HPP
<commit_msg>[Core/Prerequisites] Improve Mingw support<commit_after>#ifndef BULL_CORE_PREREQUISITES_HPP
#define BULL_CORE_PREREQUISITES_HPP

#include <cstdint>
#include <cstring>

#define BULL_COMPILER_MSC      1
#define BULL_COMPILER_GCC      2
#define BULL_COMPILER_MINGW_32 5
#define BULL_COMPILER_MINGW_64 6

#if defined _MSC_VER
    #define BULL_COMPILER BULL_COMPILER_MSC
#elif defined __GNUC__
    #if defined __MINGW32__ && defined __MINGW64__
        #define BULL_COMPILER BULL_COMPILER_MINGW_64
		#define BULL_COMPILER_VERSION_MAJOR  __MINGW64_VERSION_MAJOR
		#define BULL_COMPILER_VERSION_MINOR  __MINGW64_VERSION_MINOR
		#define BULL_COMPILER_VERSION_BUGFIX __MINGW64_VERSION_BUGFIX
		#define BULL_COMPILER_VERSION_STRING __MINGW64_VERSION_STR
    #elif defined __MINGW32__
        #define BULL_COMPILER BULL_COMPILER_MINGW_32
		#define BULL_COMPILER_VERSION_MAJOR  __MINGW32_VERSION_MAJOR
		#define BULL_COMPILER_VERSION_MINOR  __MINGW32_VERSION_MINOR
		#define BULL_COMPILER_VERSION_BUGFIX __MINGW32_VERSION_BUGFIX
		#define BULL_COMPILER_VERSION_STRING __MINGW32_VERSION_STR
    #else
        #define BULL_COMPILER BULL_COMPILER_GCC
    #endif
#else
	#warning Unsupported compiler
#endif

#if defined _WIN32
    #define BULL_OS_WINDOWS

    #define BULL_WINDOWS_8     0x0602
    #define BULL_WINDOWS_7     0x0601
    #define BULL_WINDOWS_VISTA 0x0600
    #define BULL_WINDOWS_XP    0x0501 // Defined but not planed to be used

    #if defined BULL_BUILD_WINDOWS_8
        #define BULL_WINDOWS_VERSION BULL_WINDOWS_8
    #elif defined BULL_BUILD_WINDOWS_7
        #define BULL_WINDOWS_VERSION BULL_WINDOWS_7
    #elif defined BULL_BUILD_WINDOWS_VISTA
        #define BULL_WINDOWS_VERSION BULL_WINDOWS_VISTA
    #else
        #error Windows XP is not supported
    #endif
#elif defined __FreeBSD__
    #define BULL_OS_FREEBSD
    #define BULL_OS_UNIX
#elif defined __gnu_linux__
    #define BULL_OS_UNIX
    #define BULL_OS_GNU_LINUX
#elif defined __APPLE__ && __MACH__
    #define BULL_OS_OSX
    #define BULL_OS_UNIX
#else
    #error Your system is not supported by Bull
#endif

#if defined BULL_DYNAMIC
    #if defined BULL_OS_WINDOWS
        #define BULL_API_EXPORT __declspec(dllexport)
        #define BULL_API_IMPORT __declspec(dllimport)
    #else
        #if BULL_COMPLER == BULL_COMPILER_GCC
            #if BULL_COMPILER_VERSION >= 4
                #define BULL_API_EXPORT __attribute__ ((__visibility__ ("default")))
                #define BULL_API_IMPORT __attribute__ ((__visibility__ ("default")))
            #else
                #define BULL_API_EXPORT
                #define BULL_API_IMPORT
            #endif
        #endif
     #endif
#else
    #define BULL_API_EXPORT
    #define BULL_API_IMPORT
#endif

#ifndef BULL_ZERO_MEMORY
    #define BULL_ZERO_MEMORY(Object) std::memset(&(Object), 0, sizeof(decltype(Object)))
#endif

#ifndef BULL_ZERO_MEMORY_PTR
    #define BULL_ZERO_MEMORY_PTR(Pointer, Length) std::memset(Pointer, 0, Length)
#endif

#ifndef BULL_UNUSED
    #define BULL_UNUSED(Variable) (void)Variable
#endif

namespace Bull
{
    typedef int8_t   Int8;
    typedef int16_t  Int16;
    typedef int32_t  Int32;
    typedef int64_t  Int64;
    typedef uint8_t  Uint8;
    typedef uint16_t Uint16;
    typedef uint32_t Uint32;
    typedef uint64_t Uint64;
}

#endif // BULL_CORE_PREREQUISITES_HPP
<|endoftext|>


<commit_before>/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Module: FGColumnVector3.cpp
Author: Originally by Tony Peden [formatted here by JSB]
Date started: 1998
Purpose: FGColumnVector3 class
Called by: Various

 ------------- Copyright (C) 1998 Tony Peden and Jon S. Berndt (jon@jsbsim.org) -

 This program 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 of the License, or (at your option) any later
 version.

 This program 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 program; if not, write to the Free Software Foundation, Inc., 59 Temple
 Place - Suite 330, Boston, MA  02111-1307, USA.

 Further information about the GNU Lesser General Public License can also be found on
 the world wide web at http://www.gnu.org.

FUNCTIONAL DESCRIPTION
--------------------------------------------------------------------------------

HISTORY
--------------------------------------------------------------------------------
??/??/??   TP   Created
03/16/2000 JSB  Added exception throwing

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

#include "FGColumnVector3.h"
#include <iostream>
#include <sstream>
#include <iomanip>
#include <cmath>

using namespace std;

namespace JSBSim {

static const char *IdSrc = "$Id: FGColumnVector3.cpp,v 1.14 2010/12/07 12:57:14 jberndt Exp $";
static const char *IdHdr = ID_COLUMNVECTOR3;

/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

FGColumnVector3::FGColumnVector3(void)
{
  data[0] = data[1] = data[2] = 0.0;
  // Debug(0);
}

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

string FGColumnVector3::Dump(const string& delimiter) const
{
  ostringstream buffer;
  buffer << std::setw(18) << std::setprecision(16) << data[0] << delimiter;
  buffer << std::setw(18) << std::setprecision(16) << data[1] << delimiter;
  buffer << std::setw(18) << std::setprecision(16) << data[2];
  return buffer.str();
}

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

ostream& operator<<(ostream& os, const FGColumnVector3& col)
{
  os << col(1) << " , " << col(2) << " , " << col(3);
  return os;
}

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

FGColumnVector3 FGColumnVector3::operator/(const double scalar) const
{
  if (scalar != 0.0)
    return operator*( 1.0/scalar );

  cerr << "Attempt to divide by zero in method \
    FGColumnVector3::operator/(const double scalar), \
    object " << data[0] << " , " << data[1] << " , " << data[2] << endl;
  return FGColumnVector3();
}

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

FGColumnVector3& FGColumnVector3::operator/=(const double scalar)
{
  if (scalar != 0.0)
    operator*=( 1.0/scalar );
  else
    cerr << "Attempt to divide by zero in method \
      FGColumnVector3::operator/=(const double scalar), \
      object " << data[0] << " , " << data[1] << " , " << data[2] << endl;

  return *this;
}

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

double FGColumnVector3::Magnitude(void) const
{
  return sqrt( data[0]*data[0] +  data[1]*data[1] +  data[2]*data[2] );
}

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

FGColumnVector3& FGColumnVector3::Normalize(void)
{
  double Mag = Magnitude();

  if (Mag != 0.0)
    operator*=( 1.0/Mag );

  return *this;
}

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

double FGColumnVector3::Magnitude(const int idx1, const int idx2) const {
  return sqrt( data[idx1-1]*data[idx1-1] +  data[idx2-1]*data[idx2-1] );
}

} // namespace JSBSim
<commit_msg>Remove superfluous field widths from Dump method. They were originally added for sprintf buffer handling.<commit_after>/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Module: FGColumnVector3.cpp
Author: Originally by Tony Peden [formatted here by JSB]
Date started: 1998
Purpose: FGColumnVector3 class
Called by: Various

 ------------- Copyright (C) 1998 Tony Peden and Jon S. Berndt (jon@jsbsim.org) -

 This program 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 of the License, or (at your option) any later
 version.

 This program 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 program; if not, write to the Free Software Foundation, Inc., 59 Temple
 Place - Suite 330, Boston, MA  02111-1307, USA.

 Further information about the GNU Lesser General Public License can also be found on
 the world wide web at http://www.gnu.org.

FUNCTIONAL DESCRIPTION
--------------------------------------------------------------------------------

HISTORY
--------------------------------------------------------------------------------
??/??/??   TP   Created
03/16/2000 JSB  Added exception throwing

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

#include "FGColumnVector3.h"
#include <iostream>
#include <sstream>
#include <iomanip>
#include <cmath>

using namespace std;

namespace JSBSim {

static const char *IdSrc = "$Id: FGColumnVector3.cpp,v 1.15 2012/02/07 00:27:51 jentron Exp $";
static const char *IdHdr = ID_COLUMNVECTOR3;

/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

FGColumnVector3::FGColumnVector3(void)
{
  data[0] = data[1] = data[2] = 0.0;
  // Debug(0);
}

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

string FGColumnVector3::Dump(const string& delimiter) const
{
  ostringstream buffer;
  buffer << std::setprecision(16) << data[0] << delimiter;
  buffer << std::setprecision(16) << data[1] << delimiter;
  buffer << std::setprecision(16) << data[2];
  return buffer.str();
}

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

ostream& operator<<(ostream& os, const FGColumnVector3& col)
{
  os << col(1) << " , " << col(2) << " , " << col(3);
  return os;
}

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

FGColumnVector3 FGColumnVector3::operator/(const double scalar) const
{
  if (scalar != 0.0)
    return operator*( 1.0/scalar );

  cerr << "Attempt to divide by zero in method \
    FGColumnVector3::operator/(const double scalar), \
    object " << data[0] << " , " << data[1] << " , " << data[2] << endl;
  return FGColumnVector3();
}

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

FGColumnVector3& FGColumnVector3::operator/=(const double scalar)
{
  if (scalar != 0.0)
    operator*=( 1.0/scalar );
  else
    cerr << "Attempt to divide by zero in method \
      FGColumnVector3::operator/=(const double scalar), \
      object " << data[0] << " , " << data[1] << " , " << data[2] << endl;

  return *this;
}

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

double FGColumnVector3::Magnitude(void) const
{
  return sqrt( data[0]*data[0] +  data[1]*data[1] +  data[2]*data[2] );
}

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

FGColumnVector3& FGColumnVector3::Normalize(void)
{
  double Mag = Magnitude();

  if (Mag != 0.0)
    operator*=( 1.0/Mag );

  return *this;
}

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

double FGColumnVector3::Magnitude(const int idx1, const int idx2) const {
  return sqrt( data[idx1-1]*data[idx1-1] +  data[idx2-1]*data[idx2-1] );
}

} // namespace JSBSim
<|endoftext|>


<commit_before>#ifndef V_SMC_CORE_SAMPLER_HPP
#define V_SMC_CORE_SAMPLER_HPP

#include <iostream>
#include <map>
#include <set>
#include <string>
#include <vSMC/internal/common.hpp>

namespace vSMC {

/// \brief SMC Sampler
template <typename T>
class Sampler
{
    public :

    /// The type of initialization functor
    typedef internal::function<std::size_t (Particle<T> &, void *)>
        initialize_type;

    /// The type of move functor
    typedef internal::function<std::size_t (std::size_t, Particle<T> &)>
        move_type;

    /// The type ESS history vector
    typedef std::vector<double> ess_type;

    /// The type resampling history vector
    typedef std::vector<bool> resampled_type;

    /// The type accept count history vector
    typedef std::vector<std::size_t> accept_type;

    /// \brief Construct a sampler with given number of particles
    ///
    /// \param N The number of particles
    /// \param init The functor used to initialize the particles
    /// \param move The functor used to move the particles and weights
    /// \param mcmc The functor used to perform MCMC move
    /// \param scheme The resampling scheme. See ResampleScheme
    /// \param threshold The threshold for performing resampling
    /// \param seed The seed to the parallel RNG system
    explicit Sampler (
            std::size_t N,
            const initialize_type &init = NULL,
            const move_type &move = NULL,
            const move_type &mcmc = NULL,
            ResampleScheme scheme = STRATIFIED,
            double threshold = 0.5,
            typename Particle<T>::seed_type seed = V_SMC_CRNG_SEED) :
        initialized_(false), init_(init), move_(move), mcmc_(mcmc),
        scheme_(scheme), threshold_(threshold * N),
        particle_(N, seed), iter_num_(0)
    {
        particle_.sampler(this);
    }

    /// \brief Size of the particle set
    ///
    /// \return The number of particles
    std::size_t size () const
    {
        return particle_.size();
    }

    /// \brief Size of records
    ///
    /// \return The number of iterations recorded (including the
    /// initialization step)
    std::size_t iter_size () const
    {
        return ess_.size();
    }

    /// \brief Get the current resampling scheme
    ///
    /// \return The current resampling scheme
    ResampleScheme resample_scheme () const
    {
        return scheme_;
    }

    /// \brief Set new resampling scheme
    ///
    /// \param scheme The new scheme for resampling
    void resample_scheme (ResampleScheme scheme)
    {
        scheme_ = scheme;
    }

    /// \brief Get the current threshold
    ///
    /// \return The current threshold for resmapling
    double resample_threshold () const
    {
        return threshold_;
    }

    /// \brief Set new resampling threshold
    ///
    /// \param threshold The new threshold for resampling
    void resample_threshold (double threshold)
    {
        threshold_ = threshold * particle_.size();
    }

    /// \brief ESS
    ///
    /// \return The ESS value of the latest iteration
    ess_type::value_type ess () const
    {
        return ess_.back();
    }

    /// \brief ESS history
    ///
    /// \return A const reference to the history of ESS
    const ess_type &ess_history () const
    {
        return ess_;
    }

    /// \brief Indicator of resampling
    ///
    /// \return A bool value, \b true if the latest iteration was resampled
    resampled_type::value_type resampled () const
    {
        return resampled_.back();
    }

    /// \brief Resampling history
    ///
    /// \return A const reference to the history of resampling
    const resampled_type &resampled_history () const
    {
        return resampled_;
    }

    /// \brief Accept count
    ///
    /// \return The accept count of the latest iteration
    accept_type::value_type accept () const
    {
        return accept_.back();
    }

    /// \brief Accept count history
    ///
    /// \return A const reference to the history of accept count
    const accept_type &accept_history () const
    {
        return accept_;
    }

    /// \brief Read and write access to the particle set
    ///
    /// \return A reference to the latest particle set
    ///
    /// \note When the system changes, this reference may be invalidated
    Particle<T> &particle ()
    {
        return particle_;
    }

    /// \brief Read only access to the particle set
    ///
    /// \return A const reference to the latest particle set.
    ///
    /// \note When the system changes, this reference may be invalidated
    const Particle<T> &particle () const
    {
        return particle_;
    }

    /// \brief Replace initialization functor
    ///
    /// \param init New Initialization functor
    void initialize (initialize_type &init)
    {
        init_ = init;
    }

    /// \brief Initialize the particle set
    ///
    /// \param param Additional parameters passed to the initialization
    /// functor
    void initialize (void *param = NULL)
    {
        ess_.clear();
        resampled_.clear();
        accept_.clear();
        path_.clear();

        for (typename std::map<std::string, Monitor<T> >::iterator
                imap = monitor_.begin(); imap != monitor_.end(); ++imap)
            imap->second.clear();

        iter_num_ = 0;
        accept_.push_back(init_(particle_, param));
        post_move();
        particle_.reset_zconst();

        initialized_ = true;
    }

    /// \brief Replace iteration functor
    ///
    /// \param move New Move functor
    /// \param mcmc New MCMC functor
    void iterate (const move_type &move, const move_type &mcmc = NULL)
    {
        move_ = move;
        mcmc_ = mcmc;
    }

    /// \brief Perform iteration
    void iterate ()
    {
        assert(initialized_);

        ++iter_num_;
        accept_.push_back(move_(iter_num_, particle_));
        if (bool(mcmc_))
            accept_.back() = mcmc_(iter_num_, particle_);
        post_move();
    }

    /// \brief Perform iteration
    ///
    /// \param n The number of iterations to be performed
    void iterate (std::size_t n)
    {
        for (std::size_t i = 0; i != n; ++i)
            iterate();
    }

    /// \brief Perform importance sampling integration
    ///
    /// \param integral The functor used to compute the integrands
    /// \param res The result, an array of length dim
    template<typename MonitorType>
    void integrate (const MonitorType &integral, double *res)
    {
        Monitor<T> m(integral.dim(), integral);
        m.eval(iter_num_, particle_);
        Eigen::Map<Eigen::VectorXd> r(res, m.dim());
        r = m.record().back();
    }

    /// \brief Perform importance sampling integration
    ///
    /// \param dim The dimension of the parameter
    /// \param integral The functor used to compute the integrands
    /// \param res The result, an array of length dim
    void integrate (unsigned dim,
            const typename Monitor<T>::integral_type &integral, double *res)
    {
        Monitor<T> m(dim, integral);
        m.eval(iter_num_, particle_);
        Eigen::Map<Eigen::VectorXd> r(res, m.dim());
        r = m.record().back();
    }

    /// \brief Add a monitor, similar to \b monitor in \b BUGS
    ///
    /// \param name The name of the monitor
    /// \param integral The functor used to compute the integrands
    template<typename MonitorType>
    void monitor (const std::string &name, const MonitorType &integral)
    {
        monitor_.insert(std::make_pair(
                    name, Monitor<T>(integral.dim(), integral)));
        monitor_name_.insert(name);
    }

    /// \brief Add a monitor, similar to \b monitor in \b BUGS
    ///
    /// \param name The name of the monitor
    /// \param dim The dimension of the monitor
    /// \param integral The functor used to compute the integrands
    void monitor (const std::string &name, unsigned dim,
            const typename Monitor<T>::integral_type &integral)
    {
        monitor_.insert(std::make_pair(name, Monitor<T>(dim, integral)));
        monitor_name_.insert(name);
    }

    /// \brief Read only access to a named monitor through iterator
    ///
    /// \param name The name of the monitor
    ///
    /// \return An const_iterator point to the monitor for the given name
    ///
    /// \note When the system changes, this reference may be invalidated
    typename std::map<std::string, Monitor<T> >::const_iterator
        monitor (const std::string &name) const
    {
        return monitor_.find(name);
    }

    /// \brief Read only access to all monitors
    ///
    /// \return A const reference to monitors
    ///
    /// \note When the system changes, this reference may be invalidated
    const std::map<std::string, Monitor<T> > &monitor () const
    {
        return monitor_;
    }

    /// \brief Erase a named monitor
    ///
    /// \param name The name of the monitor
    void clear_monitor (const std::string &name)
    {
        monitor_.erase(name);
        monitor_name_.erase(name);
    }

    /// \brief Erase all monitors
    void clear_monitor ()
    {
        monitor_.clear();
        monitor_name_.clear();
    }

    /// \brief Read only access to the Path sampling monitor
    ///
    /// \return A const reference to the Path sampling monitor
    ///
    /// \note When the system changes, this reference may be invalidated
    const Path<T> &path () const
    {
        return path_;
    }

    /// \brief Set the path sampling integral
    ///
    /// \param integral The functor used to compute the integrands
    ///
    /// \note Set integral = NULL will stop path sampling recording
    void path_sampling (const typename Path<T>::integral_type &integral)
    {
        path_.integral(integral);
    }

    /// \brief Path sampling estimate of normalizing constant
    ///
    /// \return The log ratio of normalizing constants
    double path_sampling () const
    {
        return path_.zconst();
    }

    /// \brief SMC estimate of normalizing constant
    ///
    /// \return The log of SMC normalizng constant estimate
    double zconst () const
    {
        return particle_.zconst();
    }

    /// \brief Print the history of the sampler
    ///
    /// \param os The ostream to which the contents are printed
    /// \param print_header Print header if \b true
    void print (std::ostream &os = std::cout, bool print_header = true) const
    {
        print(os, print_header, !path_.index().empty(), monitor_name_);
    }

    /// \brief Print the history of the sampler
    ///
    /// \param os The ostream to which the contents are printed
    /// \param print_path Print path sampling history if \b true
    /// \param print_monitor A set of monitor names to be printed
    /// \param print_header Print header if \b true
    void print (std::ostream &os, bool print_header, bool print_path,
            const std::set<std::string> &print_monitor) const
    {
        if (print_header) {
            os << "iter\tESS\tresample\taccept\t";
            if (print_path)
                os << "path.integrand\tpath.width\tpath.grid\t";
        }

        typename Path<T>::index_type::const_iterator iter_path_index
            = path_.index().begin();
        typename Path<T>::integrand_type::const_iterator iter_path_integrand
            = path_.integrand().begin();
        typename Path<T>::width_type::const_iterator iter_path_width
            = path_.width().begin();
        typename Path<T>::grid_type::const_iterator iter_path_grid
            = path_.grid().begin();

        std::vector<bool> monitor_index_empty;
        std::vector<unsigned> monitor_dim;
        std::vector<typename Monitor<T>::index_type::const_iterator>
            iter_monitor_index;
        std::vector<typename Monitor<T>::record_type::const_iterator>
            iter_monitor_record;
        for (typename std::map<std::string, Monitor<T> >::const_iterator
                imap = monitor_.begin(); imap != monitor_.end(); ++imap) {
            if (print_monitor.count(imap->first)) {
                monitor_index_empty.push_back(imap->second.index().empty());
                monitor_dim.push_back(imap->second.dim());
                iter_monitor_index.push_back(imap->second.index().begin());
                iter_monitor_record.push_back(imap->second.record().begin());
                if (print_header) {
                    if (monitor_dim.back() > 1) {
                        for (unsigned d = 0; d != monitor_dim.back(); ++d)
                            os << imap->first << d + 1 << '\t';
                    } else {
                        os << imap->first << '\t';
                    }
                }
            }
        }

        if (print_header)
            os << '\n';

        for (std::size_t i = 0; i != iter_size(); ++i) {
            os
                << i << '\t' << ess_[i] / size()
                << '\t' << resampled_[i]
                << '\t' << static_cast<double>(accept_[i]) / size();

            if (print_path) {
                if (!path_.index().empty() && *iter_path_index == i) {
                    os
                        << '\t' << *iter_path_integrand++
                        << '\t' << *iter_path_width++
                        << '\t' << *iter_path_grid++;
                    ++iter_path_index;
                } else {
                    os << '\t' << '.' << '\t' << '.' << '\t' << '.';
                }
            }

            for (std::size_t m = 0; m != monitor_index_empty.size(); ++m) {
                if (!monitor_index_empty[m] && *iter_monitor_index[m] == i) {
                    for (unsigned d = 0; d != monitor_dim[m]; ++d)
                        os << '\t' << (*iter_monitor_record[m])[d];
                    ++iter_monitor_index[m];
                    ++iter_monitor_record[m];
                } else {
                    for (unsigned d = 0; d != monitor_dim[m]; ++d)
                        os << '\t' << '.';
                }
            }

            if (i != iter_size() - 1)
                os << '\n';
        }
    }

    private :

    /// Initialization indicator
    bool initialized_;

    /// Initialization and movement
    initialize_type init_;
    move_type move_;
    move_type mcmc_;

    /// Resampling
    ResampleScheme scheme_;
    double threshold_;

    /// Particle sets
    Particle<T> particle_;
    std::size_t iter_num_;
    ess_type ess_;
    resampled_type resampled_;
    accept_type accept_;

    /// Monte Carlo estimation by integration
    std::map<std::string, Monitor<T> > monitor_;
    std::set<std::string> monitor_name_;

    /// Path sampling
    Path<T> path_;

    void post_move ()
    {
        ess_.push_back(particle_.ess());
        particle_.resampled(ess_.back() < threshold_);
        resampled_.push_back(particle_.resampled());
        if (particle_.resampled()) {
            particle_.resample(scheme_);
            ess_.back() = particle_.size();
        }

        if (!path_.empty())
            path_.eval(iter_num_, particle_);

        for (typename std::map<std::string, Monitor<T> >::iterator
                imap = monitor_.begin(); imap != monitor_.end(); ++imap) {
            if (!imap->second.empty())
                imap->second.eval(iter_num_, particle_);
        }
    }
}; // class Sampler

} // namespace vSMC

namespace std {

/// \brief Print the sampler
///
/// \param os The ostream to which the contents are printed
/// \param sampler The sampler to be printed
///
/// \note This is the same as <tt>sampler.print(os)</tt>
template<typename T>
std::ostream & operator<< (std::ostream &os, const vSMC::Sampler<T> &sampler)
{
    sampler.print(os);

    return os;
}

} // namespace std

#endif // V_SMC_CORE_SAMPLER_HPP
<commit_msg>use Particle<T>::size_type for Sampler constructor;<commit_after>#ifndef V_SMC_CORE_SAMPLER_HPP
#define V_SMC_CORE_SAMPLER_HPP

#include <iostream>
#include <map>
#include <set>
#include <string>
#include <vSMC/internal/common.hpp>

namespace vSMC {

/// \brief SMC Sampler
template <typename T>
class Sampler
{
    public :

    /// The type of initialization functor
    typedef internal::function<std::size_t (Particle<T> &, void *)>
        initialize_type;

    /// The type of move functor
    typedef internal::function<std::size_t (std::size_t, Particle<T> &)>
        move_type;

    /// The type ESS history vector
    typedef std::vector<double> ess_type;

    /// The type resampling history vector
    typedef std::vector<bool> resampled_type;

    /// The type accept count history vector
    typedef std::vector<std::size_t> accept_type;

    /// \brief Construct a sampler with given number of particles
    ///
    /// \param N The number of particles
    /// \param init The functor used to initialize the particles
    /// \param move The functor used to move the particles and weights
    /// \param mcmc The functor used to perform MCMC move
    /// \param scheme The resampling scheme. See ResampleScheme
    /// \param threshold The threshold for performing resampling
    /// \param seed The seed to the parallel RNG system
    explicit Sampler (
            typename Particle<T>::size_type N,
            const initialize_type &init = NULL,
            const move_type &move = NULL,
            const move_type &mcmc = NULL,
            ResampleScheme scheme = STRATIFIED,
            double threshold = 0.5,
            typename Particle<T>::seed_type seed = V_SMC_CRNG_SEED) :
        initialized_(false), init_(init), move_(move), mcmc_(mcmc),
        scheme_(scheme), threshold_(threshold * N),
        particle_(N, seed), iter_num_(0)
    {
        particle_.sampler(this);
    }

    /// \brief Size of the particle set
    ///
    /// \return The number of particles
    typename Particle<T>::size_type size () const
    {
        return particle_.size();
    }

    /// \brief Size of records
    ///
    /// \return The number of iterations recorded (including the
    /// initialization step)
    std::size_t iter_size () const
    {
        return ess_.size();
    }

    /// \brief Get the current resampling scheme
    ///
    /// \return The current resampling scheme
    ResampleScheme resample_scheme () const
    {
        return scheme_;
    }

    /// \brief Set new resampling scheme
    ///
    /// \param scheme The new scheme for resampling
    void resample_scheme (ResampleScheme scheme)
    {
        scheme_ = scheme;
    }

    /// \brief Get the current threshold
    ///
    /// \return The current threshold for resmapling
    double resample_threshold () const
    {
        return threshold_;
    }

    /// \brief Set new resampling threshold
    ///
    /// \param threshold The new threshold for resampling
    void resample_threshold (double threshold)
    {
        threshold_ = threshold * particle_.size();
    }

    /// \brief ESS
    ///
    /// \return The ESS value of the latest iteration
    ess_type::value_type ess () const
    {
        return ess_.back();
    }

    /// \brief ESS history
    ///
    /// \return A const reference to the history of ESS
    const ess_type &ess_history () const
    {
        return ess_;
    }

    /// \brief Indicator of resampling
    ///
    /// \return A bool value, \b true if the latest iteration was resampled
    resampled_type::value_type resampled () const
    {
        return resampled_.back();
    }

    /// \brief Resampling history
    ///
    /// \return A const reference to the history of resampling
    const resampled_type &resampled_history () const
    {
        return resampled_;
    }

    /// \brief Accept count
    ///
    /// \return The accept count of the latest iteration
    accept_type::value_type accept () const
    {
        return accept_.back();
    }

    /// \brief Accept count history
    ///
    /// \return A const reference to the history of accept count
    const accept_type &accept_history () const
    {
        return accept_;
    }

    /// \brief Read and write access to the particle set
    ///
    /// \return A reference to the latest particle set
    ///
    /// \note When the system changes, this reference may be invalidated
    Particle<T> &particle ()
    {
        return particle_;
    }

    /// \brief Read only access to the particle set
    ///
    /// \return A const reference to the latest particle set.
    ///
    /// \note When the system changes, this reference may be invalidated
    const Particle<T> &particle () const
    {
        return particle_;
    }

    /// \brief Replace initialization functor
    ///
    /// \param init New Initialization functor
    void initialize (initialize_type &init)
    {
        init_ = init;
    }

    /// \brief Initialize the particle set
    ///
    /// \param param Additional parameters passed to the initialization
    /// functor
    void initialize (void *param = NULL)
    {
        ess_.clear();
        resampled_.clear();
        accept_.clear();
        path_.clear();

        for (typename std::map<std::string, Monitor<T> >::iterator
                imap = monitor_.begin(); imap != monitor_.end(); ++imap)
            imap->second.clear();

        iter_num_ = 0;
        accept_.push_back(init_(particle_, param));
        post_move();
        particle_.reset_zconst();

        initialized_ = true;
    }

    /// \brief Replace iteration functor
    ///
    /// \param move New Move functor
    /// \param mcmc New MCMC functor
    void iterate (const move_type &move, const move_type &mcmc = NULL)
    {
        move_ = move;
        mcmc_ = mcmc;
    }

    /// \brief Perform iteration
    void iterate ()
    {
        assert(initialized_);

        ++iter_num_;
        accept_.push_back(move_(iter_num_, particle_));
        if (bool(mcmc_))
            accept_.back() = mcmc_(iter_num_, particle_);
        post_move();
    }

    /// \brief Perform iteration
    ///
    /// \param n The number of iterations to be performed
    void iterate (std::size_t n)
    {
        for (std::size_t i = 0; i != n; ++i)
            iterate();
    }

    /// \brief Perform importance sampling integration
    ///
    /// \param integral The functor used to compute the integrands
    /// \param res The result, an array of length dim
    template<typename MonitorType>
    void integrate (const MonitorType &integral, double *res)
    {
        Monitor<T> m(integral.dim(), integral);
        m.eval(iter_num_, particle_);
        Eigen::Map<Eigen::VectorXd> r(res, m.dim());
        r = m.record().back();
    }

    /// \brief Perform importance sampling integration
    ///
    /// \param dim The dimension of the parameter
    /// \param integral The functor used to compute the integrands
    /// \param res The result, an array of length dim
    void integrate (unsigned dim,
            const typename Monitor<T>::integral_type &integral, double *res)
    {
        Monitor<T> m(dim, integral);
        m.eval(iter_num_, particle_);
        Eigen::Map<Eigen::VectorXd> r(res, m.dim());
        r = m.record().back();
    }

    /// \brief Add a monitor, similar to \b monitor in \b BUGS
    ///
    /// \param name The name of the monitor
    /// \param integral The functor used to compute the integrands
    template<typename MonitorType>
    void monitor (const std::string &name, const MonitorType &integral)
    {
        monitor_.insert(std::make_pair(
                    name, Monitor<T>(integral.dim(), integral)));
        monitor_name_.insert(name);
    }

    /// \brief Add a monitor, similar to \b monitor in \b BUGS
    ///
    /// \param name The name of the monitor
    /// \param dim The dimension of the monitor
    /// \param integral The functor used to compute the integrands
    void monitor (const std::string &name, unsigned dim,
            const typename Monitor<T>::integral_type &integral)
    {
        monitor_.insert(std::make_pair(name, Monitor<T>(dim, integral)));
        monitor_name_.insert(name);
    }

    /// \brief Read only access to a named monitor through iterator
    ///
    /// \param name The name of the monitor
    ///
    /// \return An const_iterator point to the monitor for the given name
    ///
    /// \note When the system changes, this reference may be invalidated
    typename std::map<std::string, Monitor<T> >::const_iterator
        monitor (const std::string &name) const
    {
        return monitor_.find(name);
    }

    /// \brief Read only access to all monitors
    ///
    /// \return A const reference to monitors
    ///
    /// \note When the system changes, this reference may be invalidated
    const std::map<std::string, Monitor<T> > &monitor () const
    {
        return monitor_;
    }

    /// \brief Erase a named monitor
    ///
    /// \param name The name of the monitor
    void clear_monitor (const std::string &name)
    {
        monitor_.erase(name);
        monitor_name_.erase(name);
    }

    /// \brief Erase all monitors
    void clear_monitor ()
    {
        monitor_.clear();
        monitor_name_.clear();
    }

    /// \brief Read only access to the Path sampling monitor
    ///
    /// \return A const reference to the Path sampling monitor
    ///
    /// \note When the system changes, this reference may be invalidated
    const Path<T> &path () const
    {
        return path_;
    }

    /// \brief Set the path sampling integral
    ///
    /// \param integral The functor used to compute the integrands
    ///
    /// \note Set integral = NULL will stop path sampling recording
    void path_sampling (const typename Path<T>::integral_type &integral)
    {
        path_.integral(integral);
    }

    /// \brief Path sampling estimate of normalizing constant
    ///
    /// \return The log ratio of normalizing constants
    double path_sampling () const
    {
        return path_.zconst();
    }

    /// \brief SMC estimate of normalizing constant
    ///
    /// \return The log of SMC normalizng constant estimate
    double zconst () const
    {
        return particle_.zconst();
    }

    /// \brief Print the history of the sampler
    ///
    /// \param os The ostream to which the contents are printed
    /// \param print_header Print header if \b true
    void print (std::ostream &os = std::cout, bool print_header = true) const
    {
        print(os, print_header, !path_.index().empty(), monitor_name_);
    }

    /// \brief Print the history of the sampler
    ///
    /// \param os The ostream to which the contents are printed
    /// \param print_path Print path sampling history if \b true
    /// \param print_monitor A set of monitor names to be printed
    /// \param print_header Print header if \b true
    void print (std::ostream &os, bool print_header, bool print_path,
            const std::set<std::string> &print_monitor) const
    {
        if (print_header) {
            os << "iter\tESS\tresample\taccept\t";
            if (print_path)
                os << "path.integrand\tpath.width\tpath.grid\t";
        }

        typename Path<T>::index_type::const_iterator iter_path_index
            = path_.index().begin();
        typename Path<T>::integrand_type::const_iterator iter_path_integrand
            = path_.integrand().begin();
        typename Path<T>::width_type::const_iterator iter_path_width
            = path_.width().begin();
        typename Path<T>::grid_type::const_iterator iter_path_grid
            = path_.grid().begin();

        std::vector<bool> monitor_index_empty;
        std::vector<unsigned> monitor_dim;
        std::vector<typename Monitor<T>::index_type::const_iterator>
            iter_monitor_index;
        std::vector<typename Monitor<T>::record_type::const_iterator>
            iter_monitor_record;
        for (typename std::map<std::string, Monitor<T> >::const_iterator
                imap = monitor_.begin(); imap != monitor_.end(); ++imap) {
            if (print_monitor.count(imap->first)) {
                monitor_index_empty.push_back(imap->second.index().empty());
                monitor_dim.push_back(imap->second.dim());
                iter_monitor_index.push_back(imap->second.index().begin());
                iter_monitor_record.push_back(imap->second.record().begin());
                if (print_header) {
                    if (monitor_dim.back() > 1) {
                        for (unsigned d = 0; d != monitor_dim.back(); ++d)
                            os << imap->first << d + 1 << '\t';
                    } else {
                        os << imap->first << '\t';
                    }
                }
            }
        }

        if (print_header)
            os << '\n';

        for (std::size_t i = 0; i != iter_size(); ++i) {
            os
                << i << '\t' << ess_[i] / size()
                << '\t' << resampled_[i]
                << '\t' << static_cast<double>(accept_[i]) / size();

            if (print_path) {
                if (!path_.index().empty() && *iter_path_index == i) {
                    os
                        << '\t' << *iter_path_integrand++
                        << '\t' << *iter_path_width++
                        << '\t' << *iter_path_grid++;
                    ++iter_path_index;
                } else {
                    os << '\t' << '.' << '\t' << '.' << '\t' << '.';
                }
            }

            for (std::size_t m = 0; m != monitor_index_empty.size(); ++m) {
                if (!monitor_index_empty[m] && *iter_monitor_index[m] == i) {
                    for (unsigned d = 0; d != monitor_dim[m]; ++d)
                        os << '\t' << (*iter_monitor_record[m])[d];
                    ++iter_monitor_index[m];
                    ++iter_monitor_record[m];
                } else {
                    for (unsigned d = 0; d != monitor_dim[m]; ++d)
                        os << '\t' << '.';
                }
            }

            if (i != iter_size() - 1)
                os << '\n';
        }
    }

    private :

    /// Initialization indicator
    bool initialized_;

    /// Initialization and movement
    initialize_type init_;
    move_type move_;
    move_type mcmc_;

    /// Resampling
    ResampleScheme scheme_;
    double threshold_;

    /// Particle sets
    Particle<T> particle_;
    std::size_t iter_num_;
    ess_type ess_;
    resampled_type resampled_;
    accept_type accept_;

    /// Monte Carlo estimation by integration
    std::map<std::string, Monitor<T> > monitor_;
    std::set<std::string> monitor_name_;

    /// Path sampling
    Path<T> path_;

    void post_move ()
    {
        ess_.push_back(particle_.ess());
        particle_.resampled(ess_.back() < threshold_);
        resampled_.push_back(particle_.resampled());
        if (particle_.resampled()) {
            particle_.resample(scheme_);
            ess_.back() = particle_.size();
        }

        if (!path_.empty())
            path_.eval(iter_num_, particle_);

        for (typename std::map<std::string, Monitor<T> >::iterator
                imap = monitor_.begin(); imap != monitor_.end(); ++imap) {
            if (!imap->second.empty())
                imap->second.eval(iter_num_, particle_);
        }
    }
}; // class Sampler

} // namespace vSMC

namespace std {

/// \brief Print the sampler
///
/// \param os The ostream to which the contents are printed
/// \param sampler The sampler to be printed
///
/// \note This is the same as <tt>sampler.print(os)</tt>
template<typename T>
std::ostream & operator<< (std::ostream &os, const vSMC::Sampler<T> &sampler)
{
    sampler.print(os);

    return os;
}

} // namespace std

#endif // V_SMC_CORE_SAMPLER_HPP
<|endoftext|>


<commit_before>/*
 *
 * MIT License
 *
 * Copyright (c) 2016-2018 The Cats Project
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 */

#ifndef CATS_CORECAT_DATA_ARRAY_HPP
#define CATS_CORECAT_DATA_ARRAY_HPP

#include <cstddef>

#include <iterator>
#include <memory>
#include <utility>

#include "Allocator/DefaultAllocator.hpp"
#include "../Util/Iterator.hpp"

namespace Cats {
namespace Corecat {
inline namespace Data {

template <typename T>
class ArrayView;

template <typename T, typename A = DefaultAllocator>
class Array {

public:

    using Type = T;
    using AllocatorType = A;

    using Iterator = Type*;
    using ConstIterator = const Type*;
    using ReverseIterator = Corecat::ReverseIterator<Iterator>;
    using ConstReverseIterator = Corecat::ReverseIterator<ConstIterator>;

    using ArrayViewType = ArrayView<T>;
    using ConstArrayViewType = ArrayView<const T>;

private:

    A allocator;
    Type* data = nullptr;
    std::size_t size = 0;
    std::size_t capacity = 0;

public:

    Array() = default;
    Array(std::size_t size_) { resize(size_); }
    Array(const Array& src) {

        data = static_cast<T*>(allocator.allocate(src.size * sizeof(T)));
        size = src.size;
        capacity = size;
        std::size_t i = 0;
        try {

            for(; i < size; ++i) new(data + i) T(src.data[i]);

        } catch(...) {

            for(--i; i != std::size_t(-1); --i) data[i].~T();
            allocator.deallocate(data, capacity * sizeof(T));
            std::rethrow_exception(std::current_exception());

        }

    }
    Array(Array&& src) noexcept { swap(src); }
    ~Array() {

        clear();
        if(data) allocator.deallocate(data, capacity * sizeof(T));

    }

    Array& operator =(const Array& src) = delete;
    Array& operator =(Array&& src) noexcept { swap(*this, src); return *this; }

    operator ConstArrayViewType() const noexcept { return getView(); }
    operator ArrayViewType() noexcept { return getView(); }

    const Type& operator [](std::size_t index) const noexcept { return data[index]; }
    Type& operator [](std::size_t index) noexcept { return data[index]; }

    const Type* getData() const noexcept { return data; }
    Type* getData() noexcept { return data; }
    std::size_t getSize() const noexcept { return size; }
    std::size_t getCapacity() const noexcept { return capacity; }

    ConstArrayViewType getView() const noexcept { return {data, size}; }
    ArrayViewType getView() noexcept { return {data, size}; }

    bool isEmpty() const noexcept { return !size; }

    void clear() noexcept { resize(0); }

    void reserve(std::size_t capacity_) {

        if(capacity >= capacity_) return;
        T* data_ = static_cast<T*>(allocator.allocate(capacity_ * sizeof(T)));
        std::size_t i = 0;
        try {

            for(; i < size; ++i) new(data_ + i) T(data[i]);

        } catch(...) {

            for(--i; i != std::size_t(-1); --i) data_[i].~T();
            allocator.deallocate(data_, capacity_ * sizeof(T));
            std::rethrow_exception(std::current_exception());

        }
        if(data) {

            for(std::size_t i = size - 1; i != std::size_t(-1); --i) data[i].~T();
            allocator.deallocate(data, capacity * sizeof(T));

        }
        data = data_;
        capacity = capacity_;

    }

    void resize(std::size_t size_) {

        if(size_ < size) {

            for(std::size_t i = size_ - 1; i != size_ - 1; --i)
                data[i].~T();

        } else if(size_ > size) {

            if(size_ <= capacity) {

                std::size_t i = size;
                try {

                    for(; i < size_; ++i) new(data + i) T();

                } catch(...) {

                    for(--i; i != size - 1; --i) data[i].~T();
                    std::rethrow_exception(std::current_exception());

                }

            } else {

                T* data_ = static_cast<T*>(allocator.allocate(size_ * sizeof(T)));
                std::size_t i = 0;
                try {

                    for(; i < size; ++i) new(data_ + i) T(data[i]);
                    for(; i < size_; ++i) new(data_ + i) T();

                } catch(...) {

                    for(--i; i != std::size_t(-1); --i) data_[i].~T();
                    allocator.deallocate(data_, size_ * sizeof(T));
                    std::rethrow_exception(std::current_exception());

                }
                if(data) {

                    for(std::size_t i = size - 1; i != std::size_t(-1); --i) data[i].~T();
                    allocator.deallocate(data, capacity * sizeof(T));

                }
                data = data_;
                capacity = size_;

            }

        }
        size = size_;

    }

    template <typename... Arg>
    void append(Arg&&... arg) {

        if(size < capacity) {

            new(data + size) T(std::forward<Arg>(arg)...);

        } else {

            std::size_t newSize = size + 1;
            T* newData = static_cast<T*>(allocator.allocate(newSize * sizeof(T)));
            std::size_t i = 0;
            try {

                for(; i < size; ++i) new(newData + i) T(data[i]);
                new(newData + size) T(std::forward<Arg>(arg)...);

            } catch(...) {

                for(--i; i != std::size_t(-1); --i) newData[i].~T();
                allocator.deallocate(newData, newSize * sizeof(T));
                std::rethrow_exception(std::current_exception());

            }
            if(data) {

                for(std::size_t i = size - 1; i != std::size_t(-1); --i) data[i].~T();
                allocator.deallocate(data, capacity * sizeof(T));

            }
            data = newData;
            capacity = newSize;

        }
        ++size;

    }

    void swap(Array& src) noexcept {

        std::swap(allocator, src.allocator);
        std::swap(data, src.data);
        std::swap(size, src.size);
        std::swap(capacity, src.capacity);

    }

    Iterator begin() const noexcept { return data; }
    Iterator end() const noexcept { return data + size; }

    ConstIterator cbegin() const noexcept { return begin(); }
    ConstIterator cend() const noexcept { return end(); }

    ReverseIterator rbegin() const noexcept { return ReverseIterator(end()); }
    ReverseIterator rend() const noexcept { return ReverseIterator(begin()); }

    ConstReverseIterator crbegin() const noexcept { return ConstReverseIterator(cend()); }
    ConstReverseIterator crend() const noexcept { return ConstReverseIterator(cbegin()); }

};

template <typename T>
class ArrayView {

public:

    using Type = T;

    using Iterator = Type*;
    using ConstIterator = const Type*;
    using ReverseIterator = Corecat::ReverseIterator<Iterator>;
    using ConstReverseIterator = Corecat::ReverseIterator<ConstIterator>;

private:

    Type* data = nullptr;
    std::size_t size = 0;

public:

    ArrayView() = default;
    ArrayView(std::nullptr_t) noexcept {}
    ArrayView(Type* data_, std::size_t size_) noexcept : data(data_), size(size_) {}
    template <std::size_t S>
    ArrayView(Type (&array)[S]) noexcept : data(array), size(S) {}
    ArrayView(const ArrayView& src) = default;

    ArrayView& operator =(const ArrayView& src) = default;

    operator ArrayView<const Type>() noexcept { return {data, size}; }

    Type& operator [](std::size_t index) const noexcept { return data[index]; }

    Type* getData() const noexcept { return data; }
    std::size_t getSize() const noexcept { return size; }

    bool isEmpty() const noexcept { return !size; }

    Iterator begin() const noexcept { return data; }
    Iterator end() const noexcept { return data + size; }

    ConstIterator cbegin() const noexcept { return begin(); }
    ConstIterator cend() const noexcept { return end(); }

    ReverseIterator rbegin() const noexcept { return ReverseIterator(end()); }
    ReverseIterator rend() const noexcept { return ReverseIterator(begin()); }

    ConstReverseIterator crbegin() const noexcept { return ConstReverseIterator(cend()); }
    ConstReverseIterator crend() const noexcept { return ConstReverseIterator(cbegin()); }

};

}
}
}

#endif
<commit_msg>Update Array<commit_after>/*
 *
 * MIT License
 *
 * Copyright (c) 2016-2018 The Cats Project
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 */

#ifndef CATS_CORECAT_DATA_ARRAY_HPP
#define CATS_CORECAT_DATA_ARRAY_HPP

#include <cstddef>

#include <iterator>
#include <memory>
#include <utility>

#include "Allocator/DefaultAllocator.hpp"
#include "../Util/Iterator.hpp"

namespace Cats {
namespace Corecat {
inline namespace Data {

template <typename T>
class ArrayView;

template <typename T, typename A = DefaultAllocator>
class Array {

public:

    using Type = T;
    using AllocatorType = A;

    using Iterator = Type*;
    using ConstIterator = const Type*;
    using ReverseIterator = Corecat::ReverseIterator<Iterator>;
    using ConstReverseIterator = Corecat::ReverseIterator<ConstIterator>;

    using ArrayViewType = ArrayView<T>;
    using ConstArrayViewType = ArrayView<const T>;

private:

    A allocator;
    Type* data = nullptr;
    std::size_t size = 0;
    std::size_t capacity = 0;

public:

    Array() = default;
    Array(std::size_t size_) { resize(size_); }
    Array(const Array& src) {

        data = static_cast<T*>(allocator.allocate(src.size * sizeof(T)));
        size = src.size;
        capacity = size;
        std::size_t i = 0;
        try {

            for(; i < size; ++i) new(data + i) T(src.data[i]);

        } catch(...) {

            for(std::size_t j = 0; j < i; ++j) data[j].~T();
            allocator.deallocate(data, capacity * sizeof(T));
            throw;

        }

    }
    Array(Array&& src) noexcept { swap(src); }
    ~Array() {

        clear();
        if(data) allocator.deallocate(data, capacity * sizeof(T));

    }

    Array& operator =(const Array& src) {

        if(src.size > capacity) {

            T* newData = static_cast<T*>(allocator.allocate(src.size * sizeof(T)));
            std::size_t i = 0;
            try {

                for(; i < src.size; ++i) new(newData + i) T(src.data[i]);

            } catch(...) {

                for(std::size_t j = 0; j < i; ++j) newData[j].~T();
                allocator.deallocate(newData, src.size * sizeof(T));
                throw;

            }
            if(data) {

                for(std::size_t i = 0; i < size; ++i) data[i].~T();
                allocator.deallocate(data, capacity * sizeof(T));

            }
            data = newData;
            size = src.size;
            capacity = size;

        } else if(src.size > size) {

            std::size_t i = 0;
            for(; i < size; ++i) data[i] = src.data[i];
            try {

                for(; i < src.size; ++i) new(data + i) T(src.data[i]);

            } catch(...) {

                for(std::size_t j = size; j < i; ++j) data[j].~T();
                throw;

            }
            size = src.size;

        } else {

            std::size_t i = 0;
            for(; i < src.size; ++i) data[i] = src.data[i];
            for(; i < size; ++i) data[i].~T();
            size = src.size;

        }
        return *this;

    }
    Array& operator =(Array&& src) noexcept { swap(src); return *this; }

    operator ConstArrayViewType() const noexcept { return getView(); }
    operator ArrayViewType() noexcept { return getView(); }

    const Type& operator [](std::size_t index) const noexcept { return data[index]; }
    Type& operator [](std::size_t index) noexcept { return data[index]; }

    const Type* getData() const noexcept { return data; }
    Type* getData() noexcept { return data; }
    std::size_t getSize() const noexcept { return size; }
    std::size_t getCapacity() const noexcept { return capacity; }

    ConstArrayViewType getView() const noexcept { return {data, size}; }
    ArrayViewType getView() noexcept { return {data, size}; }

    bool isEmpty() const noexcept { return !size; }

    void clear() noexcept { resize(0); }

    void reserve(std::size_t capacity_) {

        if(capacity >= capacity_) return;
        T* data_ = static_cast<T*>(allocator.allocate(capacity_ * sizeof(T)));
        std::size_t i = 0;
        try {

            for(; i < size; ++i) new(data_ + i) T(data[i]);

        } catch(...) {

            for(std::size_t j = 0; j < i; ++j) data[j].~T();
            allocator.deallocate(data_, capacity_ * sizeof(T));
            throw;

        }
        if(data) {

            for(std::size_t i = 0; i < size; ++i) data[i].~T();
            allocator.deallocate(data, capacity * sizeof(T));

        }
        data = data_;
        capacity = capacity_;

    }

    void resize(std::size_t size_) {

        if(size_ < size) {

            for(std::size_t i = size_ - 1; i != size_ - 1; --i)
                data[i].~T();

        } else if(size_ > size) {

            if(size_ <= capacity) {

                std::size_t i = size;
                try {

                    for(; i < size_; ++i) new(data + i) T();

                } catch(...) {

                    for(std::size_t j = 0; j < i; ++j) data[j].~T();
                    throw;

                }

            } else {

                T* data_ = static_cast<T*>(allocator.allocate(size_ * sizeof(T)));
                std::size_t i = 0;
                try {

                    for(; i < size; ++i) new(data_ + i) T(data[i]);
                    for(; i < size_; ++i) new(data_ + i) T();

                } catch(...) {

                    for(std::size_t j = 0; j < i; ++j) data_[j].~T();
                    allocator.deallocate(data_, size_ * sizeof(T));
                    throw;

                }
                if(data) {

                    for(std::size_t i = 0; i < size; ++i) data[i].~T();
                    allocator.deallocate(data, capacity * sizeof(T));

                }
                data = data_;
                capacity = size_;

            }

        }
        size = size_;

    }

    template <typename... Arg>
    void append(Arg&&... arg) {

        if(size < capacity) {

            new(data + size) T(std::forward<Arg>(arg)...);

        } else {

            std::size_t newSize = size + 1;
            T* newData = static_cast<T*>(allocator.allocate(newSize * sizeof(T)));
            std::size_t i = 0;
            try {

                for(; i < size; ++i) new(newData + i) T(data[i]);
                new(newData + size) T(std::forward<Arg>(arg)...);

            } catch(...) {

                for(std::size_t j = 0; j < i; ++j) newData[j].~T();
                allocator.deallocate(newData, newSize * sizeof(T));
                throw;

            }
            if(data) {

                for(std::size_t i = 0; i < size; ++i) data[i].~T();
                allocator.deallocate(data, capacity * sizeof(T));

            }
            data = newData;
            capacity = newSize;

        }
        ++size;

    }

    void swap(Array& src) noexcept {

        std::swap(allocator, src.allocator);
        std::swap(data, src.data);
        std::swap(size, src.size);
        std::swap(capacity, src.capacity);

    }

    Iterator begin() const noexcept { return data; }
    Iterator end() const noexcept { return data + size; }

    ConstIterator cbegin() const noexcept { return begin(); }
    ConstIterator cend() const noexcept { return end(); }

    ReverseIterator rbegin() const noexcept { return ReverseIterator(end()); }
    ReverseIterator rend() const noexcept { return ReverseIterator(begin()); }

    ConstReverseIterator crbegin() const noexcept { return ConstReverseIterator(cend()); }
    ConstReverseIterator crend() const noexcept { return ConstReverseIterator(cbegin()); }

};

template <typename T>
class ArrayView {

public:

    using Type = T;

    using Iterator = Type*;
    using ConstIterator = const Type*;
    using ReverseIterator = Corecat::ReverseIterator<Iterator>;
    using ConstReverseIterator = Corecat::ReverseIterator<ConstIterator>;

private:

    Type* data = nullptr;
    std::size_t size = 0;

public:

    ArrayView() = default;
    ArrayView(std::nullptr_t) noexcept {}
    ArrayView(Type* data_, std::size_t size_) noexcept : data(data_), size(size_) {}
    template <std::size_t S>
    ArrayView(Type (&array)[S]) noexcept : data(array), size(S) {}
    ArrayView(const ArrayView& src) = default;

    ArrayView& operator =(const ArrayView& src) = default;

    operator ArrayView<const Type>() noexcept { return {data, size}; }

    Type& operator [](std::size_t index) const noexcept { return data[index]; }

    Type* getData() const noexcept { return data; }
    std::size_t getSize() const noexcept { return size; }

    bool isEmpty() const noexcept { return !size; }

    Iterator begin() const noexcept { return data; }
    Iterator end() const noexcept { return data + size; }

    ConstIterator cbegin() const noexcept { return begin(); }
    ConstIterator cend() const noexcept { return end(); }

    ReverseIterator rbegin() const noexcept { return ReverseIterator(end()); }
    ReverseIterator rend() const noexcept { return ReverseIterator(begin()); }

    ConstReverseIterator crbegin() const noexcept { return ConstReverseIterator(cend()); }
    ConstReverseIterator crend() const noexcept { return ConstReverseIterator(cbegin()); }

};

}
}
}

#endif
<|endoftext|>


<commit_before>#include "common.h"
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <ctime>
#include <cstddef>
#include <cstdio>
#include <mutex>
#include <memory>

#ifdef PROJECT_NAMESPACE
namespace PROJECT_NAMESPACE {
#endif  // PROJECT_NAMESPACE

namespace common {

namespace {

const bool use_color = isatty(fileno(stderr));
thread_local const int pid = getpid();

}  // unnamed namespace

char const* LogLevelSymbol(LogLevel l) {
  switch (l) {
    case LogLevel::kInfo:
      return "I";
    case LogLevel::kWarn:
      return "W";
    case LogLevel::kDebug:
      return "D";
    case LogLevel::kFatal:
      return "F";
  }
  return "";
}

char const* LogLevelColorMaybe(LogLevel l) {
  if (use_color) {
    switch (l) {
      case LogLevel::kInfo:
        return "\x1b[32m";
      case LogLevel::kWarn:
        return "\x1b[31m";
      case LogLevel::kDebug:
        return "\x1b[34m";
      case LogLevel::kFatal:
        return "\x1b[31m";
    }
  }
  return "";
}

char const* LogLevelClearMaybe() {
  if (use_color) {
    return "\x1b[0m";
  } else {
    return "";
  }
}

void Log(LogLevel level, char const* file, int line, char const* func,
         char const* fmt, ...) {
  static std::mutex m;
  char const* format_string = "%s%s%s.%06d %d %s:%d: %s]%s ";
  std::time_t time_now;
  std::time(&time_now);
  char time_str[64];
  timeval tv;
  gettimeofday(&tv, nullptr);
  {
    std::lock_guard<std::mutex> lock{m};
    std::strftime(time_str, sizeof(time_str), "%m%d %H:%M:%S",
                  std::localtime(&time_now));
    std::fprintf(stderr, format_string, LogLevelColorMaybe(level),
                 LogLevelSymbol(level), time_str, tv.tv_usec, pid, file, line,
                 func, LogLevelClearMaybe());
    std::va_list ap;
    va_start(ap, fmt);
    std::vfprintf(stderr, fmt, ap);
    va_end(ap);
    std::fputc('\n', stderr);
  }
  if (level == LogLevel::kFatal) {
    throw FatalError{"Fatal error"};
  }
}

void AssertFail(char const* file, int line, char const* func, char const* expr,
                char const* fmt, ...) {
  std::string msg = FormatString("Assertion `%s' failed at %s:%d: %s", expr,
                                 file, line, func);
  if (fmt) {
    msg.append("\nextra message: ");
    std::va_list ap;
    va_start(ap, fmt);
    msg.append(FormatString(fmt, ap));
    va_end(ap);
  }
  throw AssertionError{msg};
}

std::string FormatString(char const* fmt, ...) {
  std::va_list ap;
  va_start(ap, fmt);
  auto&& rst = FormatStringVariadic(fmt, ap);
  va_end(ap);
  return rst;
}

std::string FormatStringVariadic(char const* fmt, std::va_list ap_orig) {
  constexpr std::size_t stack_size = 128;
  auto size = stack_size;
  char stack_ptr[stack_size];
  std::unique_ptr<char[]> heap_ptr{};
  char* ptr = stack_ptr;

  while (true) {
    std::va_list ap;
    va_copy(ap, ap_orig);
    auto n = std::vsnprintf(ptr, size, fmt, ap);
    va_end(ap);
    if (n < 0) {
      throw std::runtime_error("Encoding error");
    } else if (static_cast<std::size_t>(n) < size) {
      return std::string(ptr);
    } else {
      size = n + 1;
      heap_ptr.reset(new char[size]);
      ptr = heap_ptr.get();
    }
  }
}

Exception::Exception(std::string const& s) : msg_{s} {}

Exception::~Exception() = default;

char const* Exception::what() const noexcept { return msg_.c_str(); }

}  // namespace common

#ifdef PROJECT_NAMESPACE
}  // namespace PROJECT_NAMESPACE
#endif  // PROJECT_NAMESPACE
<commit_msg>[master] use curly braces<commit_after>#include "common.h"
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <ctime>
#include <cstddef>
#include <cstdio>
#include <mutex>
#include <memory>

#ifdef PROJECT_NAMESPACE
namespace PROJECT_NAMESPACE {
#endif  // PROJECT_NAMESPACE

namespace common {

namespace {

const bool use_color = isatty(fileno(stderr));
thread_local const int pid = getpid();

}  // unnamed namespace

char const* LogLevelSymbol(LogLevel l) {
  switch (l) {
    case LogLevel::kInfo:
      return "I";
    case LogLevel::kWarn:
      return "W";
    case LogLevel::kDebug:
      return "D";
    case LogLevel::kFatal:
      return "F";
  }
  return "";
}

char const* LogLevelColorMaybe(LogLevel l) {
  if (use_color) {
    switch (l) {
      case LogLevel::kInfo:
        return "\x1b[32m";
      case LogLevel::kWarn:
        return "\x1b[31m";
      case LogLevel::kDebug:
        return "\x1b[34m";
      case LogLevel::kFatal:
        return "\x1b[31m";
    }
  }
  return "";
}

char const* LogLevelClearMaybe() {
  if (use_color) {
    return "\x1b[0m";
  } else {
    return "";
  }
}

void Log(LogLevel level, char const* file, int line, char const* func,
         char const* fmt, ...) {
  static std::mutex m;
  char const* format_string = "%s%s%s.%06d %d %s:%d: %s]%s ";
  std::time_t time_now;
  std::time(&time_now);
  char time_str[64];
  timeval tv;
  gettimeofday(&tv, nullptr);
  {
    std::lock_guard<std::mutex> lock{m};
    std::strftime(time_str, sizeof(time_str), "%m%d %H:%M:%S",
                  std::localtime(&time_now));
    std::fprintf(stderr, format_string, LogLevelColorMaybe(level),
                 LogLevelSymbol(level), time_str, tv.tv_usec, pid, file, line,
                 func, LogLevelClearMaybe());
    std::va_list ap;
    va_start(ap, fmt);
    std::vfprintf(stderr, fmt, ap);
    va_end(ap);
    std::fputc('\n', stderr);
  }
  if (level == LogLevel::kFatal) {
    throw FatalError{"Fatal error"};
  }
}

void AssertFail(char const* file, int line, char const* func, char const* expr,
                char const* fmt, ...) {
  std::string msg = FormatString("Assertion `%s' failed at %s:%d: %s", expr,
                                 file, line, func);
  if (fmt) {
    msg.append("\nextra message: ");
    std::va_list ap;
    va_start(ap, fmt);
    msg.append(FormatString(fmt, ap));
    va_end(ap);
  }
  throw AssertionError{msg};
}

std::string FormatString(char const* fmt, ...) {
  std::va_list ap;
  va_start(ap, fmt);
  auto&& rst = FormatStringVariadic(fmt, ap);
  va_end(ap);
  return rst;
}

std::string FormatStringVariadic(char const* fmt, std::va_list ap_orig) {
  constexpr std::size_t stack_size = 128;
  auto size = stack_size;
  char stack_ptr[stack_size];
  std::unique_ptr<char[]> heap_ptr{};
  char* ptr = stack_ptr;

  while (true) {
    std::va_list ap;
    va_copy(ap, ap_orig);
    auto n = std::vsnprintf(ptr, size, fmt, ap);
    va_end(ap);
    if (n < 0) {
      throw std::runtime_error{"Encoding error"};
    } else if (static_cast<std::size_t>(n) < size) {
      return std::string(ptr);
    } else {
      size = n + 1;
      heap_ptr.reset(new char[size]);
      ptr = heap_ptr.get();
    }
  }
}

Exception::Exception(std::string const& s) : msg_{s} {}

Exception::~Exception() = default;

char const* Exception::what() const noexcept { return msg_.c_str(); }

}  // namespace common

#ifdef PROJECT_NAMESPACE
}  // namespace PROJECT_NAMESPACE
#endif  // PROJECT_NAMESPACE
<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/extensions/theme_installed_infobar_delegate.h"

#include <string>

#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/extensions/extensions_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/themes/browser_theme_provider.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/notification_service.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"

ThemeInstalledInfoBarDelegate::ThemeInstalledInfoBarDelegate(
    TabContents* tab_contents,
    const Extension* new_theme,
    const std::string& previous_theme_id)
    : ConfirmInfoBarDelegate(tab_contents),
      profile_(tab_contents->profile()),
      name_(new_theme->name()),
      theme_id_(new_theme->id()),
      previous_theme_id_(previous_theme_id),
      tab_contents_(tab_contents) {
  profile_->GetThemeProvider()->OnInfobarDisplayed();
  registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED,
                 NotificationService::AllSources());
}

ThemeInstalledInfoBarDelegate::~ThemeInstalledInfoBarDelegate() {
  // We don't want any notifications while we're running our destructor.
  registrar_.RemoveAll();

  profile_->GetThemeProvider()->OnInfobarDestroyed();
}

void ThemeInstalledInfoBarDelegate::InfoBarClosed() {
  delete this;
}

string16 ThemeInstalledInfoBarDelegate::GetMessageText() const {
  return l10n_util::GetStringFUTF16(IDS_THEME_INSTALL_INFOBAR_LABEL,
                                    UTF8ToUTF16(name_));
}

SkBitmap* ThemeInstalledInfoBarDelegate::GetIcon() const {
  // TODO(aa): Reply with the theme's icon, but this requires reading it
  // asynchronously from disk.
  return ResourceBundle::GetSharedInstance().GetBitmapNamed(IDR_INFOBAR_THEME);
}

ThemeInstalledInfoBarDelegate*
    ThemeInstalledInfoBarDelegate::AsThemePreviewInfobarDelegate() {
  return this;
}

int ThemeInstalledInfoBarDelegate::GetButtons() const {
  return BUTTON_CANCEL;
}

string16 ThemeInstalledInfoBarDelegate::GetButtonLabel(
    ConfirmInfoBarDelegate::InfoBarButton button) const {
  // The InfoBar will create a default OK button and make it invisible.
  // TODO(mirandac): remove the default OK button from ConfirmInfoBar.
  return (button == BUTTON_CANCEL) ?
      l10n_util::GetStringUTF16(IDS_THEME_INSTALL_INFOBAR_UNDO_BUTTON) :
      string16();
}

bool ThemeInstalledInfoBarDelegate::Cancel() {
  if (!previous_theme_id_.empty()) {
    ExtensionsService* service = profile_->GetExtensionsService();
    if (service) {
      const Extension* previous_theme =
          service->GetExtensionById(previous_theme_id_, true);
      if (previous_theme) {
        profile_->SetTheme(previous_theme);
        return true;
      }
    }
  }

  profile_->ClearTheme();
  return true;
}

void ThemeInstalledInfoBarDelegate::Observe(
    NotificationType type,
    const NotificationSource& source,
    const NotificationDetails& details) {
  DCHECK_EQ(NotificationType::BROWSER_THEME_CHANGED, type.value);
  // If the new theme is different from what this info bar is associated
  // with, close this info bar since it is no longer relevant.
  const Extension* extension = Details<const Extension>(details).ptr();
  if (!extension || theme_id_ != extension->id())
    tab_contents_->RemoveInfoBar(this);
}

bool ThemeInstalledInfoBarDelegate::MatchesTheme(const Extension* theme) {
  return (theme && theme->id() == theme_id_);
}
<commit_msg>Check that TabContents is valid (not null) before removing theme change InfoBar.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/extensions/theme_installed_infobar_delegate.h"

#include <string>

#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/extensions/extensions_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/themes/browser_theme_provider.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/notification_service.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"

ThemeInstalledInfoBarDelegate::ThemeInstalledInfoBarDelegate(
    TabContents* tab_contents,
    const Extension* new_theme,
    const std::string& previous_theme_id)
    : ConfirmInfoBarDelegate(tab_contents),
      profile_(tab_contents->profile()),
      name_(new_theme->name()),
      theme_id_(new_theme->id()),
      previous_theme_id_(previous_theme_id),
      tab_contents_(tab_contents) {
  profile_->GetThemeProvider()->OnInfobarDisplayed();
  registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED,
                 NotificationService::AllSources());
}

ThemeInstalledInfoBarDelegate::~ThemeInstalledInfoBarDelegate() {
  // We don't want any notifications while we're running our destructor.
  registrar_.RemoveAll();

  profile_->GetThemeProvider()->OnInfobarDestroyed();
}

void ThemeInstalledInfoBarDelegate::InfoBarClosed() {
  delete this;
}

string16 ThemeInstalledInfoBarDelegate::GetMessageText() const {
  return l10n_util::GetStringFUTF16(IDS_THEME_INSTALL_INFOBAR_LABEL,
                                    UTF8ToUTF16(name_));
}

SkBitmap* ThemeInstalledInfoBarDelegate::GetIcon() const {
  // TODO(aa): Reply with the theme's icon, but this requires reading it
  // asynchronously from disk.
  return ResourceBundle::GetSharedInstance().GetBitmapNamed(IDR_INFOBAR_THEME);
}

ThemeInstalledInfoBarDelegate*
    ThemeInstalledInfoBarDelegate::AsThemePreviewInfobarDelegate() {
  return this;
}

int ThemeInstalledInfoBarDelegate::GetButtons() const {
  return BUTTON_CANCEL;
}

string16 ThemeInstalledInfoBarDelegate::GetButtonLabel(
    ConfirmInfoBarDelegate::InfoBarButton button) const {
  // The InfoBar will create a default OK button and make it invisible.
  // TODO(mirandac): remove the default OK button from ConfirmInfoBar.
  return (button == BUTTON_CANCEL) ?
      l10n_util::GetStringUTF16(IDS_THEME_INSTALL_INFOBAR_UNDO_BUTTON) :
      string16();
}

bool ThemeInstalledInfoBarDelegate::Cancel() {
  if (!previous_theme_id_.empty()) {
    ExtensionsService* service = profile_->GetExtensionsService();
    if (service) {
      const Extension* previous_theme =
          service->GetExtensionById(previous_theme_id_, true);
      if (previous_theme) {
        profile_->SetTheme(previous_theme);
        return true;
      }
    }
  }

  profile_->ClearTheme();
  return true;
}

void ThemeInstalledInfoBarDelegate::Observe(
    NotificationType type,
    const NotificationSource& source,
    const NotificationDetails& details) {
  DCHECK_EQ(NotificationType::BROWSER_THEME_CHANGED, type.value);
  // If the new theme is different from what this info bar is associated
  // with, close this info bar since it is no longer relevant.
  const Extension* extension = Details<const Extension>(details).ptr();
  if (!extension || theme_id_ != extension->id()) {
    if (tab_contents_ && !tab_contents_->is_being_destroyed()) {
      tab_contents_->RemoveInfoBar(this);
      // The infobar is gone so there is no reason for this delegate to keep
      // a pointer to the TabContents (the TabContents has deleted its
      // reference to this delegate and a new delegate will be created if
      // a new infobar is created).
      tab_contents_ = NULL;
      // Although it's not being used anymore, this delegate is never deleted.
      // It can not be deleted now because it is still needed if we
      // "undo" the theme change that triggered this notification
      // (when InfoBar::OnBackgroundExpose() is called). This will likely
      // be fixed when infobar delegate deletion is cleaned up for
      // http://crbug.com/62154.
    }
  }
}

bool ThemeInstalledInfoBarDelegate::MatchesTheme(const Extension* theme) {
  return (theme && theme->id() == theme_id_);
}
<|endoftext|>


<commit_before>#include <iostream>
#include <cstdlib>
#include <cmath>
#include <cstdio>
#include "consts.h"
#include "circuits/circuit.h"
#include "matrix/newtonraphson.h"

using namespace std;

static const int MAX_ATTEMPTS = 500;
static const int MAX_LOOPS = 1000;
static const double TOLERANCE = 1e-4;

void randomize(int numVariables, double (&solution)[MAX_NODES+1]){
    solution[0] = 0; // gnd
    for(int i=1; i<=numVariables; i++){
        solution[i] = ((double(rand()) / double(RAND_MAX)) - 0.5)*100;
    }
}

double calcDistance(int numVariables, double x[MAX_NODES+1], double y[MAX_NODES+1]){
    double sum=0;
    double distance=0;
    for(int i=1; i<=numVariables ;i++) {
        sum += pow((x[i]-y[i]),2);
    }
    distance = sqrt(sum);
    return distance;
}

void printSolution(int numVariables, double solution[MAX_NODES+1]){
    for(int i=1; i<=numVariables; i++){
        cout << solution[i] << endl;
    }
    cout << endl;
}

int runNewtonRaphson(Circuit circuit,
                     double (&finalSolution)[MAX_NODES+1],
                     double t,
                     double (&lastSolution)[MAX_NODES+1]){

    int rc=0;
    int numAttempts=0;
    int numLoops=0;
    bool converged=false;
    double solution[MAX_NODES+1];
    double distance=0;
    double previousSolution[MAX_NODES+1];
    double Yn[MAX_NODES+1][MAX_NODES+2];

    copySolution(circuit.getNumVariables(), ZERO_SOLUTION, previousSolution);

    while(!converged && numAttempts <= MAX_ATTEMPTS ){
        numAttempts++;
        numLoops=0;

        while(!converged && numLoops <= MAX_LOOPS){
            numLoops++;

            init(circuit.getNumVariables(), Yn);
            circuit.applyStamps(Yn,
                                previousSolution,
                                t,
                                lastSolution);

            rc = solve(circuit.getNumVariables(), Yn);
            if (rc)
                // Let's try a new randomized initial solution!
                break;

            getSolution(circuit.getNumVariables(),
                        Yn,
                        solution);

            distance = calcDistance(circuit.getNumVariables(),
                                    solution,
                                    previousSolution);
            if (distance < TOLERANCE){
                converged = true;
                solution[0] = 0; // Ground!
                copySolution(circuit.getNumVariables(),
                             solution,
                             finalSolution);
            } else {
                copySolution(circuit.getNumVariables(),
                             solution,
                             previousSolution);
            }
        }
        randomize(circuit.getNumVariables(), previousSolution);
    }
    if (!converged){
        cout << "Newton Raphson did not converge.";
        #if defined (WIN32) || defined(_WIN32)
        cout << endl << "Press any key to exit...";
        cin.get();
        cin.get();
        #endif
        exit(EXIT_FAILURE);
    }
    return 0;
}
<commit_msg>Revert "Raises range for Newton Raphson initialization"<commit_after>#include <iostream>
#include <cstdlib>
#include <cmath>
#include <cstdio>
#include "consts.h"
#include "circuits/circuit.h"
#include "matrix/newtonraphson.h"

using namespace std;

static const int MAX_ATTEMPTS = 500;
static const int MAX_LOOPS = 1000;
static const double TOLERANCE = 1e-4;

void randomize(int numVariables, double (&solution)[MAX_NODES+1]){
    solution[0] = 0; // gnd
    for(int i=1; i<=numVariables; i++){
        solution[i] = (double(rand()) / double(RAND_MAX)) - 0.5;
    }
}

double calcDistance(int numVariables, double x[MAX_NODES+1], double y[MAX_NODES+1]){
    double sum=0;
    double distance=0;
    for(int i=1; i<=numVariables ;i++) {
        sum += pow((x[i]-y[i]),2);
    }
    distance = sqrt(sum);
    return distance;
}

void printSolution(int numVariables, double solution[MAX_NODES+1]){
    for(int i=1; i<=numVariables; i++){
        cout << solution[i] << endl;
    }
    cout << endl;
}

int runNewtonRaphson(Circuit circuit,
                     double (&finalSolution)[MAX_NODES+1],
                     double t,
                     double (&lastSolution)[MAX_NODES+1]){

    int rc=0;
    int numAttempts=0;
    int numLoops=0;
    bool converged=false;
    double solution[MAX_NODES+1];
    double distance=0;
    double previousSolution[MAX_NODES+1];
    double Yn[MAX_NODES+1][MAX_NODES+2];

    copySolution(circuit.getNumVariables(), ZERO_SOLUTION, previousSolution);

    while(!converged && numAttempts <= MAX_ATTEMPTS ){
        numAttempts++;
        numLoops=0;

        while(!converged && numLoops <= MAX_LOOPS){
            numLoops++;

            init(circuit.getNumVariables(), Yn);
            circuit.applyStamps(Yn,
                                previousSolution,
                                t,
                                lastSolution);

            rc = solve(circuit.getNumVariables(), Yn);
            if (rc)
                // Let's try a new randomized initial solution!
                break;

            getSolution(circuit.getNumVariables(),
                        Yn,
                        solution);

            distance = calcDistance(circuit.getNumVariables(),
                                    solution,
                                    previousSolution);
            if (distance < TOLERANCE){
                converged = true;
                solution[0] = 0; // Ground!
                copySolution(circuit.getNumVariables(),
                             solution,
                             finalSolution);
            } else {
                copySolution(circuit.getNumVariables(),
                             solution,
                             previousSolution);
            }
        }
        randomize(circuit.getNumVariables(), previousSolution);
    }
    if (!converged){
        cout << "Newton Raphson did not converge.";
        #if defined (WIN32) || defined(_WIN32)
        cout << endl << "Press any key to exit...";
        cin.get();
        cin.get();
        #endif
        exit(EXIT_FAILURE);
    }
    return 0;
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2017 Tmplt <tmplt@dragons.rocks>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include <map>                       // std::map
#include <string>                    // std::string
#include <vector>                    // std::vector
#include <memory>                    // std:unique_ptr
#include <utility>                   // std::forward
#include <experimental/string_view>  // std::experimental::string_view

#include "errors.hpp"

using std::string;
using std::vector;
using std::experimental::string_view;

using std::forward;

namespace command_line {

/* Something more specific than "runtime_error". */
DEFINE_ERROR(argument_error);
DEFINE_ERROR(value_error);

class option;
class option_group;
using options = vector<option>;
using groups  = vector<option_group>;
using choices = vector<string>;

/*
 * Holds all properties for an option.
 * (A possible flag to pass to the program.)
 */
struct option {
    const string flag, flag_long, desc;

    /*
     * e.g. seen as --log LEVEL in usage(),
     * where LEVEL is the token.
     */
    const string token;

    /*
     * For options where a set of values are allowed,
     * e.g. --log LEVEL, where LEVEL is one of:
     * error, warning, info, trace.
     */
    const choices values;

    explicit option(string &&flag, string &&flag_long, string &&desc, string &&token = "",
            const choices c = {})
        : flag(forward<string>(flag)), flag_long(forward<string>(flag_long)),
        desc(forward<string>(desc)), token(forward<string>(token)), values(c) {}
};

/* A named group with it's related options. */
struct option_group {
public:
    const string name;
    const string synopsis;
    vector<option> options;

    explicit option_group(string &&name, string &&synopsis)
        : name(forward<string>(name)), synopsis(forward<string>(synopsis)) {}

    template <typename... Args>
    option_group& operator()(Args&&... args)
    {
        options.emplace_back(option(forward<Args>(args)...));

        return *this;
    }
};

class parser {
public:
    using cli_type = std::unique_ptr<parser>;
    static cli_type make(const string &&scriptname, const groups &&groups);

    /* Construct the parser. */
    explicit parser(string &&synopsis, const groups &&groups)
        : synopsis_(std::forward<decltype(synopsis)>(synopsis)),
        valid_groups_(std::forward<decltype(groups)>(groups)) {}

    /* Print which flags you can pass and how to use the program. */
    void usage() const;

    /* Process command line arguments. */
    void process_arguments(const vector<string> &args);

    /*
     * Program specific; adhere to the options' synopsises seen in main(),
     * e.g. pass at least one main argument if -d isn't passed.
     */
    void validate_arguments() const;

    /* Check if an option has been passed. */
    bool has(const string &option) const;

    /* Get the value for a given option. */
    string get(string opt) const;

protected:
    /*
     * Construct a string of all valid token values,
     * e.g. "VAL1, VAL2, VAL3".
     */
    auto values_to_str(const choices &values) const;

    /*
     * Is the flag passed in it's long or its short form?
     * Does it match any of the two?
     */
    auto is_short(const string_view &option, const string_view &opt_short) const;
    auto is_long(const string_view &option, const string_view &opt_long) const;
    auto is(const string_view &option, string opt_short, string opt_long) const;

    /* Check if the passed value matches an element in the group of valid values. */
    auto check_value(const string_view &flag, const string_view &value, const choices &values) const;

    /* Parse a single argument with the next argument, which may be its value (or another flag). */
    void parse(const string_view &input, const string_view &input_next);

    /*
     * Used to check if a passed option is valid
     * between the group of valid options and the group
     * of passed options.
     */
    bool compare(string opt, const string_view &val) const;

private:
    /* Program synopsis. */
    const string synopsis_;

    const options valid_opts_;
    const groups valid_groups_;
    std::map<string, string> passed_opts_;

    /*
     * Is the next argument associated with the previous one,
     * or should the current argument be treated as another flag?
     */
    bool skipnext_ = false;
};

/* ns command_line */
}

using cliparser = command_line::parser;
using cligroup  = command_line::option_group;
using clioption = command_line::option;
<commit_msg>option_group::operator(): let emplace_back handle option construction<commit_after>/*
 * Copyright (C) 2017 Tmplt <tmplt@dragons.rocks>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include <map>                       // std::map
#include <string>                    // std::string
#include <vector>                    // std::vector
#include <memory>                    // std:unique_ptr
#include <utility>                   // std::forward
#include <experimental/string_view>  // std::experimental::string_view

#include "errors.hpp"

using std::string;
using std::vector;
using std::experimental::string_view;

using std::forward;

namespace command_line {

/* Something more specific than "runtime_error". */
DEFINE_ERROR(argument_error);
DEFINE_ERROR(value_error);

class option;
class option_group;
using options = vector<option>;
using groups  = vector<option_group>;
using choices = vector<string>;

/*
 * Holds all properties for an option.
 * (A possible flag to pass to the program.)
 */
struct option {
    const string flag, flag_long, desc;

    /*
     * e.g. seen as --log LEVEL in usage(),
     * where LEVEL is the token.
     */
    const string token;

    /*
     * For options where a set of values are allowed,
     * e.g. --log LEVEL, where LEVEL is one of:
     * error, warning, info, trace.
     */
    const choices values;

    explicit option(string &&flag, string &&flag_long, string &&desc, string &&token = "",
            const choices c = {})
        : flag(forward<string>(flag)), flag_long(forward<string>(flag_long)),
        desc(forward<string>(desc)), token(forward<string>(token)), values(c) {}
};

/* A named group with it's related options. */
struct option_group {
public:
    const string name;
    const string synopsis;
    vector<option> options;

    explicit option_group(string &&name, string &&synopsis)
        : name(forward<string>(name)), synopsis(forward<string>(synopsis)) {}

    template <typename... Args>
    option_group& operator()(Args&&... args)
    {
        options.emplace_back(forward<Args>(args)...);
        return *this;
    }
};

class parser {
public:
    using cli_type = std::unique_ptr<parser>;
    static cli_type make(const string &&scriptname, const groups &&groups);

    /* Construct the parser. */
    explicit parser(string &&synopsis, const groups &&groups)
        : synopsis_(std::forward<decltype(synopsis)>(synopsis)),
        valid_groups_(std::forward<decltype(groups)>(groups)) {}

    /* Print which flags you can pass and how to use the program. */
    void usage() const;

    /* Process command line arguments. */
    void process_arguments(const vector<string> &args);

    /*
     * Program specific; adhere to the options' synopsises seen in main(),
     * e.g. pass at least one main argument if -d isn't passed.
     */
    void validate_arguments() const;

    /* Check if an option has been passed. */
    bool has(const string &option) const;

    /* Get the value for a given option. */
    string get(string opt) const;

protected:
    /*
     * Construct a string of all valid token values,
     * e.g. "VAL1, VAL2, VAL3".
     */
    auto values_to_str(const choices &values) const;

    /*
     * Is the flag passed in it's long or its short form?
     * Does it match any of the two?
     */
    auto is_short(const string_view &option, const string_view &opt_short) const;
    auto is_long(const string_view &option, const string_view &opt_long) const;
    auto is(const string_view &option, string opt_short, string opt_long) const;

    /* Check if the passed value matches an element in the group of valid values. */
    auto check_value(const string_view &flag, const string_view &value, const choices &values) const;

    /* Parse a single argument with the next argument, which may be its value (or another flag). */
    void parse(const string_view &input, const string_view &input_next);

    /*
     * Used to check if a passed option is valid
     * between the group of valid options and the group
     * of passed options.
     */
    bool compare(string opt, const string_view &val) const;

private:
    /* Program synopsis. */
    const string synopsis_;

    const options valid_opts_;
    const groups valid_groups_;
    std::map<string, string> passed_opts_;

    /*
     * Is the next argument associated with the previous one,
     * or should the current argument be treated as another flag?
     */
    bool skipnext_ = false;
};

/* ns command_line */
}

using cliparser = command_line::parser;
using cligroup  = command_line::option_group;
using clioption = command_line::option;
<|endoftext|>