<commit_before>// BezierCurve.cpp
// Copyright (c) 2009, Dan Heeks
// This program is released under the BSD license. See the file COPYING for details.

#include "stdafx.h"
#include "BezierCurve.h"
#if 0
#include "Point.h"
#include "Arc.h"
#endif

void split_bezier_curve(int level, const gp_Pnt& vt0, const gp_Pnt& vt2, const gp_Pnt& vt02, const gp_Pnt& vt20, void(*call_back)(const gp_Pnt& vt0, const gp_Pnt& vt1))
{
	if(level > 0)
	{
		// split into two sub lines
		for(int i = 0; i<2; i++){
			gp_Pnt nvt0 = vt0;
			gp_Pnt nvt2 = vt2;
			gp_Pnt nvt20 = vt20;
			gp_Pnt nvt02 = vt02;

			if(i == 1){
				// mirror
				gp_Pnt t2 = nvt2;
				gp_Pnt t20 = nvt20;
				nvt2 = nvt0;
				nvt20 = nvt02;
				nvt0 = t2;
				nvt02 = t20;
			}

			nvt2=(nvt20.XYZ()+nvt2.XYZ())/2;
			nvt20=(nvt02.XYZ()+nvt20.XYZ())/2;
			nvt2=(nvt20.XYZ()+nvt2.XYZ())/2;
			nvt02=(nvt0.XYZ()+nvt02.XYZ())/2;
			nvt20=(nvt02.XYZ()+nvt20.XYZ())/2;
			nvt2=(nvt20.XYZ()+nvt2.XYZ())/2;

			if(i == 1){
				// unmirror
				gp_Pnt t2 = nvt2;
				gp_Pnt t20 = nvt20;
				nvt2 = nvt0;
				nvt20 = nvt02;
				nvt0 = t2;
				nvt02 = t20;
			}

			// recursive
			split_bezier_curve(level - 1, nvt0, nvt2, nvt02, nvt20, call_back);
		}

	}
	else{
		// render line
		(*call_back)(vt0, vt2);
	}
}

#if 0

void biarc(const Point& P0, const Point& TS, const Point& P4, const Point& TE, double r, Point& P1, Point& P2, Point& P3, double &alpha, double &beta))
{
    TS = TS.unit();
    TE = TE.unit();

    Point v = P0 - P4;

    Point c = v*v
    double b = 2*v*(TS*r+TE)
    double a = 2*r*(TS*TE-1)

    if(fabs(a)<0.0000000000001)
	return;

    double discr = b*b-4*a*c;
    if(discr < 0)
	return;

    double disq = discr**.5;
    double beta1 = (-b - disq) / 2 / a;
    double beta2 = (-b + disq) / 2 / a;

    if (beta1 > 0.0000000000001 && beta2 > 0.000000000001)
	return;

	double beta = beta1;
	if(beta2 > beta)beta = beta2;

    if (beta < -0.0000000000001)
	return;

    double alpha = beta * r;
    double ab = alpha + beta;
    P1 = P0 + TS * alpha;
    P3 = P4 - TE * beta;
    P2 = P1 * (beta / ab) + P3 * (alpha / ab);
}

double radiusDifference(const Arc& arc, const Point& p)
{
	if(arc.m_c == arc.m_p0)return 0.0;

        return (arc.m_c - p).magn() - fabs(arc.m_p0.dist(arc.m_c));
}

void giarc(const Point& PS, const Point& TS, const Point& PE, const Point& TE, double r, Arc& arc1, Arc& arc2)
{
	Point TSu = TS.unit();
	Point TEu = TE.unit();
	Point P1, P2, P3;
	double alpha, beta;
	biarc(PS, TS, PE, TE, r, P1, P2, P3, alpha, beta);

	arc1 = Arc(PS, P2, TS);
	arc2 = Arc(P2, PE, P3 - P2);
}

// Calculate the the location of the point on the curve at t
void calculateSplinePoint(self, t):
        return (self.P0 * (1 - t) ** 3 +
                3 * self.P1 * t * (1 - t) ** 2 +
                3 * self.P2 * t ** 2 * (1-t) +
                self.P3 * t ** 3)

    # Calculate the the tangent on the curve at t
    def calculateTangent(self, t):
        return (self.Q0 * (1 - t) ** 2 +
                2 * self.Q1 * t * (1 - t) +
                self.Q2 * t ** 2)

    # Create biarcs for a piece of the curve. The first arc will start
    # on the curve at tS, the second one will end at tE. If the curve
    # distance from the center of the arcs to the midpoint of the half
    # of the curve segment the arc represents is larger than
    # max_divergence, split the curve and repeat until the arcs stay
    # within the limit. This function returns the location and tangent
    # at tE
    def createArcs(self, PS, TS, tS, tE):
        PE = self.calculateSplinePoint(tE)
        TE = self.calculateTangent(tE)

        tDelta = tE - tS

        a1, a2 = giarc(PS, TS, PE, TE)

        PM1 = self.calculateSplinePoint(tS + (tDelta * 0.25))
        PM2 = self.calculateSplinePoint(tS + (tDelta * 0.75))

        if ((abs(a1.radiusDifference(PM1) ) > self.max_divergence) or
            (abs(a2.radiusDifference(PM2) ) > self.max_divergence)):
            tM = tS + (tDelta * 0.5)

            PM, TM = self.createArcs(PS, TS, tS, tM)
            self.createArcs(PM, TM, tM, tE)
        else:
            self.arcs.append(a1)
            self.arcs.append(a2)

        return PE, TE

    # Output the G-code for the arcs describing this curve.
    def printGCode(self, output):
        if len(self.arcs) == 0:
            PS = self.P0
            TS = self.P1 - self.P0
            tS = 0

            for i in range(0, self.n):
                tE = (i + 1) * 1. / self.n

                PS, TS = self.createArcs(PS, TS, tS, tE)
                tS = tE

        for arc in self.arcs:
            arc.printGCode(output)

if __name__ == '__main__':
    import sys
    print "G0X0Y0Z0"
    print "F100"
    s = Spline(P(0,0), P(.25,1), P(1,1), P(2,0), 2)
    s.max_divergence = 2
    s.printGCode(sys.stdout)
    print "G0X0Y0Z0"
    s = Spline(P(0,0), P(.25,1), P(1,1), P(2,0), 4)
    s.max_divergence = 2
    s.printGCode(sys.stdout)
    print "G0X0Y0Z0"
    s = Spline(P(0,0), P(.25,1), P(1,1), P(2,0), 8)
    s.max_divergence = 2
    s.printGCode(sys.stdout)
    print "M2"

void bezier_curve_to_arcs(double maximum_deviation, const gp_Pnt& vt0, const gp_Pnt& vt2, const gp_Pnt& vt02, const gp_Pnt& vt20, void(*call_back)(const gp_Pnt& vt0, const gp_Pnt& vt1, const gp_Pnt& c, bool dir))
{
	gp_Pnt arc0_p0
}
#endif
<commit_msg>removed some code that I was trying, but didn't mean to add<commit_after>// BezierCurve.cpp
// Copyright (c) 2009, Dan Heeks
// This program is released under the BSD license. See the file COPYING for details.

#include "stdafx.h"
#include "BezierCurve.h"

void split_bezier_curve(int level, const gp_Pnt& vt0, const gp_Pnt& vt2, const gp_Pnt& vt02, const gp_Pnt& vt20, void(*call_back)(const gp_Pnt& vt0, const gp_Pnt& vt1))
{
	if(level > 0)
	{
		// split into two sub lines
		for(int i = 0; i<2; i++){
			gp_Pnt nvt0 = vt0;
			gp_Pnt nvt2 = vt2;
			gp_Pnt nvt20 = vt20;
			gp_Pnt nvt02 = vt02;

			if(i == 1){
				// mirror
				gp_Pnt t2 = nvt2;
				gp_Pnt t20 = nvt20;
				nvt2 = nvt0;
				nvt20 = nvt02;
				nvt0 = t2;
				nvt02 = t20;
			}

			nvt2=(nvt20.XYZ()+nvt2.XYZ())/2;
			nvt20=(nvt02.XYZ()+nvt20.XYZ())/2;
			nvt2=(nvt20.XYZ()+nvt2.XYZ())/2;
			nvt02=(nvt0.XYZ()+nvt02.XYZ())/2;
			nvt20=(nvt02.XYZ()+nvt20.XYZ())/2;
			nvt2=(nvt20.XYZ()+nvt2.XYZ())/2;

			if(i == 1){
				// unmirror
				gp_Pnt t2 = nvt2;
				gp_Pnt t20 = nvt20;
				nvt2 = nvt0;
				nvt20 = nvt02;
				nvt0 = t2;
				nvt02 = t20;
			}

			// recursive
			split_bezier_curve(level - 1, nvt0, nvt2, nvt02, nvt20, call_back);
		}

	}
	else{
		// render line
		(*call_back)(vt0, vt2);
	}
}

<|endoftext|>


<commit_before>/*
Copyright (c) 2016,
Dan Bethell, Johannes Saam, Vahan Sosoyan, Brian Scherbinski.
All rights reserved. See COPYING.txt for more details.
*/

#include "FrameBuffer.h"
#include "boost/format.hpp"

using namespace aton;

const std::string chStr::RGBA = "RGBA",
                  chStr::rgb = "rgb",
                  chStr::depth = "depth",
                  chStr::Z = "Z",
                  chStr::N = "N",
                  chStr::P = "P",
                  chStr::_red = ".red",
                  chStr::_green = ".green",
                  chStr::_blue = ".blue",
                  chStr::_X = ".X",
                  chStr::_Y = ".Y",
                  chStr::_Z = ".Z";

// Lightweight color pixel class
RenderColor::RenderColor() { _val[0] = _val[1] = _val[2] = 0.0f; }

float& RenderColor::operator[](int i) { return _val[i]; }
const float& RenderColor::operator[](int i) const { return _val[i]; }

void RenderColor::reset() { _val[0] = _val[1] = _val[2] = 0.0f; }

// RenderBuffer class
RenderBuffer::RenderBuffer(const unsigned int& width,
                           const unsigned int& height,
                           const int& spp)
{
    int size = width * height;

    switch (spp)
    {
        case 1: // Float channels
            _float_data.resize(size);
            break;
        case 3: // Color Channels
            _color_data.resize(size);
            break;
        case 4: // Color + Alpha channels
            _color_data.resize(size);
            _float_data.resize(size);
            break;
    }
}

// FrameBuffer class
FrameBuffer::FrameBuffer(const double& currentFrame,
                         const int& w,
                         const int& h): _frame(currentFrame),
                                        _width(w),
                                        _height(h),
                                        _progress(0),
                                        _time(0),
                                        _ram(0),
                                        _pram(0),
                                        _ready(false) {}

// Add new buffer
void FrameBuffer::addBuffer(const char* aov,
                            const int& spp)
{
    RenderBuffer buffer(_width, _height, spp);

    _buffers.push_back(buffer);
    _aovs.push_back(aov);
}

// Get writable buffer object
void FrameBuffer::setBufferPix(const int& b,
                               const unsigned int& x,
                               const unsigned int& y,
                               const int& spp,
                               const int& c,
                               const float& pix)
{
    RenderBuffer& rb = _buffers[b];
    unsigned int index = (_width * y) + x;
    if (c < 3 && spp != 1)
        rb._color_data[index][c] = pix;
    else
        rb._float_data[index] = pix;
}

// Get read only buffer object
const float& FrameBuffer::getBufferPix(const int& b,
                                       const unsigned int& x,
                                       const unsigned int& y,
                                       const int& c) const
{
    const RenderBuffer& rb = _buffers[b];
    unsigned int index = (_width * y) + x;
    if (c < 3 && !rb._color_data.empty())
        return rb._color_data[index][c];
    else
        return rb._float_data[index];
}

// Get the current buffer index
int FrameBuffer::getBufferIndex(const Channel& z)
{
    int b_index = 0;
    if (_aovs.size() > 1)
    {
        using namespace chStr;
        std::string layer = getLayerName(z);

        std::vector<std::string>::iterator it;
        for(it = _aovs.begin(); it != _aovs.end(); ++it)
        {
            if (*it == layer)
            {
                b_index = static_cast<int>(it - _aovs.begin());
                break;
            }
            else if (*it == Z && layer == depth)
            {
                b_index = static_cast<int>(it - _aovs.begin());
                break;
            }
        }

    }
    return b_index;
}

// Get the current buffer index
int FrameBuffer::getBufferIndex(const char* aovName)
{
    int b_index = 0;
    if (_aovs.size() > 1)
    {
        std::vector<std::string>::iterator it;
        for(it = _aovs.begin(); it != _aovs.end(); ++it)
        {
            if (*it == aovName)
            {
                b_index = static_cast<int>(it - _aovs.begin());
                break;
            }
        }
    }
    return b_index;
}

// Get N buffer/aov name name
const char* FrameBuffer::getBufferName(const int& index)
{
    const char* aovName = "";

    if(!_aovs.empty())
        try
        {
            aovName = _aovs.at(index).c_str();
        }
        catch (const std::out_of_range& e) {}
        catch (...)
        {
            std::cerr << "Unexpected error at getting buffer name" << std::endl;
        }

    return aovName;
}

// Get last buffer/aov name
bool FrameBuffer::isFirstBufferName(const char* aovName)
{
    return strcmp(_aovs.front().c_str(), aovName) == 0;;
}

// Check if Frame has been changed
bool FrameBuffer::isFrameChanged(const double& frame)
{
    return frame != _frame;
}

// Check if Aovs has been changed
bool FrameBuffer::isAovsChanged(const std::vector<std::string>& aovs)
{
    return (aovs != _aovs);
}

// Check if Resolution has been changed
bool FrameBuffer::isResolutionChanged(const unsigned int& w,
                                      const unsigned int& h)
{
    return (w != _width && h != _height);
}

// Resize the containers to match the resolution
void FrameBuffer::setResolution(const unsigned int& w,
                                const unsigned int& h)
{
    _width = w;
    _height = h;

    int bfSize = _width * _height;

    std::vector<RenderBuffer>::iterator iRB;
    for(iRB = _buffers.begin(); iRB != _buffers.end(); ++iRB)
    {
        if (!iRB->_color_data.empty())
        {
            RenderColor color;
            std::fill(iRB->_color_data.begin(), iRB->_color_data.end(), color);
            iRB->_color_data.resize(bfSize);
        }
        if (!iRB->_float_data.empty())
        {
            std::fill(iRB->_float_data.begin(), iRB->_float_data.end(), 0.0f);
            iRB->_float_data.resize(bfSize);
        }
    }
}

// Clear buffers and aovs
void FrameBuffer::clearAll()
{
    _buffers = std::vector<RenderBuffer>();
    _aovs = std::vector<std::string>();
}

// Check if the given buffer/aov name name is exist
bool FrameBuffer::isBufferExist(const char* aovName)
{
    return std::find(_aovs.begin(), _aovs.end(), aovName) != _aovs.end();
}

// Get width of the buffer
const int& FrameBuffer::getWidth() { return _width; }

// Get height of the buffer
const int& FrameBuffer::getHeight() { return _height; }

// Get size of the buffers aka AOVs count
size_t FrameBuffer::size() { return _aovs.size(); }

// Resize the buffers
void FrameBuffer::resize(const size_t& s)
{
    _buffers.resize(s);
    _aovs.resize(s);
}

// Set status parameters
void FrameBuffer::setProgress(const long long& progress)
{
    _progress = progress > 100 ? 100 : progress;
}

void FrameBuffer::setRAM(const long long& ram)
{
    int ramGb = static_cast<int>(ram / 1048576);
    _ram = ramGb;
    _pram = ramGb > _pram ? ramGb : _pram;

}
void FrameBuffer::setTime(const int& time,
                          const int& dtime)
{
    _time = dtime > time ? time : time - dtime;
}

// Get status parameters
const long long& FrameBuffer::getProgress() { return _progress; }
const long long& FrameBuffer::getRAM() { return _ram; }
const long long& FrameBuffer::getPRAM() { return _pram; }
const int& FrameBuffer::getTime() { return _time; }

// Set Arnold core version
void FrameBuffer::setArnoldVersion(const int& version)
{
    // Construct a string from the version number passed
    int archV = (version % 10000000) / 1000000;
    int majorV = (version % 1000000) / 10000;
    int minorV = (version % 10000) / 100;
    int fixV = version % 100;

    std::stringstream stream;
    stream << archV << "." << majorV << "." << minorV << "." << fixV;
    _version = stream.str();
}

// Get Arnold core version
const char* FrameBuffer::getArnoldVersion() { return _version.c_str(); }

// Set the frame number of this framebuffer
void FrameBuffer::setFrame(const double& frame) { _frame = frame; }

// Get the frame number of this framebuffer
const double& FrameBuffer::getFrame() { return _frame; }

// Check if this framebuffer is empty
bool FrameBuffer::empty() { return (_buffers.empty() && _aovs.empty()) ; }

// To keep False while writing the buffer
void FrameBuffer::ready(const bool& ready) { _ready = ready; }
const bool& FrameBuffer::isReady() { return _ready; }
<commit_msg>Code cleanup<commit_after>/*
Copyright (c) 2016,
Dan Bethell, Johannes Saam, Vahan Sosoyan, Brian Scherbinski.
All rights reserved. See COPYING.txt for more details.
*/

#include "FrameBuffer.h"
#include "boost/format.hpp"

using namespace aton;

const std::string chStr::RGBA = "RGBA",
                  chStr::rgb = "rgb",
                  chStr::depth = "depth",
                  chStr::Z = "Z",
                  chStr::N = "N",
                  chStr::P = "P",
                  chStr::_red = ".red",
                  chStr::_green = ".green",
                  chStr::_blue = ".blue",
                  chStr::_X = ".X",
                  chStr::_Y = ".Y",
                  chStr::_Z = ".Z";

// Lightweight color pixel class
RenderColor::RenderColor() { _val[0] = _val[1] = _val[2] = 0.0f; }

float& RenderColor::operator[](int i) { return _val[i]; }
const float& RenderColor::operator[](int i) const { return _val[i]; }

void RenderColor::reset() { _val[0] = _val[1] = _val[2] = 0.0f; }

// RenderBuffer class
RenderBuffer::RenderBuffer(const unsigned int& width,
                           const unsigned int& height,
                           const int& spp)
{
    int size = width * height;

    switch (spp)
    {
        case 1: // Float channels
            _float_data.resize(size);
            break;
        case 3: // Color Channels
            _color_data.resize(size);
            break;
        case 4: // Color + Alpha channels
            _color_data.resize(size);
            _float_data.resize(size);
            break;
    }
}

// FrameBuffer class
FrameBuffer::FrameBuffer(const double& currentFrame,
                         const int& w,
                         const int& h): _frame(currentFrame),
                                        _width(w),
                                        _height(h),
                                        _progress(0),
                                        _time(0),
                                        _ram(0),
                                        _pram(0),
                                        _ready(false) {}

// Add new buffer
void FrameBuffer::addBuffer(const char* aov,
                            const int& spp)
{
    RenderBuffer buffer(_width, _height, spp);

    _buffers.push_back(buffer);
    _aovs.push_back(aov);
}

// Get writable buffer object
void FrameBuffer::setBufferPix(const int& b,
                               const unsigned int& x,
                               const unsigned int& y,
                               const int& spp,
                               const int& c,
                               const float& pix)
{
    RenderBuffer& rb = _buffers[b];
    unsigned int index = (_width * y) + x;
    if (c < 3 && spp != 1)
        rb._color_data[index][c] = pix;
    else
        rb._float_data[index] = pix;
}

// Get read only buffer object
const float& FrameBuffer::getBufferPix(const int& b,
                                       const unsigned int& x,
                                       const unsigned int& y,
                                       const int& c) const
{
    const RenderBuffer& rb = _buffers[b];
    unsigned int index = (_width * y) + x;
    if (c < 3 && !rb._color_data.empty())
        return rb._color_data[index][c];
    else
        return rb._float_data[index];
}

// Get the current buffer index
int FrameBuffer::getBufferIndex(const Channel& z)
{
    int b_index = 0;
    if (_aovs.size() > 1)
    {
        using namespace chStr;
        std::string layer = getLayerName(z);

        std::vector<std::string>::iterator it;
        for(it = _aovs.begin(); it != _aovs.end(); ++it)
        {
            if (*it == layer)
            {
                b_index = static_cast<int>(it - _aovs.begin());
                break;
            }
            else if (*it == Z && layer == depth)
            {
                b_index = static_cast<int>(it - _aovs.begin());
                break;
            }
        }

    }
    return b_index;
}

// Get the current buffer index
int FrameBuffer::getBufferIndex(const char* aovName)
{
    int b_index = 0;
    if (_aovs.size() > 1)
    {
        std::vector<std::string>::iterator it;
        for(it = _aovs.begin(); it != _aovs.end(); ++it)
        {
            if (*it == aovName)
            {
                b_index = static_cast<int>(it - _aovs.begin());
                break;
            }
        }
    }
    return b_index;
}

// Get N buffer/aov name name
const char* FrameBuffer::getBufferName(const int& index)
{
    const char* aovName = "";

    if(!_aovs.empty())
        try
        {
            aovName = _aovs.at(index).c_str();
        }
        catch (const std::out_of_range& e)
		{
			(void)e;
		}
        catch (...)
        {
            std::cerr << "Unexpected error at getting buffer name" << std::endl;
        }

    return aovName;
}

// Get last buffer/aov name
bool FrameBuffer::isFirstBufferName(const char* aovName)
{
    return strcmp(_aovs.front().c_str(), aovName) == 0;;
}

// Check if Frame has been changed
bool FrameBuffer::isFrameChanged(const double& frame)
{
    return frame != _frame;
}

// Check if Aovs has been changed
bool FrameBuffer::isAovsChanged(const std::vector<std::string>& aovs)
{
    return (aovs != _aovs);
}

// Check if Resolution has been changed
bool FrameBuffer::isResolutionChanged(const unsigned int& w,
                                      const unsigned int& h)
{
    return (w != _width && h != _height);
}

// Resize the containers to match the resolution
void FrameBuffer::setResolution(const unsigned int& w,
                                const unsigned int& h)
{
    _width = w;
    _height = h;

    int bfSize = _width * _height;

    std::vector<RenderBuffer>::iterator iRB;
    for(iRB = _buffers.begin(); iRB != _buffers.end(); ++iRB)
    {
        if (!iRB->_color_data.empty())
        {
            RenderColor color;
            std::fill(iRB->_color_data.begin(), iRB->_color_data.end(), color);
            iRB->_color_data.resize(bfSize);
        }
        if (!iRB->_float_data.empty())
        {
            std::fill(iRB->_float_data.begin(), iRB->_float_data.end(), 0.0f);
            iRB->_float_data.resize(bfSize);
        }
    }
}

// Clear buffers and aovs
void FrameBuffer::clearAll()
{
    _buffers = std::vector<RenderBuffer>();
    _aovs = std::vector<std::string>();
}

// Check if the given buffer/aov name name is exist
bool FrameBuffer::isBufferExist(const char* aovName)
{
    return std::find(_aovs.begin(), _aovs.end(), aovName) != _aovs.end();
}

// Get width of the buffer
const int& FrameBuffer::getWidth() { return _width; }

// Get height of the buffer
const int& FrameBuffer::getHeight() { return _height; }

// Get size of the buffers aka AOVs count
size_t FrameBuffer::size() { return _aovs.size(); }

// Resize the buffers
void FrameBuffer::resize(const size_t& s)
{
    _buffers.resize(s);
    _aovs.resize(s);
}

// Set status parameters
void FrameBuffer::setProgress(const long long& progress)
{
    _progress = progress > 100 ? 100 : progress;
}

void FrameBuffer::setRAM(const long long& ram)
{
    int ramGb = static_cast<int>(ram / 1048576);
    _ram = ramGb;
    _pram = ramGb > _pram ? ramGb : _pram;

}
void FrameBuffer::setTime(const int& time,
                          const int& dtime)
{
    _time = dtime > time ? time : time - dtime;
}

// Get status parameters
const long long& FrameBuffer::getProgress() { return _progress; }
const long long& FrameBuffer::getRAM() { return _ram; }
const long long& FrameBuffer::getPRAM() { return _pram; }
const int& FrameBuffer::getTime() { return _time; }

// Set Arnold core version
void FrameBuffer::setArnoldVersion(const int& version)
{
    // Construct a string from the version number passed
    int archV = (version % 10000000) / 1000000;
    int majorV = (version % 1000000) / 10000;
    int minorV = (version % 10000) / 100;
    int fixV = version % 100;

    std::stringstream stream;
    stream << archV << "." << majorV << "." << minorV << "." << fixV;
    _version = stream.str();
}

// Get Arnold core version
const char* FrameBuffer::getArnoldVersion() { return _version.c_str(); }

// Set the frame number of this framebuffer
void FrameBuffer::setFrame(const double& frame) { _frame = frame; }

// Get the frame number of this framebuffer
const double& FrameBuffer::getFrame() { return _frame; }

// Check if this framebuffer is empty
bool FrameBuffer::empty() { return (_buffers.empty() && _aovs.empty()) ; }

// To keep False while writing the buffer
void FrameBuffer::ready(const bool& ready) { _ready = ready; }
const bool& FrameBuffer::isReady() { return _ready; }
<|endoftext|>


<commit_before>/****************************************************************************
** libmatroska : parse Matroska files, see http://www.matroska.org/
**
** <file/class description>
**
** Copyright (C) 2002-2010 Steve Lhomme.  All rights reserved.
**
** This file is part of libmatroska.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License as published by the Free Software Foundation; either
** version 2.1 of the License, or (at your option) any later version.
**
** This library is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
** Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public
** License along with this library; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
**
** See http://www.matroska.org/license/lgpl/ for LGPL licensing information.**
** Contact license@matroska.org if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/

/*!
	\file
	\version \$Id: KaxTagMulti.cpp 640 2004-07-09 21:05:36Z mosu $
	\author Jory Stone       <jcsston @ toughguy.net>
	\author Steve Lhomme     <robux4 @ users.sf.net>
*/
#include "matroska/KaxTagMulti.h"
#include "matroska/KaxContexts.h"
#include "matroska/KaxDefines.h"

using namespace LIBEBML_NAMESPACE;

START_LIBMATROSKA_NAMESPACE

DEFINE_START_SEMANTIC(KaxTagMultiGlobal)
DEFINE_SEMANTIC_ITEM(false, false, KaxTagMultiComment)
DEFINE_END_SEMANTIC(KaxTagMultiGlobal)

DEFINE_START_SEMANTIC(KaxTagMultiComment)
DEFINE_SEMANTIC_ITEM(false, true, KaxTagMultiCommentName)
DEFINE_SEMANTIC_ITEM(false, true, KaxTagMultiCommentComments)
DEFINE_SEMANTIC_ITEM(false, true, KaxTagMultiCommentLanguage)
DEFINE_END_SEMANTIC(KaxTagMultiComment)

DEFINE_START_SEMANTIC(KaxTagMultiCommercial)
DEFINE_SEMANTIC_ITEM(true, false, KaxTagCommercial)
DEFINE_END_SEMANTIC(KaxTagMultiCommercial)

DEFINE_START_SEMANTIC(KaxTagCommercial)
DEFINE_SEMANTIC_ITEM(true, true, KaxTagMultiCommercialType)
DEFINE_SEMANTIC_ITEM(false, true, KaxTagMultiCommercialAddress)
DEFINE_SEMANTIC_ITEM(false, false, KaxTagMultiCommercialURL)
DEFINE_SEMANTIC_ITEM(false, false, KaxTagMultiCommercialEmail)
DEFINE_SEMANTIC_ITEM(false, false, KaxTagMultiPrice)
DEFINE_END_SEMANTIC(KaxTagCommercial)

DEFINE_START_SEMANTIC(KaxTagMultiPrice)
DEFINE_SEMANTIC_ITEM(false, true, KaxTagMultiPriceCurrency)
DEFINE_SEMANTIC_ITEM(false, true, KaxTagMultiPriceAmount)
DEFINE_SEMANTIC_ITEM(false, true, KaxTagMultiPricePriceDate)
DEFINE_END_SEMANTIC(KaxTagMultiPrice)

DEFINE_START_SEMANTIC(KaxTagMultiDate)
DEFINE_SEMANTIC_ITEM(true, false, KaxTagDate)
DEFINE_END_SEMANTIC(KaxTagMultiDate)

DEFINE_START_SEMANTIC(KaxTagDate)
DEFINE_SEMANTIC_ITEM(true, true, KaxTagMultiDateType)
DEFINE_SEMANTIC_ITEM(false, true, KaxTagMultiDateDateBegin)
DEFINE_SEMANTIC_ITEM(false, true, KaxTagMultiDateDateEnd)
DEFINE_END_SEMANTIC(KaxTagDate)

DEFINE_START_SEMANTIC(KaxTagMultiEntity)
DEFINE_SEMANTIC_ITEM(true, false, KaxTagEntity)
DEFINE_END_SEMANTIC(KaxTagMultiEntity)

DEFINE_START_SEMANTIC(KaxTagEntity)
DEFINE_SEMANTIC_ITEM(true, true, KaxTagMultiEntityType)
DEFINE_SEMANTIC_ITEM(false, true, KaxTagMultiEntityName)
DEFINE_SEMANTIC_ITEM(false, false, KaxTagMultiEntityURL)
DEFINE_SEMANTIC_ITEM(false, false, KaxTagMultiEntityEmail)
DEFINE_SEMANTIC_ITEM(false, true, KaxTagMultiEntityAddress)
DEFINE_END_SEMANTIC(KaxTagEntity)

DEFINE_START_SEMANTIC(KaxTagMultiIdentifier)
DEFINE_SEMANTIC_ITEM(true, false, KaxTagIdentifier)
DEFINE_END_SEMANTIC(KaxTagMultiIdentifier)

DEFINE_START_SEMANTIC(KaxTagIdentifier)
DEFINE_SEMANTIC_ITEM(true, true, KaxTagMultiIdentifierType)
DEFINE_SEMANTIC_ITEM(false, true, KaxTagMultiIdentifierBinary)
DEFINE_SEMANTIC_ITEM(false, true, KaxTagMultiIdentifierString)
DEFINE_END_SEMANTIC(KaxTagIdentifier)

DEFINE_START_SEMANTIC(KaxTagMultiLegal)
DEFINE_SEMANTIC_ITEM(true, false, KaxTagLegal)
DEFINE_END_SEMANTIC(KaxTagMultiLegal)

DEFINE_START_SEMANTIC(KaxTagLegal)
DEFINE_SEMANTIC_ITEM(true, true, KaxTagMultiLegalType)
DEFINE_SEMANTIC_ITEM(false, true, KaxTagMultiLegalContent)
DEFINE_SEMANTIC_ITEM(false, false, KaxTagMultiLegalURL)
DEFINE_SEMANTIC_ITEM(false, true, KaxTagMultiLegalAddress)
DEFINE_END_SEMANTIC(KaxTagLegal)

DEFINE_START_SEMANTIC(KaxTagMultiTitle)
DEFINE_SEMANTIC_ITEM(true, false, KaxTagTitle)
DEFINE_END_SEMANTIC(KaxTagMultiTitle)

DEFINE_START_SEMANTIC(KaxTagTitle)
DEFINE_SEMANTIC_ITEM(true, true, KaxTagMultiTitleType)
DEFINE_SEMANTIC_ITEM(false, true, KaxTagMultiTitleName)
DEFINE_SEMANTIC_ITEM(false, true, KaxTagMultiTitleSubTitle)
DEFINE_SEMANTIC_ITEM(false, true, KaxTagMultiTitleEdition)
DEFINE_SEMANTIC_ITEM(false, true, KaxTagMultiTitleAddress)
DEFINE_SEMANTIC_ITEM(false, false, KaxTagMultiTitleURL)
DEFINE_SEMANTIC_ITEM(false, false, KaxTagMultiTitleEmail)
DEFINE_SEMANTIC_ITEM(false, true, KaxTagMultiTitleLanguage)
DEFINE_END_SEMANTIC(KaxTagTitle)

DEFINE_START_SEMANTIC(KaxTagMultiAttachment)
DEFINE_SEMANTIC_ITEM(true, false, KaxTagAttachment)
DEFINE_END_SEMANTIC(KaxTagMultiAttachment)

DEFINE_START_SEMANTIC(KaxTagAttachment)
DEFINE_SEMANTIC_ITEM(false, true, KaxTagAttachmentID)
DEFINE_END_SEMANTIC(KaxTagAttachment)

DEFINE_MKX_CONTEXT(KaxTagMultiGlobal);

const EbmlSemanticContext & GetKaxTagsGlobal_Context()
{
	return Context_KaxTagMultiGlobal;
}

#define DEFINE_TAG_MASTER(a,b,c,d,e)   DEFINE_xxx_MASTER(a,b,c,d,e,*GetKaxTagsGlobal_Context)

DEFINE_MKX_MASTER   (KaxTagMultiComment,           0x5B7B, 2, KaxTag, "MultiComment");
DEFINE_MKX_STRING   (KaxTagMultiCommentName,       0x5F7D, 2, KaxTagMultiComment, "MultiCommentName");
DEFINE_MKX_UNISTRING(KaxTagMultiCommentComments,   0x5F7C, 2, KaxTagMultiComment, "MultiCommentComments");
DEFINE_MKX_STRING   (KaxTagMultiCommentLanguage, 0x22B59D, 3, KaxTagMultiComment, "MultiCommentLanguage");

DEFINE_TAG_MASTER   (KaxTagMultiCommercial,        0x4DC7, 2, KaxTag, "MultiCommercial");
DEFINE_TAG_MASTER   (KaxTagCommercial,             0x4EC7, 2, KaxTagMultiCommercial, "Commercial");
DEFINE_MKX_UINTEGER (KaxTagMultiCommercialType,    0x5BD7, 2, KaxTagCommercial, "MultiCommercialType");
DEFINE_MKX_UNISTRING(KaxTagMultiCommercialAddress, 0x5BBB, 2, KaxTagCommercial, "MultiCommercialAddress");
DEFINE_MKX_STRING   (KaxTagMultiCommercialURL,     0x5BDA, 2, KaxTagCommercial, "MultiCommercialURL");
DEFINE_MKX_STRING   (KaxTagMultiCommercialEmail,   0x5BC0, 2, KaxTagCommercial, "MultiCommercialEmail");
DEFINE_TAG_MASTER   (KaxTagMultiPrice,             0x5BC3, 2, KaxTagCommercial, "MultiPrice");
DEFINE_MKX_STRING   (KaxTagMultiPriceCurrency,     0x5B6C, 2, KaxTagMultiPrice, "MultiPriceCurrency");
DEFINE_MKX_FLOAT    (KaxTagMultiPriceAmount,       0x5B6E, 2, KaxTagMultiPrice, "MultiPriceAmount");
DEFINE_MKX_DATE     (KaxTagMultiPricePriceDate,    0x5B6F, 2, KaxTagMultiPrice, "MultiPricePriceDate");

DEFINE_TAG_MASTER   (KaxTagMultiDate,              0x4DC8, 2, KaxTag, "MultiDate");
DEFINE_TAG_MASTER   (KaxTagDate,                   0x4EC8, 2, KaxTagMultiDate, "Date");
DEFINE_MKX_UINTEGER (KaxTagMultiDateType,          0x5BD8, 2, KaxTagDate, "MultiDateType");
DEFINE_MKX_DATE     (KaxTagMultiDateDateBegin,     0x4460, 2, KaxTagDate, "MultiDateDateBegin");
DEFINE_MKX_DATE     (KaxTagMultiDateDateEnd,       0x4462, 2, KaxTagDate, "MultiDateDateEnd");

DEFINE_TAG_MASTER   (KaxTagMultiEntity,            0x4DC9, 2, KaxTag, "MultiEntity");
DEFINE_TAG_MASTER   (KaxTagEntity,                 0x4EC9, 2, KaxTagMultiEntity, "Entity");
DEFINE_MKX_UINTEGER (KaxTagMultiEntityType,        0x5BD9, 2, KaxTagEntity, "MultiEntityType");
DEFINE_MKX_UNISTRING(KaxTagMultiEntityName,        0x5BED, 2, KaxTagEntity, "MultiEntityName");
DEFINE_MKX_STRING   (KaxTagMultiEntityURL,         0x5BDB, 2, KaxTagEntity, "MultiEntityURL");
DEFINE_MKX_STRING   (KaxTagMultiEntityEmail,       0x5BC1, 2, KaxTagEntity, "MultiEntityEmail");
DEFINE_MKX_UNISTRING(KaxTagMultiEntityAddress,     0x5BDC, 2, KaxTagEntity, "MultiEntityAddress");

DEFINE_TAG_MASTER   (KaxTagMultiIdentifier,        0x4DC6, 2, KaxTag, "MultiIdentifier");
DEFINE_TAG_MASTER   (KaxTagIdentifier,             0x4EC6, 2, KaxTagMultiIdentifier, "Identifier");
DEFINE_MKX_UINTEGER (KaxTagMultiIdentifierType,    0x5BAD, 2, KaxTagIdentifier, "MultiIdentifierType");
DEFINE_MKX_BINARY   (KaxTagMultiIdentifierBinary,  0x6B67, 2, KaxTagIdentifier, "MultiIdentifierBinary");
DEFINE_MKX_UNISTRING(KaxTagMultiIdentifierString,  0x6B68, 2, KaxTagIdentifier, "MultiIdentifierString");

DEFINE_TAG_MASTER   (KaxTagMultiLegal,             0x4DC5, 2, KaxTag, "MultiLegal");
DEFINE_TAG_MASTER   (KaxTagLegal,                  0x4EC5, 2, KaxTagMultiLegal, "Legal");
DEFINE_MKX_UINTEGER (KaxTagMultiLegalType,         0x5BBD, 2, KaxTagLegal, "MultiLegalType");
DEFINE_MKX_UNISTRING(KaxTagMultiLegalContent,      0x5BB2, 2, KaxTagLegal, "MultiLegalContent");
DEFINE_MKX_STRING   (KaxTagMultiLegalURL,          0x5B34, 2, KaxTagLegal, "MultiLegalURL");
DEFINE_MKX_UNISTRING(KaxTagMultiLegalAddress,      0x5B9B, 2, KaxTagLegal, "MultiLegalAddress");

DEFINE_TAG_MASTER   (KaxTagMultiTitle,             0x4DC4, 2, KaxTag, "MultiTitle");
DEFINE_TAG_MASTER   (KaxTagTitle,                  0x4EC4, 2, KaxTagMultiTitle, "Title");
DEFINE_MKX_UINTEGER (KaxTagMultiTitleType,         0x5B7D, 2, KaxTagTitle, "MultiTitleType");
DEFINE_MKX_UNISTRING(KaxTagMultiTitleName,         0x5BB9, 2, KaxTagTitle, "MultiTitleName");
DEFINE_MKX_UNISTRING(KaxTagMultiTitleSubTitle,     0x5B5B, 2, KaxTagTitle, "MultiTitleSubTitle");
DEFINE_MKX_UNISTRING(KaxTagMultiTitleEdition,      0x5BAE, 2, KaxTagTitle, "MultiTitleEdition");
DEFINE_MKX_UNISTRING(KaxTagMultiTitleAddress,      0x5B33, 2, KaxTagTitle, "MultiTitleAddress");
DEFINE_MKX_STRING   (KaxTagMultiTitleURL,          0x5BA9, 2, KaxTagTitle, "MultiTitleURL");
DEFINE_MKX_STRING   (KaxTagMultiTitleEmail,        0x5BC9, 2, KaxTagTitle, "MultiTitleEmail");
DEFINE_MKX_STRING   (KaxTagMultiTitleLanguage,   0x22B59E, 3, KaxTagTitle, "MultiTitleLanguage");

DEFINE_TAG_MASTER   (KaxTagMultiAttachment,        0x4DC3, 2, KaxTag, "MultiAttachment");
DEFINE_TAG_MASTER   (KaxTagAttachment,             0x4EC3, 2, KaxTagMultiAttachment, "Attachment");
DEFINE_MKX_UINTEGER (KaxTagAttachmentID,           0x5BA0, 2, KaxTagAttachment, "AttachmentID");

END_LIBMATROSKA_NAMESPACE
<commit_msg>add EBML_CLASS_SEMCONTEXT() for a more generic way to describe a global context callback<commit_after>/****************************************************************************
** libmatroska : parse Matroska files, see http://www.matroska.org/
**
** <file/class description>
**
** Copyright (C) 2002-2010 Steve Lhomme.  All rights reserved.
**
** This file is part of libmatroska.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License as published by the Free Software Foundation; either
** version 2.1 of the License, or (at your option) any later version.
**
** This library is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
** Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public
** License along with this library; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
**
** See http://www.matroska.org/license/lgpl/ for LGPL licensing information.**
** Contact license@matroska.org if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/

/*!
	\file
	\version \$Id: KaxTagMulti.cpp 640 2004-07-09 21:05:36Z mosu $
	\author Jory Stone       <jcsston @ toughguy.net>
	\author Steve Lhomme     <robux4 @ users.sf.net>
*/
#include "matroska/KaxTagMulti.h"
#include "matroska/KaxContexts.h"
#include "matroska/KaxDefines.h"

using namespace LIBEBML_NAMESPACE;

START_LIBMATROSKA_NAMESPACE

DEFINE_START_SEMANTIC(KaxTagMultiGlobal)
DEFINE_SEMANTIC_ITEM(false, false, KaxTagMultiComment)
DEFINE_END_SEMANTIC(KaxTagMultiGlobal)

DEFINE_START_SEMANTIC(KaxTagMultiComment)
DEFINE_SEMANTIC_ITEM(false, true, KaxTagMultiCommentName)
DEFINE_SEMANTIC_ITEM(false, true, KaxTagMultiCommentComments)
DEFINE_SEMANTIC_ITEM(false, true, KaxTagMultiCommentLanguage)
DEFINE_END_SEMANTIC(KaxTagMultiComment)

DEFINE_START_SEMANTIC(KaxTagMultiCommercial)
DEFINE_SEMANTIC_ITEM(true, false, KaxTagCommercial)
DEFINE_END_SEMANTIC(KaxTagMultiCommercial)

DEFINE_START_SEMANTIC(KaxTagCommercial)
DEFINE_SEMANTIC_ITEM(true, true, KaxTagMultiCommercialType)
DEFINE_SEMANTIC_ITEM(false, true, KaxTagMultiCommercialAddress)
DEFINE_SEMANTIC_ITEM(false, false, KaxTagMultiCommercialURL)
DEFINE_SEMANTIC_ITEM(false, false, KaxTagMultiCommercialEmail)
DEFINE_SEMANTIC_ITEM(false, false, KaxTagMultiPrice)
DEFINE_END_SEMANTIC(KaxTagCommercial)

DEFINE_START_SEMANTIC(KaxTagMultiPrice)
DEFINE_SEMANTIC_ITEM(false, true, KaxTagMultiPriceCurrency)
DEFINE_SEMANTIC_ITEM(false, true, KaxTagMultiPriceAmount)
DEFINE_SEMANTIC_ITEM(false, true, KaxTagMultiPricePriceDate)
DEFINE_END_SEMANTIC(KaxTagMultiPrice)

DEFINE_START_SEMANTIC(KaxTagMultiDate)
DEFINE_SEMANTIC_ITEM(true, false, KaxTagDate)
DEFINE_END_SEMANTIC(KaxTagMultiDate)

DEFINE_START_SEMANTIC(KaxTagDate)
DEFINE_SEMANTIC_ITEM(true, true, KaxTagMultiDateType)
DEFINE_SEMANTIC_ITEM(false, true, KaxTagMultiDateDateBegin)
DEFINE_SEMANTIC_ITEM(false, true, KaxTagMultiDateDateEnd)
DEFINE_END_SEMANTIC(KaxTagDate)

DEFINE_START_SEMANTIC(KaxTagMultiEntity)
DEFINE_SEMANTIC_ITEM(true, false, KaxTagEntity)
DEFINE_END_SEMANTIC(KaxTagMultiEntity)

DEFINE_START_SEMANTIC(KaxTagEntity)
DEFINE_SEMANTIC_ITEM(true, true, KaxTagMultiEntityType)
DEFINE_SEMANTIC_ITEM(false, true, KaxTagMultiEntityName)
DEFINE_SEMANTIC_ITEM(false, false, KaxTagMultiEntityURL)
DEFINE_SEMANTIC_ITEM(false, false, KaxTagMultiEntityEmail)
DEFINE_SEMANTIC_ITEM(false, true, KaxTagMultiEntityAddress)
DEFINE_END_SEMANTIC(KaxTagEntity)

DEFINE_START_SEMANTIC(KaxTagMultiIdentifier)
DEFINE_SEMANTIC_ITEM(true, false, KaxTagIdentifier)
DEFINE_END_SEMANTIC(KaxTagMultiIdentifier)

DEFINE_START_SEMANTIC(KaxTagIdentifier)
DEFINE_SEMANTIC_ITEM(true, true, KaxTagMultiIdentifierType)
DEFINE_SEMANTIC_ITEM(false, true, KaxTagMultiIdentifierBinary)
DEFINE_SEMANTIC_ITEM(false, true, KaxTagMultiIdentifierString)
DEFINE_END_SEMANTIC(KaxTagIdentifier)

DEFINE_START_SEMANTIC(KaxTagMultiLegal)
DEFINE_SEMANTIC_ITEM(true, false, KaxTagLegal)
DEFINE_END_SEMANTIC(KaxTagMultiLegal)

DEFINE_START_SEMANTIC(KaxTagLegal)
DEFINE_SEMANTIC_ITEM(true, true, KaxTagMultiLegalType)
DEFINE_SEMANTIC_ITEM(false, true, KaxTagMultiLegalContent)
DEFINE_SEMANTIC_ITEM(false, false, KaxTagMultiLegalURL)
DEFINE_SEMANTIC_ITEM(false, true, KaxTagMultiLegalAddress)
DEFINE_END_SEMANTIC(KaxTagLegal)

DEFINE_START_SEMANTIC(KaxTagMultiTitle)
DEFINE_SEMANTIC_ITEM(true, false, KaxTagTitle)
DEFINE_END_SEMANTIC(KaxTagMultiTitle)

DEFINE_START_SEMANTIC(KaxTagTitle)
DEFINE_SEMANTIC_ITEM(true, true, KaxTagMultiTitleType)
DEFINE_SEMANTIC_ITEM(false, true, KaxTagMultiTitleName)
DEFINE_SEMANTIC_ITEM(false, true, KaxTagMultiTitleSubTitle)
DEFINE_SEMANTIC_ITEM(false, true, KaxTagMultiTitleEdition)
DEFINE_SEMANTIC_ITEM(false, true, KaxTagMultiTitleAddress)
DEFINE_SEMANTIC_ITEM(false, false, KaxTagMultiTitleURL)
DEFINE_SEMANTIC_ITEM(false, false, KaxTagMultiTitleEmail)
DEFINE_SEMANTIC_ITEM(false, true, KaxTagMultiTitleLanguage)
DEFINE_END_SEMANTIC(KaxTagTitle)

DEFINE_START_SEMANTIC(KaxTagMultiAttachment)
DEFINE_SEMANTIC_ITEM(true, false, KaxTagAttachment)
DEFINE_END_SEMANTIC(KaxTagMultiAttachment)

DEFINE_START_SEMANTIC(KaxTagAttachment)
DEFINE_SEMANTIC_ITEM(false, true, KaxTagAttachmentID)
DEFINE_END_SEMANTIC(KaxTagAttachment)

DEFINE_MKX_CONTEXT(KaxTagMultiGlobal);

const EbmlSemanticContext & GetKaxTagsGlobal_Context()
{
    return EBML_CLASS_SEMCONTEXT(KaxTagMultiGlobal);
}

#define DEFINE_TAG_MASTER(a,b,c,d,e)   DEFINE_xxx_MASTER(a,b,c,d,e,*GetKaxTagsGlobal_Context)

DEFINE_MKX_MASTER   (KaxTagMultiComment,           0x5B7B, 2, KaxTag, "MultiComment");
DEFINE_MKX_STRING   (KaxTagMultiCommentName,       0x5F7D, 2, KaxTagMultiComment, "MultiCommentName");
DEFINE_MKX_UNISTRING(KaxTagMultiCommentComments,   0x5F7C, 2, KaxTagMultiComment, "MultiCommentComments");
DEFINE_MKX_STRING   (KaxTagMultiCommentLanguage, 0x22B59D, 3, KaxTagMultiComment, "MultiCommentLanguage");

DEFINE_TAG_MASTER   (KaxTagMultiCommercial,        0x4DC7, 2, KaxTag, "MultiCommercial");
DEFINE_TAG_MASTER   (KaxTagCommercial,             0x4EC7, 2, KaxTagMultiCommercial, "Commercial");
DEFINE_MKX_UINTEGER (KaxTagMultiCommercialType,    0x5BD7, 2, KaxTagCommercial, "MultiCommercialType");
DEFINE_MKX_UNISTRING(KaxTagMultiCommercialAddress, 0x5BBB, 2, KaxTagCommercial, "MultiCommercialAddress");
DEFINE_MKX_STRING   (KaxTagMultiCommercialURL,     0x5BDA, 2, KaxTagCommercial, "MultiCommercialURL");
DEFINE_MKX_STRING   (KaxTagMultiCommercialEmail,   0x5BC0, 2, KaxTagCommercial, "MultiCommercialEmail");
DEFINE_TAG_MASTER   (KaxTagMultiPrice,             0x5BC3, 2, KaxTagCommercial, "MultiPrice");
DEFINE_MKX_STRING   (KaxTagMultiPriceCurrency,     0x5B6C, 2, KaxTagMultiPrice, "MultiPriceCurrency");
DEFINE_MKX_FLOAT    (KaxTagMultiPriceAmount,       0x5B6E, 2, KaxTagMultiPrice, "MultiPriceAmount");
DEFINE_MKX_DATE     (KaxTagMultiPricePriceDate,    0x5B6F, 2, KaxTagMultiPrice, "MultiPricePriceDate");

DEFINE_TAG_MASTER   (KaxTagMultiDate,              0x4DC8, 2, KaxTag, "MultiDate");
DEFINE_TAG_MASTER   (KaxTagDate,                   0x4EC8, 2, KaxTagMultiDate, "Date");
DEFINE_MKX_UINTEGER (KaxTagMultiDateType,          0x5BD8, 2, KaxTagDate, "MultiDateType");
DEFINE_MKX_DATE     (KaxTagMultiDateDateBegin,     0x4460, 2, KaxTagDate, "MultiDateDateBegin");
DEFINE_MKX_DATE     (KaxTagMultiDateDateEnd,       0x4462, 2, KaxTagDate, "MultiDateDateEnd");

DEFINE_TAG_MASTER   (KaxTagMultiEntity,            0x4DC9, 2, KaxTag, "MultiEntity");
DEFINE_TAG_MASTER   (KaxTagEntity,                 0x4EC9, 2, KaxTagMultiEntity, "Entity");
DEFINE_MKX_UINTEGER (KaxTagMultiEntityType,        0x5BD9, 2, KaxTagEntity, "MultiEntityType");
DEFINE_MKX_UNISTRING(KaxTagMultiEntityName,        0x5BED, 2, KaxTagEntity, "MultiEntityName");
DEFINE_MKX_STRING   (KaxTagMultiEntityURL,         0x5BDB, 2, KaxTagEntity, "MultiEntityURL");
DEFINE_MKX_STRING   (KaxTagMultiEntityEmail,       0x5BC1, 2, KaxTagEntity, "MultiEntityEmail");
DEFINE_MKX_UNISTRING(KaxTagMultiEntityAddress,     0x5BDC, 2, KaxTagEntity, "MultiEntityAddress");

DEFINE_TAG_MASTER   (KaxTagMultiIdentifier,        0x4DC6, 2, KaxTag, "MultiIdentifier");
DEFINE_TAG_MASTER   (KaxTagIdentifier,             0x4EC6, 2, KaxTagMultiIdentifier, "Identifier");
DEFINE_MKX_UINTEGER (KaxTagMultiIdentifierType,    0x5BAD, 2, KaxTagIdentifier, "MultiIdentifierType");
DEFINE_MKX_BINARY   (KaxTagMultiIdentifierBinary,  0x6B67, 2, KaxTagIdentifier, "MultiIdentifierBinary");
DEFINE_MKX_UNISTRING(KaxTagMultiIdentifierString,  0x6B68, 2, KaxTagIdentifier, "MultiIdentifierString");

DEFINE_TAG_MASTER   (KaxTagMultiLegal,             0x4DC5, 2, KaxTag, "MultiLegal");
DEFINE_TAG_MASTER   (KaxTagLegal,                  0x4EC5, 2, KaxTagMultiLegal, "Legal");
DEFINE_MKX_UINTEGER (KaxTagMultiLegalType,         0x5BBD, 2, KaxTagLegal, "MultiLegalType");
DEFINE_MKX_UNISTRING(KaxTagMultiLegalContent,      0x5BB2, 2, KaxTagLegal, "MultiLegalContent");
DEFINE_MKX_STRING   (KaxTagMultiLegalURL,          0x5B34, 2, KaxTagLegal, "MultiLegalURL");
DEFINE_MKX_UNISTRING(KaxTagMultiLegalAddress,      0x5B9B, 2, KaxTagLegal, "MultiLegalAddress");

DEFINE_TAG_MASTER   (KaxTagMultiTitle,             0x4DC4, 2, KaxTag, "MultiTitle");
DEFINE_TAG_MASTER   (KaxTagTitle,                  0x4EC4, 2, KaxTagMultiTitle, "Title");
DEFINE_MKX_UINTEGER (KaxTagMultiTitleType,         0x5B7D, 2, KaxTagTitle, "MultiTitleType");
DEFINE_MKX_UNISTRING(KaxTagMultiTitleName,         0x5BB9, 2, KaxTagTitle, "MultiTitleName");
DEFINE_MKX_UNISTRING(KaxTagMultiTitleSubTitle,     0x5B5B, 2, KaxTagTitle, "MultiTitleSubTitle");
DEFINE_MKX_UNISTRING(KaxTagMultiTitleEdition,      0x5BAE, 2, KaxTagTitle, "MultiTitleEdition");
DEFINE_MKX_UNISTRING(KaxTagMultiTitleAddress,      0x5B33, 2, KaxTagTitle, "MultiTitleAddress");
DEFINE_MKX_STRING   (KaxTagMultiTitleURL,          0x5BA9, 2, KaxTagTitle, "MultiTitleURL");
DEFINE_MKX_STRING   (KaxTagMultiTitleEmail,        0x5BC9, 2, KaxTagTitle, "MultiTitleEmail");
DEFINE_MKX_STRING   (KaxTagMultiTitleLanguage,   0x22B59E, 3, KaxTagTitle, "MultiTitleLanguage");

DEFINE_TAG_MASTER   (KaxTagMultiAttachment,        0x4DC3, 2, KaxTag, "MultiAttachment");
DEFINE_TAG_MASTER   (KaxTagAttachment,             0x4EC3, 2, KaxTagMultiAttachment, "Attachment");
DEFINE_MKX_UINTEGER (KaxTagAttachmentID,           0x5BA0, 2, KaxTagAttachment, "AttachmentID");

END_LIBMATROSKA_NAMESPACE
<|endoftext|>


<commit_before>/*
 * LPConverter.cpp
 *
 *  Created on: Nov 13, 2014
 *      Author: lukas
 */

#include "LPConverter.h"

#include <algorithm>
#include <iostream>
#include <fstream>
#include <sstream>
#include <stdexcept>
#include <vector>

namespace ls2
{

LPConverter::LPConverter()
{
}

LPConverter::~LPConverter()
{
}

void LPConverter::convertToLP(const std::string &inputFile, const char delimiter, int k, const std::string &outputFile)
{
    DoubleMat inputPointsMatrix;
    file2DoubleMat(inputFile, delimiter).swap(inputPointsMatrix);
    DoubleMat costs;
    calculateLPCosts(inputPointsMatrix).swap(costs);

    std::ofstream os;
    os.open(outputFile.c_str());

    if (os.fail())
    {
        throw std::invalid_argument("File " + outputFile + " cannot be opened or created!");
    }
    if (!os.is_open())
    {
        throw std::invalid_argument("File " + outputFile + " cannot be opened or created!");
    }

    std::cout << "Writing results to " << outputFile.c_str() << "..." << std::endl;
    writeLPToFile(os, costs, k);

    os.close();
}

DoubleMat LPConverter::calculateLPCosts(const DoubleMat& inputPoints)
{
	int n = inputPoints.size();

    std::cout <<  "N: " << n << std::endl;

	DoubleMat costs(n, std::vector<double>(n, 0));

	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n; j++)
		{
			costs[i][j] = squaredEuclideanDistance(inputPoints[i], inputPoints[j]);
		}
	}

	return costs;
}

void LPConverter::writeLPToFile(std::ofstream& os, const DoubleMat& costs, int k)
{
    int n = costs[0].size();

    // header
    os << "Minimize" << std::endl;
    os << "kmedian_2approximation:" << std::endl;

    // target function: sum c_ij*x_ij
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            os << costs[i][j] << "xi" << i << "j" << j;

            if ( (i == n-1) && (j == n-1) )
            {
                break;
            }

            os << " + ";
        }
    }
    os << std::endl;

    // restrictions header
    os << "Subject to" << std::endl;

    // restrictions: each city connected to at least one facility: foreach j in C sum x_ij >= 1
    for (int j = 0; j < n; j++)
    {
        os << "City_" << j << "_connected: ";
        for (int i = 0; i < n; i++)
        {
            os << "xi" << i << "" << "j" << j;

            if (i != n-1)
            {
                os << " + ";
            }
            else
            {
                os << " >= 1";
            }
        }
        os << std::endl;
    }

    // restrictions: connected facilities must be open: foreach i in F, j in C y_i - x_ij >= 0
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            os << "Facility_" << i << "_open_rsp_city_" << j << ": " << "yi" <<  i << " - " << "xi" << i << "j" << j << " >= 0" << std::endl;
        }
    }

    // restrictions: exactly k facilities are opened: sum -y_i >= -k
    os << "Exactly_k_facilities_opened: ";
    for (int i = 0; i < n-1; i++)
    {
        os << "-yi" << i << " + ";
    }
    os << "yi" << n-1;
    os << " >= " << "-" << k << std::endl;

    // relaxed ILP-restrictions i.e. non-negativity: foreach i in F, j in C x_ij >= 0
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            os << "xi" << i << "j" << j << " >= 0" << std::endl;
        }
    }
    // foreach i in F y_i >= 0
    for (int i = 0; i < n; i++)
    {
        os << "yi" << i << " >= 0" << std::endl;
    }

    // footer
    os << "End" << std::endl;
}

DoubleMat LPConverter::file2DoubleMat(const std::string &file, const char delimiter)
{
	std::ifstream is(file.c_str());

	if (is.fail())
	{
		throw std::invalid_argument("File " + file + " does not exist or cannot be opened!");
	}

	if (!is.is_open())
	{
		throw std::invalid_argument("File " + file + " does not exist or cannot be opened!");
	}

	DoubleMat doubleMat(0, std::vector<double>(0, 0));
	doubleMat.clear();

	std::string line;
	while (std::getline(is, line))
	{
		DoubleVec row(0);

		std::stringstream linestream(line);
		std::string value;
		while (std::getline(linestream, value, delimiter))
		{
			row.push_back(string2double(value));
		}
		doubleMat.push_back(row);
	}

	is.close();

	return doubleMat;
}

double LPConverter::string2double(const std::string &s)
{
	std::istringstream i(s);
	double x;

	if (!(i >> x))
		return 0;
	return x;
}

double LPConverter::squaredEuclideanDistance(const DoubleVec& v1, const DoubleVec& v2)
{
    if (v1.size() != v2.size())
    {
        throw std::invalid_argument("Euclidean distance can only be calculated for vectors of equal dimension!");
    }

    int dim = v1.size();
    double distance = 0.0;

    for (int i = 0; i < dim; i++)
    {
        distance += ( (v1[i] - v2[i]) * (v1[i] - v2[i]));
    }

    return distance;
}

} /* namespace ls2 */
<commit_msg>Ensure costs are always printed fixed and not in scientifc notation.<commit_after>/*
 * LPConverter.cpp
 *
 *  Created on: Nov 13, 2014
 *      Author: lukas
 */

#include "LPConverter.h"

#include <algorithm>
#include <iostream>
#include <fstream>
#include <sstream>
#include <stdexcept>
#include <vector>

namespace ls2
{

LPConverter::LPConverter()
{
}

LPConverter::~LPConverter()
{
}

void LPConverter::convertToLP(const std::string &inputFile, const char delimiter, int k, const std::string &outputFile)
{
    DoubleMat inputPointsMatrix;
    file2DoubleMat(inputFile, delimiter).swap(inputPointsMatrix);
    DoubleMat costs;
    calculateLPCosts(inputPointsMatrix).swap(costs);

    std::ofstream os;
    os.open(outputFile.c_str());

    if (os.fail())
    {
        throw std::invalid_argument("File " + outputFile + " cannot be opened or created!");
    }
    if (!os.is_open())
    {
        throw std::invalid_argument("File " + outputFile + " cannot be opened or created!");
    }

    std::cout << "Writing results to " << outputFile.c_str() << "..." << std::endl;
    writeLPToFile(os, costs, k);

    os.close();
}

DoubleMat LPConverter::calculateLPCosts(const DoubleMat& inputPoints)
{
    int n = inputPoints.size();

    std::cout <<  "N: " << n << std::endl;

    DoubleMat costs(n, std::vector<double>(n, 0));

    for (int i = 0; i < n; i++)
    {
	    for (int j = 0; j < n; j++)
	    {
		    costs[i][j] = squaredEuclideanDistance(inputPoints[i], inputPoints[j]);
	    }
    }

    return costs;
}

void LPConverter::writeLPToFile(std::ofstream& os, const DoubleMat& costs, int k)
{
    int n = costs[0].size();

    // header
    os << "Minimize" << std::endl;
    os << "kmedian_2approximation:" << std::endl;

    // target function: sum c_ij*x_ij
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            os << std::fixed << costs[i][j] << "xi" << i << "j" << j;

            if ( (i == n-1) && (j == n-1) )
            {
                break;
            }

            os << " + ";
        }
    }
    os << std::endl;

    // restrictions header
    os << "Subject to" << std::endl;

    // restrictions: each city connected to at least one facility: foreach j in C sum x_ij >= 1
    for (int j = 0; j < n; j++)
    {
        os << "City_" << j << "_connected: ";
        for (int i = 0; i < n; i++)
        {
            os << "xi" << i << "" << "j" << j;

            if (i != n-1)
            {
                os << " + ";
            }
            else
            {
                os << " >= 1";
            }
        }
        os << std::endl;
    }

    // restrictions: connected facilities must be open: foreach i in F, j in C y_i - x_ij >= 0
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            os << "Facility_" << i << "_open_rsp_city_" << j << ": " << "yi" <<  i << " - " << "xi" << i << "j" << j << " >= 0" << std::endl;
        }
    }

    // restrictions: exactly k facilities are opened: sum -y_i >= -k
    os << "Exactly_k_facilities_opened: ";
    for (int i = 0; i < n-1; i++)
    {
        os << "-yi" << i << " + ";
    }
    os << "yi" << n-1;
    os << " >= " << "-" << k << std::endl;

    // relaxed ILP-restrictions i.e. non-negativity: foreach i in F, j in C x_ij >= 0
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            os << "xi" << i << "j" << j << " >= 0" << std::endl;
        }
    }
    // foreach i in F y_i >= 0
    for (int i = 0; i < n; i++)
    {
        os << "yi" << i << " >= 0" << std::endl;
    }

    // footer
    os << "End" << std::endl;
}

DoubleMat LPConverter::file2DoubleMat(const std::string &file, const char delimiter)
{
	std::ifstream is(file.c_str());

	if (is.fail())
	{
		throw std::invalid_argument("File " + file + " does not exist or cannot be opened!");
	}

	if (!is.is_open())
	{
		throw std::invalid_argument("File " + file + " does not exist or cannot be opened!");
	}

	DoubleMat doubleMat(0, std::vector<double>(0, 0));
	doubleMat.clear();

	std::string line;
	while (std::getline(is, line))
	{
		DoubleVec row(0);

		std::stringstream linestream(line);
		std::string value;
		while (std::getline(linestream, value, delimiter))
		{
			row.push_back(string2double(value));
		}
		doubleMat.push_back(row);
	}

	is.close();

	return doubleMat;
}

double LPConverter::string2double(const std::string &s)
{
	std::istringstream i(s);
	double x;

	if (!(i >> x))
		return 0;
	return x;
}

double LPConverter::squaredEuclideanDistance(const DoubleVec& v1, const DoubleVec& v2)
{
    if (v1.size() != v2.size())
    {
        throw std::invalid_argument("Euclidean distance can only be calculated for vectors of equal dimension!");
    }

    int dim = v1.size();
    double distance = 0.0;

    for (int i = 0; i < dim; i++)
    {
        distance += ( (v1[i] - v2[i]) * (v1[i] - v2[i]));
    }

    return distance;
}

} /* namespace ls2 */
<|endoftext|>


<commit_before>#ifndef MJOLNIR_POTENTIAL_GLOBAL_INVERSE_POWER_POTENTIAL_HPP
#define MJOLNIR_POTENTIAL_GLOBAL_INVERSE_POWER_POTENTIAL_HPP
#include <mjolnir/core/ExclusionList.hpp>
#include <mjolnir/core/System.hpp>
#include <algorithm>
#include <numeric>
#include <memory>
#include <cmath>

namespace mjolnir
{

// inverse power potential.
template<typename traitsT>
class InversePowerPotential
{
  public:

    using traits_type           = traitsT;
    using real_type             = typename traits_type::real_type;
    using integer_type          = std::int32_t;
    using parameter_type        = real_type;
    using container_type        = std::vector<parameter_type>;

    using pair_parameter_type   = parameter_type;

    // ------------------------------------------------------------------------
    // topology stuff
    using topology_type        = Topology;
    using molecule_id_type     = typename topology_type::molecule_id_type;
    using group_id_type        = typename topology_type::group_id_type;
    using connection_kind_type = typename topology_type::connection_kind_type;
    using ignore_molecule_type = IgnoreMolecule<molecule_id_type>;
    using ignore_group_type    = IgnoreGroup   <group_id_type>;
    using exclusion_list_type  = ExclusionList <traits_type>;

    static constexpr real_type default_cutoff(const integer_type n) noexcept
    {
        return std::pow(2.0, 12.0 / n);
    }
    static constexpr parameter_type default_parameter() noexcept
    {
        return parameter_type{0.0};
    }

  public:

    InversePowerPotential(const real_type eps, const integer_type n, const real_type cutoff_ratio,
        const std::vector<std::pair<std::size_t, parameter_type>>& parameters,
        const std::map<connection_kind_type, std::size_t>&         exclusions,
        ignore_molecule_type ignore_mol, ignore_group_type ignore_grp)
        :epsilon_(eps), n_(n), cutoff_ratio_(cutoff_ratio),
         coef_at_cutoff_(std::pow(1.0 / cutoff_ratio, n)),
         exclusion_list_(exclusions, std::move(ignore_mol), std::move(ignore_grp))
    {
        this->parameters_  .reserve(parameters.size());
        this->participants_.reserve(parameters.size());
        for(const auto& idxp : parameters)
        {
            const auto idx = idxp.first;
            this->participants_.push_back(idx);
            if(idx >= this->parameters_.size())
            {
                this->parameters_.resize(idx+1, default_parameter());
            }
            this->parameters_.at(idx) = idxp.second;
        }
    }
    ~InversePowerPotential() = default;
    InversePowerPotential(const InversePowerPotential&) = default;
    InversePowerPotential(InversePowerPotential&&)      = default;
    InversePowerPotential& operator=(const InversePowerPotential&) = default;
    InversePowerPotential& operator=(InversePowerPotential&&)      = default;

    // this value will be stored in NeighborList
    pair_parameter_type prepare_params(std::size_t i, std::size_t j) const noexcept
    {
        return this->parameters_[i] + this->parameters_[j];
    }

    // forwarding function for clarity
    real_type potential(const std::size_t i, const std::size_t j,
                        const real_type r) const noexcept
    {
        return this->potential(r, this->prepare_params(i, j));
    }
    real_type derivative(const std::size_t i, const std::size_t j,
                         const real_type r) const noexcept
    {
        return this->derivative(r, this->prepare_params(i, j));
    }

    real_type potential(const real_type r, const pair_parameter_type& d) const noexcept
    {
        MJOLNIR_GET_DEFAULT_LOGGER_DEBUG();
        MJOLNIR_LOG_FUNCTION_DEBUG();

        if(d * this->cutoff_ratio_ < r){return 0.0;}

        const real_type rinv = 1.0 / r;
        const real_type d_r = d * rinv;
        const real_type drn = std::pow(d_r, n_);
        return this->epsilon_ * (drn - this->coef_at_cutoff_);
    }
    real_type derivative(const real_type r, const pair_parameter_type& d) const noexcept
    {
        MJOLNIR_GET_DEFAULT_LOGGER_DEBUG();
        MJOLNIR_LOG_FUNCTION_DEBUG();

        if(d * this->cutoff_ratio_ < r){return 0.0;}

        const real_type rinv = 1.0 / r;
        const real_type d_r = d * rinv;
        const drn = std::pow(d_r, n_);
        return -n_ * this->epsilon_ * drn * rinv;
    }

    void initialize(const System<traits_type>& sys) noexcept
    {
        MJOLNIR_GET_DEFAULT_LOGGER();
        MJOLNIR_LOG_FUNCTION();

        this->update(sys);
        return;
    }

    // nothing to be done if system parameter (e.g. temperature) do not changes
    void update(const System<traits_type>& sys) noexcept
    {
        MJOLNIR_GET_DEFAULT_LOGGER();
        MJOLNIR_LOG_FUNCTION();

        // update exclusion list based on sys.topology()
        exclusion_list_.make(sys);
        return;
    }

    real_type cutoff_ratio()   const noexcept {return this->cutoff_ratio_;}
    real_type coef_at_cutoff() const noexcept {return this->coef_at_cutoff_;}

    real_type max_cutoff_length() const
    {
        const real_type max_sigma =
            * (std::max_element(parameters_.cbegin(), parameters_.cend()));
        return 2 * max_sigma * this->cutoff_ratio_;
    }

    // -----------------------------------------------------------------------
    // for spatial partitions
    //
    // Here, the default implementation uses Newton's 3rd law to reduce
    // calculation. For an interacting pair (i, j), forces applied to i and j
    // are equal in magnitude and opposite in direction. So, if a pair (i, j) is
    // listed, (j, i) is not needed.
    //     See implementation of VerletList, CellList and GlobalPairInteraction
    // for more details about the usage of these functions.

    std::vector<std::size_t> const& participants_() const noexcept {return participants_;}

    range<typename std::vector<std::size_t>::const_iterator>
    leading_participants() const noexcept
    {
        return make_range(participants_.begin(), std::prev(participants_.end()));
    }
    range<typename std::vector<std::size_t>::const_iterator>
    possible_partners_of(const std::size_t participant_idx,
                         const std::size_t /*particle_idx*/) const noexcept
    {
        return make_range(participants_.begin() + participant_idx + 1,
                          participants_.end());
    }
    bool has_interaction(const std::size_t i, const std::size_t j) const noexcept
    {
        return (i < j) && !exclusion_list_.is_excluded(i, j);
    }

    // ------------------------------------------------------------------------
    // for testing
    exclusion_list_type cosnt& exclusion_list() const noexcept
    {
        return exclusion_list_;
    }

    // ------------------------------------------------------------------------
    // used by Observer.

    static const char* name() noexcept {return "InversePower";}

    // ------------------------------------------------------------------------
    // the following accessers would be used in tests.

    real_type& epsilon()       noexcept {return this->epsilon_;}
    real_type  epsilon() const noexcept {return this->epsilon_;}
    integer_type& n()             noexcept {return this->n_;}
    integer_type  n()       const noexcept {return this->n_;}
    std::vector<real_type>&       parameters()       noexcept {return this->parameters_;}
    std::vector<real_type> const& parameters() const noexcept {return this->parameters_;}

  private:

    real_type epsilon_;
    integer_type n_;
    real_type cutoff_ratio;
    real_type coef_at_cutoff_; // correction of energy value at cutoff length
    std::vector<parameter_type> parameters_;
    std::vector<std::size_t>    participants_;

    exclusion_list_type exclusion_list_;
};
} // mjolnir

#ifdef MJOLNIR_SEPARATE_BUILD
#include <mjolnir/core/SimulatorTraits.hpp>
#include <mjolnir/core/BoundaryCondition.hpp>

namespace mjolnir
{
    extern template class InversePowerPotential<SimulatorTraits<double, UnlimitedBoundary>       >;
    extern template class InversePowerPotential<SimulatorTraits<float,  UnlimitedBoundary>       >;
    extern template class InversePowerPotential<SimulatorTraits<double, CuboidalPeriodicBoundary>>;
    extern template class InversePowerPotential<SimulatorTraits<float,  CuboidalPeriodicBoundary>>;
} // mjolnir
#endif// MJOLNIR_SEPARATE_BUILD

#endif /* MJOLNIR_EXCLUDED_VOLUME_POTENTIAL */
<commit_msg>feat: add InversePowerPotential class<commit_after>#ifndef MJOLNIR_POTENTIAL_GLOBAL_INVERSE_POWER_POTENTIAL_HPP
#define MJOLNIR_POTENTIAL_GLOBAL_INVERSE_POWER_POTENTIAL_HPP
#include <mjolnir/core/ExclusionList.hpp>
#include <mjolnir/core/System.hpp>
#include <algorithm>
#include <numeric>
#include <memory>
#include <cmath>

namespace mjolnir
{

// inverse power potential.
template<typename traitsT>
class InversePowerPotential
{
  public:

    using traits_type           = traitsT;
    using real_type             = typename traits_type::real_type;
    using integer_type          = std::int32_t;
    using parameter_type        = real_type;
    using container_type        = std::vector<parameter_type>;

    using pair_parameter_type   = parameter_type;

    // ------------------------------------------------------------------------
    // topology stuff
    using topology_type        = Topology;
    using molecule_id_type     = typename topology_type::molecule_id_type;
    using group_id_type        = typename topology_type::group_id_type;
    using connection_kind_type = typename topology_type::connection_kind_type;
    using ignore_molecule_type = IgnoreMolecule<molecule_id_type>;
    using ignore_group_type    = IgnoreGroup   <group_id_type>;
    using exclusion_list_type  = ExclusionList <traits_type>;

    static constexpr real_type default_cutoff(const integer_type n) noexcept
    {
        return std::pow(2.0, 12.0 / n);
    }
    static constexpr parameter_type default_parameter() noexcept
    {
        return parameter_type{0.0};
    }

  public:

    InversePowerPotential(const real_type eps, const integer_type n, const real_type cutoff_ratio,
        const std::vector<std::pair<std::size_t, parameter_type>>& parameters,
        const std::map<connection_kind_type, std::size_t>&         exclusions,
        ignore_molecule_type ignore_mol, ignore_group_type ignore_grp)
        :epsilon_(eps), n_(n), cutoff_ratio_(cutoff_ratio),
         coef_at_cutoff_(std::pow(1.0 / cutoff_ratio, n)),
         exclusion_list_(exclusions, std::move(ignore_mol), std::move(ignore_grp))
    {
        this->parameters_  .reserve(parameters.size());
        this->participants_.reserve(parameters.size());
        for(const auto& idxp : parameters)
        {
            const auto idx = idxp.first;
            this->participants_.push_back(idx);
            if(idx >= this->parameters_.size())
            {
                this->parameters_.resize(idx+1, default_parameter());
            }
            this->parameters_.at(idx) = idxp.second;
        }
    }
    ~InversePowerPotential() = default;
    InversePowerPotential(const InversePowerPotential&) = default;
    InversePowerPotential(InversePowerPotential&&)      = default;
    InversePowerPotential& operator=(const InversePowerPotential&) = default;
    InversePowerPotential& operator=(InversePowerPotential&&)      = default;

    // this value will be stored in NeighborList
    pair_parameter_type prepare_params(std::size_t i, std::size_t j) const noexcept
    {
        return this->parameters_[i] + this->parameters_[j];
    }

    // forwarding function for clarity
    real_type potential(const std::size_t i, const std::size_t j,
                        const real_type r) const noexcept
    {
        return this->potential(r, this->prepare_params(i, j));
    }
    real_type derivative(const std::size_t i, const std::size_t j,
                         const real_type r) const noexcept
    {
        return this->derivative(r, this->prepare_params(i, j));
    }

    real_type potential(const real_type r, const pair_parameter_type& d) const noexcept
    {
        MJOLNIR_GET_DEFAULT_LOGGER_DEBUG();
        MJOLNIR_LOG_FUNCTION_DEBUG();

        if(d * this->cutoff_ratio_ < r){return 0.0;}

        const real_type rinv = 1.0 / r;
        const real_type d_r = d * rinv;
        const real_type drn = std::pow(d_r, n_);
        return this->epsilon_ * (drn - this->coef_at_cutoff_);
    }
    real_type derivative(const real_type r, const pair_parameter_type& d) const noexcept
    {
        MJOLNIR_GET_DEFAULT_LOGGER_DEBUG();
        MJOLNIR_LOG_FUNCTION_DEBUG();

        if(d * this->cutoff_ratio_ < r){return 0.0;}

        const real_type rinv = 1.0 / r;
        const real_type d_r = d * rinv;
        const real_type drn = std::pow(d_r, n_);
        return -n_ * this->epsilon_ * drn * rinv;
    }

    void initialize(const System<traits_type>& sys) noexcept
    {
        MJOLNIR_GET_DEFAULT_LOGGER();
        MJOLNIR_LOG_FUNCTION();

        this->update(sys);
        return;
    }

    // nothing to be done if system parameter (e.g. temperature) do not changes
    void update(const System<traits_type>& sys) noexcept
    {
        MJOLNIR_GET_DEFAULT_LOGGER();
        MJOLNIR_LOG_FUNCTION();

        // update exclusion list based on sys.topology()
        exclusion_list_.make(sys);
        return;
    }

    real_type cutoff_ratio()   const noexcept {return this->cutoff_ratio_;}
    real_type coef_at_cutoff() const noexcept {return this->coef_at_cutoff_;}

    real_type max_cutoff_length() const
    {
        const real_type max_sigma =
            * (std::max_element(parameters_.cbegin(), parameters_.cend()));
        return 2 * max_sigma * this->cutoff_ratio_;
    }

    // -----------------------------------------------------------------------
    // for spatial partitions
    //
    // Here, the default implementation uses Newton's 3rd law to reduce
    // calculation. For an interacting pair (i, j), forces applied to i and j
    // are equal in magnitude and opposite in direction. So, if a pair (i, j) is
    // listed, (j, i) is not needed.
    //     See implementation of VerletList, CellList and GlobalPairInteraction
    // for more details about the usage of these functions.

    std::vector<std::size_t> const& participants() const noexcept {return participants_;}

    range<typename std::vector<std::size_t>::const_iterator>
    leading_participants() const noexcept
    {
        return make_range(participants_.begin(), std::prev(participants_.end()));
    }
    range<typename std::vector<std::size_t>::const_iterator>
    possible_partners_of(const std::size_t participant_idx,
                         const std::size_t /*particle_idx*/) const noexcept
    {
        return make_range(participants_.begin() + participant_idx + 1,
                          participants_.end());
    }
    bool has_interaction(const std::size_t i, const std::size_t j) const noexcept
    {
        return (i < j) && !exclusion_list_.is_excluded(i, j);
    }

    // ------------------------------------------------------------------------
    // for testing
    exclusion_list_type const& exclusion_list() const noexcept
    {
        return exclusion_list_;
    }

    // ------------------------------------------------------------------------
    // used by Observer.

    static const char* name() noexcept {return "InversePower";}

    // ------------------------------------------------------------------------
    // the following accessers would be used in tests.

    real_type& epsilon()       noexcept {return this->epsilon_;}
    real_type  epsilon() const noexcept {return this->epsilon_;}
    integer_type& n()             noexcept {return this->n_;}
    integer_type  n()       const noexcept {return this->n_;}
    std::vector<real_type>&       parameters()       noexcept {return this->parameters_;}
    std::vector<real_type> const& parameters() const noexcept {return this->parameters_;}

  private:

    real_type epsilon_;
    integer_type n_;
    real_type cutoff_ratio_;
    real_type coef_at_cutoff_; // correction of energy value at cutoff length
    std::vector<parameter_type> parameters_;
    std::vector<std::size_t>    participants_;

    exclusion_list_type exclusion_list_;
};
} // mjolnir

#ifdef MJOLNIR_SEPARATE_BUILD
#include <mjolnir/core/SimulatorTraits.hpp>
#include <mjolnir/core/BoundaryCondition.hpp>

namespace mjolnir
{
    extern template class InversePowerPotential<SimulatorTraits<double, UnlimitedBoundary>       >;
    extern template class InversePowerPotential<SimulatorTraits<float,  UnlimitedBoundary>       >;
    extern template class InversePowerPotential<SimulatorTraits<double, CuboidalPeriodicBoundary>>;
    extern template class InversePowerPotential<SimulatorTraits<float,  CuboidalPeriodicBoundary>>;
} // mjolnir
#endif// MJOLNIR_SEPARATE_BUILD

#endif /* MJOLNIR_EXCLUDED_VOLUME_POTENTIAL */
<|endoftext|>


<commit_before>/*
 * _StockTypeInfo.cpp
 *
 *  Created on: 2012-9-28
 *      Author: fasiondog
 */

#include <boost/python.hpp>
#include <hikyuu/serialization/StockTypeInfo_serialization.h>
#include "pickle_support.h"

using namespace boost::python;
using namespace hku;

void export_StockTypeInfo() {
    class_<StockTypeInfo>("StockTypeInfo", init<>())
            .def(init<uint32, const string&, price_t, price_t, int, size_t, size_t>())
            //.def(self_ns::str(self))
            .def("__str__", &StockTypeInfo::toString)
            .add_property("type", &StockTypeInfo::type)
            .add_property("description", make_function(&StockTypeInfo::description, return_value_policy<copy_const_reference>()))
            .add_property("tick", &StockTypeInfo::tick)
            .add_property("tickValue", &StockTypeInfo::tickValue)
            .add_property("unit", &StockTypeInfo::unit)
            .add_property("precision", &StockTypeInfo::precision)
            .add_property("minTradeNumber", &StockTypeInfo::minTradeNumber)
            .add_property("maxTradeNumber", &StockTypeInfo::maxTradeNumber)
#if HKU_PYTHON_SUPPORT_PICKLE
            .def_pickle(normal_pickle_suite<StockTypeInfo>())
#endif
            ;
}
<commit_msg>修改数量的相关数据类型为double<commit_after>/*
 * _StockTypeInfo.cpp
 *
 *  Created on: 2012-9-28
 *      Author: fasiondog
 */

#include <boost/python.hpp>
#include <hikyuu/serialization/StockTypeInfo_serialization.h>
#include "pickle_support.h"

using namespace boost::python;
using namespace hku;

void export_StockTypeInfo() {
    class_<StockTypeInfo>("StockTypeInfo", init<>())
      .def(init<uint32, const string&, price_t, price_t, int, double, double>())
      //.def(self_ns::str(self))
      .def("__str__", &StockTypeInfo::toString)
      .add_property("type", &StockTypeInfo::type)
      .add_property("description", make_function(&StockTypeInfo::description,
                                                 return_value_policy<copy_const_reference>()))
      .add_property("tick", &StockTypeInfo::tick)
      .add_property("tickValue", &StockTypeInfo::tickValue)
      .add_property("unit", &StockTypeInfo::unit)
      .add_property("precision", &StockTypeInfo::precision)
      .add_property("minTradeNumber", &StockTypeInfo::minTradeNumber)
      .add_property("maxTradeNumber", &StockTypeInfo::maxTradeNumber)
#if HKU_PYTHON_SUPPORT_PICKLE
      .def_pickle(normal_pickle_suite<StockTypeInfo>())
#endif
      ;
}
<|endoftext|>


<commit_before><commit_msg>throw away servers with invalid names<commit_after><|endoftext|>


<commit_before>#include "scientistservice.h"

using namespace std;

//operator overloading for scientistSort.
bool sortByNameAsc (const Scientist &a, const Scientist &b) { return a.getName()   <  b.getName();   }
bool sortByNameDesc(const Scientist &a, const Scientist &b) { return a.getName()   >  b.getName();   }
bool sortByGender  (const Scientist &a, const Scientist &b) { return a.getGender() <  b.getGender(); }
bool sortByBirth   (const Scientist &a, const Scientist &b) { return a.getBirth()  <  b.getBirth();  }
bool sortByDeath   (const Scientist &a, const Scientist &b) { return a.getDeath()  <  b.getDeath();  }
bool sortByAge     (const Scientist &a, const Scientist &b) { return a.getAge()    <  b.getAge();    }

ScientistService::ScientistService()
{

}

vector<Scientist> ScientistService::getScientists()
{   // Uploads the list of scientists from file.
    DataAccess data;

    _scientists = data.loadScientists();

    return _scientists;
}

bool ScientistService::addScientist(string name, char gender, int birth, int death, int age)
{   // Adds a scientist to the list and updates the file.
    // returns true if adding succeded, false otherwise.
    Scientist scientist(name, gender, birth, death, age);
    DataAccess data;

    if (findScientistByName(name).size() > 0)
    {
        return false;
    }

    else
    {
        _scientists.push_back(scientist);
        data.saveScientists(_scientists);
        return true;
    }
}

bool ScientistService::removeScientist(string name)
{   // removes a scientist with that name from the vector.
    // returns true if removeing succeded, false otherwise.
    DataAccess data;

    if (findScientistByName(name).size() > 0)
    {
        Scientist toRemove = findScientistByName(name).at(0);

        _scientists.erase(remove(_scientists.begin(), _scientists.end(), toRemove), _scientists.end());

        data.saveScientists(_scientists);

        return true;
    }

    return false;
}

void ScientistService::scientistSort(int sortType)
{    // Sort by parameter, 1 = name(A-Z), 2 = name(Z-A), 3 = gender, 4 = birth, 5 = death, 6 = age
     // change to switch case?

    DataAccess data;

    if (sortType == 1)
    {
        sort(_scientists.begin(), _scientists.end(), sortByNameAsc);
    }
    else if (sortType == 2)
    {
        sort(_scientists.begin(), _scientists.end(), sortByNameDesc);
    }
    else if (sortType == 3)
    {
        sort(_scientists.begin(), _scientists.end(), sortByGender);
    }
    else if (sortType == 4)
    {
        sort(_scientists.begin(), _scientists.end(), sortByBirth);
    }
    else if (sortType == 5)
    {
        sort(_scientists.begin(), _scientists.end(), sortByDeath);
    }
    else if (sortType == 6)
    {
        sort(_scientists.begin(), _scientists.end(), sortByAge);
    }

    data.saveScientists(_scientists);
}

vector<Scientist> ScientistService::findScientistByName(string name)
{   // Returns all scientists with the full name specified.
    // TODO leita eftir part úr nafni?
    vector<Scientist> scientist;

    for (size_t i = 0; i < _scientists.size(); i++)
    {
        if (_scientists[i].getName() == name)
        {
            scientist.push_back(_scientists[i]);
        }
    }

    return scientist;
}

vector<Scientist> ScientistService::findScientistByGender(char gender)
{   // Returns all scientists of that gender.
    vector<Scientist> scientist;

    for (size_t i = 0; i < _scientists.size(); i++)
    {
        if (_scientists[i].getGender() == gender)
        {
            scientist.push_back(_scientists[i]);
        }
    }

    return scientist;
}

vector<Scientist> ScientistService::findScientistByBirth(int birth)
{   // Returns all scientists born that year.
    vector<Scientist> scientist;

    for (size_t i = 0; i < _scientists.size(); i++)
    {
        if (_scientists[i].getBirth() == birth)
        {
            scientist.push_back(_scientists[i]);
        }
    }

    return scientist;
}

vector<Scientist> ScientistService::findScientistByBirthRange(int birth1, int birth2)
{   // Returns all scientists with same age as parameter ( int age )
    vector<Scientist> scientist;
    int temp;
    if(birth1 > birth2)
    {
        temp = birth1;
        birth1 = birth2;
        birth2 = temp;
    }
    for (size_t i = 0; i < _scientists.size(); i++)
    {
        if (_scientists[i].getBirth() > birth1 && _scientists[i].getBirth() < birth2)
        {
            scientist.push_back(_scientists[i]);
        }
    }

    return scientist;
}

vector<Scientist> ScientistService::findScientistByDeath(int death)
{   // Returns all scientists that died that year, or death = 0 for still alive..
    vector<Scientist> scientist;

    for (size_t i = 0; i < _scientists.size(); i++)
    {
        if (_scientists[i].getDeath() == death)
        {
            scientist.push_back(_scientists[i]);
        }
    }

    return scientist;
}

vector<Scientist> ScientistService::findScientistByDeathRange(int death1, int death2)
{   // Returns all scientists with same age as parameter ( int age )
    vector<Scientist> scientist;
    int temp;
    if(death1 > death2)
    {
        temp = death1;
        death1 = death2;
        death2 = temp;
    }
    for (size_t i = 0; i < _scientists.size(); i++)
    {
        if (_scientists[i].getDeath() > death1 && _scientists[i].getDeath() < death2)
        {
            scientist.push_back(_scientists[i]);
        }
    }

    return scientist;
}

vector<Scientist> ScientistService::findScientistByAge(int age)
{   // Returns all scientists with same age as parameter ( int age )
    vector<Scientist> scientist;

    for (size_t i = 0; i < _scientists.size(); i++)
    {
        if (_scientists[i].getAge() == age)
        {
            scientist.push_back(_scientists[i]);
        }
    }

    return scientist;
}

vector<Scientist> ScientistService::findScientistByAgeRange(int age1, int age2)
{   // Returns all scientists with same age as parameter ( int age )
    vector<Scientist> scientist;
    int temp;
    if(age1 > age2)
    {
        temp = age1;
        age1 = age2;
        age2 = temp;
    }
    for (size_t i = 0; i < _scientists.size(); i++)
    {
        if (_scientists[i].getAge() > age1 && _scientists[i].getAge() < age2)
        {
            scientist.push_back(_scientists[i]);
        }
    }

    return scientist;
}
<commit_msg>searchByName is not case sensitive<commit_after>#include "scientistservice.h"

using namespace std;

//operator overloading for scientistSort.
bool sortByNameAsc (const Scientist &a, const Scientist &b) { return a.getName()   <  b.getName();   }
bool sortByNameDesc(const Scientist &a, const Scientist &b) { return a.getName()   >  b.getName();   }
bool sortByGender  (const Scientist &a, const Scientist &b) { return a.getGender() <  b.getGender(); }
bool sortByBirth   (const Scientist &a, const Scientist &b) { return a.getBirth()  <  b.getBirth();  }
bool sortByDeath   (const Scientist &a, const Scientist &b) { return a.getDeath()  <  b.getDeath();  }
bool sortByAge     (const Scientist &a, const Scientist &b) { return a.getAge()    <  b.getAge();    }

ScientistService::ScientistService()
{

}

vector<Scientist> ScientistService::getScientists()
{   // Uploads the list of scientists from file.
    DataAccess data;

    _scientists = data.loadScientists();

    return _scientists;
}

bool ScientistService::addScientist(string name, char gender, int birth, int death, int age)
{   // Adds a scientist to the list and updates the file.
    // returns true if adding succeded, false otherwise.
    Scientist scientist(name, gender, birth, death, age);
    DataAccess data;

    if (findScientistByName(name).size() > 0)
    {
        return false;
    }

    else
    {
        _scientists.push_back(scientist);
        data.saveScientists(_scientists);
        return true;
    }
}

bool ScientistService::removeScientist(string name)
{   // removes a scientist with that name from the vector.
    // returns true if removeing succeded, false otherwise.
    DataAccess data;

    if (findScientistByName(name).size() > 0)
    {
        Scientist toRemove = findScientistByName(name).at(0);

        _scientists.erase(remove(_scientists.begin(), _scientists.end(), toRemove), _scientists.end());

        data.saveScientists(_scientists);

        return true;
    }

    return false;
}

void ScientistService::scientistSort(int sortType)
{    // Sort by parameter, 1 = name(A-Z), 2 = name(Z-A), 3 = gender, 4 = birth, 5 = death, 6 = age
     // change to switch case?

    DataAccess data;

    if (sortType == 1)
    {
        sort(_scientists.begin(), _scientists.end(), sortByNameAsc);
    }
    else if (sortType == 2)
    {
        sort(_scientists.begin(), _scientists.end(), sortByNameDesc);
    }
    else if (sortType == 3)
    {
        sort(_scientists.begin(), _scientists.end(), sortByGender);
    }
    else if (sortType == 4)
    {
        sort(_scientists.begin(), _scientists.end(), sortByBirth);
    }
    else if (sortType == 5)
    {
        sort(_scientists.begin(), _scientists.end(), sortByDeath);
    }
    else if (sortType == 6)
    {
        sort(_scientists.begin(), _scientists.end(), sortByAge);
    }

    data.saveScientists(_scientists);
}

vector<Scientist> ScientistService::findScientistByName(string name)
{   // Returns all scientists with the full name specified.
    // TODO leita eftir part úr nafni?
    vector<Scientist> scientist;
    string databaseName;

    for (size_t i = 0; i < _scientists.size(); i++)
    {
        databaseName = _scientists[i].getName();
        transform(databaseName.begin(), databaseName.end(), databaseName.begin(), ::tolower);
        transform(name.begin(), name.end(), name.begin(), ::tolower);

        if (databaseName == name)
        {
            scientist.push_back(_scientists[i]);
        }
    }

    return scientist;
}

vector<Scientist> ScientistService::findScientistByGender(char gender)
{   // Returns all scientists of that gender.
    vector<Scientist> scientist;

    for (size_t i = 0; i < _scientists.size(); i++)
    {
        if (_scientists[i].getGender() == gender)
        {
            scientist.push_back(_scientists[i]);
        }
    }

    return scientist;
}

vector<Scientist> ScientistService::findScientistByBirth(int birth)
{   // Returns all scientists born that year.
    vector<Scientist> scientist;

    for (size_t i = 0; i < _scientists.size(); i++)
    {
        if (_scientists[i].getBirth() == birth)
        {
            scientist.push_back(_scientists[i]);
        }
    }

    return scientist;
}

vector<Scientist> ScientistService::findScientistByBirthRange(int birth1, int birth2)
{   // Returns all scientists with same age as parameter ( int age )
    vector<Scientist> scientist;
    int temp;
    if(birth1 > birth2)
    {
        temp = birth1;
        birth1 = birth2;
        birth2 = temp;
    }
    for (size_t i = 0; i < _scientists.size(); i++)
    {
        if (_scientists[i].getBirth() > birth1 && _scientists[i].getBirth() < birth2)
        {
            scientist.push_back(_scientists[i]);
        }
    }

    return scientist;
}

vector<Scientist> ScientistService::findScientistByDeath(int death)
{   // Returns all scientists that died that year, or death = 0 for still alive..
    vector<Scientist> scientist;

    for (size_t i = 0; i < _scientists.size(); i++)
    {
        if (_scientists[i].getDeath() == death)
        {
            scientist.push_back(_scientists[i]);
        }
    }

    return scientist;
}

vector<Scientist> ScientistService::findScientistByDeathRange(int death1, int death2)
{   // Returns all scientists with same age as parameter ( int age )
    vector<Scientist> scientist;
    int temp;
    if(death1 > death2)
    {
        temp = death1;
        death1 = death2;
        death2 = temp;
    }
    for (size_t i = 0; i < _scientists.size(); i++)
    {
        if (_scientists[i].getDeath() > death1 && _scientists[i].getDeath() < death2)
        {
            scientist.push_back(_scientists[i]);
        }
    }

    return scientist;
}

vector<Scientist> ScientistService::findScientistByAge(int age)
{   // Returns all scientists with same age as parameter ( int age )
    vector<Scientist> scientist;

    for (size_t i = 0; i < _scientists.size(); i++)
    {
        if (_scientists[i].getAge() == age)
        {
            scientist.push_back(_scientists[i]);
        }
    }

    return scientist;
}

vector<Scientist> ScientistService::findScientistByAgeRange(int age1, int age2)
{   // Returns all scientists with same age as parameter ( int age )
    vector<Scientist> scientist;
    int temp;
    if(age1 > age2)
    {
        temp = age1;
        age1 = age2;
        age2 = temp;
    }
    for (size_t i = 0; i < _scientists.size(); i++)
    {
        if (_scientists[i].getAge() > age1 && _scientists[i].getAge() < age2)
        {
            scientist.push_back(_scientists[i]);
        }
    }

    return scientist;
}

<|endoftext|>


<commit_before><commit_msg>Update to v3<commit_after><|endoftext|>


<commit_before>#ifndef HMLIB_ODEINT_BREAKABLE_INTEGRATE_INC
#define HMLIB_ODEINT_BREAKABLE_INTEGRATE_INC 100
#
#include<utility>
#include<boost/numeric/odeint.hpp>
namespace hmLib{
	namespace odeint{
		namespace detail{
			/*
			* integrate_adaptive for simple stepper is basically an integrate_const + some last step
			*/
			template< class Stepper, class System, class State, class Time, class BreakableObserver >
			std::pair<Time, size_t> breakable_integrate_adaptive(Stepper stepper, System system, State &start_state,
				Time start_time, Time end_time, Time dt, BreakableObserver observer, boost::numeric::odeint::stepper_tag
			){
				using namespace boost::numeric::odeint;
				using namespace boost::numeric::odeint::detail;

				unwrap_reference< BreakableObserver >::type &obs = observer;
				unwrap_reference< Stepper >::type &st = stepper;

				Time time = start_time;
				int step = 0;
				// cast time+dt explicitely in case of expression templates (e.g. multiprecision)
				while(less_eq_with_sign(static_cast<Time>(time + dt), end_time, dt)){
					if(obs(start_state, time)){
						return std::make_pair(time, step);
					}
					st.do_step(system, start_state, time, dt);
					// direct computation of the time avoids error propagation happening when using time += dt
					// we need clumsy type analysis to get boost units working here
					++step;
					time = start_time + static_cast< typename unit_value_type<Time>::type >(step) * dt;
				}
				obs(start_state, time);

				return std::make_pair(time,step);
			}

			/*
			* integrate adaptive for controlled stepper
			*/
			template< class Stepper, class System, class State, class Time, class BreakableObserver >
			std::pair<Time,size_t> breakable_integrate_adaptive(Stepper stepper, System system, State &start_state,
				Time &start_time, Time end_time, Time &dt, BreakableObserver observer, boost::numeric::odeint::controlled_stepper_tag
			){
				using namespace boost::numeric::odeint;
				using namespace boost::numeric::odeint::detail;

				typename unwrap_reference< BreakableObserver >::type &obs = observer;
				typename unwrap_reference< Stepper >::type &st = stepper;

				failed_step_checker fail_checker;  // to throw a runtime_error if step size adjustment fails
				size_t count = 0;
				while(less_with_sign(start_time, end_time, dt)){
					if(obs(start_state, start_time))return std::make_pair(start_time,count);
					if(less_with_sign(end_time, static_cast<Time>(start_time + dt), dt)){
						dt = end_time - start_time;
					}

					controlled_step_result res;
					do{
						res = st.try_step(system, start_state, start_time, dt);
						fail_checker();  // check number of failed steps
					} while(res == fail);
					fail_checker.reset();  // if we reach here, the step was successful -> reset fail checker

					++count;
				}
				obs(start_state, start_time);

				return std::make_pair(start_time, count)
			}

			/*
			* integrate adaptive for dense output steppers
			*
			* step size control is used if the stepper supports it
			*/
			template< class Stepper, class System, class State, class Time, class BreakableObserver >
			std::pair<Time, size_t> breakable_integrate_adaptive(Stepper stepper, System system, State &start_state,
				Time start_time, Time end_time, Time dt, BreakableObserver observer, boost::numeric::odeint::dense_output_stepper_tag
			){
				using namespace boost::numeric::odeint;
				using namespace boost::numeric::odeint::detail;

				typename unwrap_reference< BreakableObserver >::type &obs = observer;
				typename unwrap_reference< Stepper >::type &st = stepper;

				size_t count = 0;
				st.initialize(start_state, start_time, dt);

				while(less_with_sign(st.current_time(), end_time, st.current_time_step())){
					while(less_eq_with_sign(static_cast<Time>(st.current_time() + st.current_time_step()),
						end_time,
						st.current_time_step())){   //make sure we don't go beyond the end_time
						if(obs(st.current_state(), st.current_time())){
							// overwrite start_state with the final point
							boost::numeric::odeint::copy(st.current_state(), start_state);
							return std::make_pair(st.current_time(), count);
						}
						st.do_step(system);
						++count;
					}
					// calculate time step to arrive exactly at end time
					st.initialize(st.current_state(), st.current_time(), static_cast<Time>(end_time - st.current_time()));
				}
				obs(st.current_state(), st.current_time());

				// overwrite start_state with the final point
				boost::numeric::odeint::copy(st.current_state(), start_state);

				return std::make_pair(st.current_time(), count);
			}
		}

		template< class Stepper, class System, class State, class Time, class BreakableObserver >
		std::pair<Time, size_t> breakable_integrate_adaptive(Stepper stepper, System system, State &start_state,Time start_time, Time end_time, Time dt,BreakableObserver observer){
			using stepper_category = typename boost::numeric::odeint::unwrap_reference<Stepper>::type::stepper_category;
			return detail::breakable_integrate_adaptive(stepper,system, start_state,start_time, end_time, dt,observer,stepper_category());
		}
	}
}
#
#endif
<commit_msg>Add BH library.<commit_after>#ifndef HMLIB_ODEINT_BREAKABLE_INTEGRATE_INC
#define HMLIB_ODEINT_BREAKABLE_INTEGRATE_INC 100
#
#include<utility>
#include<boost/numeric/odeint.hpp>
namespace hmLib{
	namespace odeint{
		namespace detail{
			/*
			* integrate_adaptive for simple stepper is basically an integrate_const + some last step
			*/
			template< class Stepper, class System, class State, class Time, class BreakableObserver >
			std::pair<Time, size_t> breakable_integrate_adaptive(Stepper stepper, System system, State &start_state,
				Time start_time, Time end_time, Time dt, BreakableObserver observer, boost::numeric::odeint::stepper_tag
			){
				using namespace boost::numeric::odeint;
				using namespace boost::numeric::odeint::detail;

				boost::numeric::odeint::unwrap_reference< BreakableObserver >::type &obs = observer;
				boost::numeric::odeint::unwrap_reference< Stepper >::type &st = stepper;

				Time time = start_time;
				int step = 0;
				// cast time+dt explicitely in case of expression templates (e.g. multiprecision)
				while(less_eq_with_sign(static_cast<Time>(time + dt), end_time, dt)){
					if(obs(start_state, time)){
						return std::make_pair(time, step);
					}
					st.do_step(system, start_state, time, dt);
					// direct computation of the time avoids error propagation happening when using time += dt
					// we need clumsy type analysis to get boost units working here
					++step;
					time = start_time + static_cast< typename unit_value_type<Time>::type >(step) * dt;
				}
				obs(start_state, time);

				return std::make_pair(time,step);
			}

			/*
			* integrate adaptive for controlled stepper
			*/
			template< class Stepper, class System, class State, class Time, class BreakableObserver >
			std::pair<Time,size_t> breakable_integrate_adaptive(Stepper stepper, System system, State &start_state,
				Time &start_time, Time end_time, Time &dt, BreakableObserver observer, boost::numeric::odeint::controlled_stepper_tag
			){
				using namespace boost::numeric::odeint;
				using namespace boost::numeric::odeint::detail;

				typename unwrap_reference< BreakableObserver >::type &obs = observer;
				typename unwrap_reference< Stepper >::type &st = stepper;

				failed_step_checker fail_checker;  // to throw a runtime_error if step size adjustment fails
				size_t count = 0;
				while(less_with_sign(start_time, end_time, dt)){
					if(obs(start_state, start_time))return std::make_pair(start_time,count);
					if(less_with_sign(end_time, static_cast<Time>(start_time + dt), dt)){
						dt = end_time - start_time;
					}

					controlled_step_result res;
					do{
						res = st.try_step(system, start_state, start_time, dt);
						fail_checker();  // check number of failed steps
					} while(res == fail);
					fail_checker.reset();  // if we reach here, the step was successful -> reset fail checker

					++count;
				}
				obs(start_state, start_time);

				return std::make_pair(start_time, count)
			}

			/*
			* integrate adaptive for dense output steppers
			*
			* step size control is used if the stepper supports it
			*/
			template< class Stepper, class System, class State, class Time, class BreakableObserver >
			std::pair<Time, size_t> breakable_integrate_adaptive(Stepper stepper, System system, State &start_state,
				Time start_time, Time end_time, Time dt, BreakableObserver observer, boost::numeric::odeint::dense_output_stepper_tag
			){
				using namespace boost::numeric::odeint;
				using namespace boost::numeric::odeint::detail;

				typename unwrap_reference< BreakableObserver >::type &obs = observer;
				typename unwrap_reference< Stepper >::type &st = stepper;

				size_t count = 0;
				st.initialize(start_state, start_time, dt);

				while(less_with_sign(st.current_time(), end_time, st.current_time_step())){
					while(less_eq_with_sign(static_cast<Time>(st.current_time() + st.current_time_step()),
						end_time,
						st.current_time_step())){   //make sure we don't go beyond the end_time
						if(obs(st.current_state(), st.current_time())){
							// overwrite start_state with the final point
							boost::numeric::odeint::copy(st.current_state(), start_state);
							return std::make_pair(st.current_time(), count);
						}
						st.do_step(system);
						++count;
					}
					// calculate time step to arrive exactly at end time
					st.initialize(st.current_state(), st.current_time(), static_cast<Time>(end_time - st.current_time()));
				}
				obs(st.current_state(), st.current_time());

				// overwrite start_state with the final point
				boost::numeric::odeint::copy(st.current_state(), start_state);

				return std::make_pair(st.current_time(), count);
			}
		}

		template< class Stepper, class System, class State, class Time, class BreakableObserver >
		std::pair<Time, size_t> breakable_integrate_adaptive(Stepper stepper, System system, State &start_state,Time start_time, Time end_time, Time dt,BreakableObserver observer){
			using stepper_category = typename boost::numeric::odeint::unwrap_reference<Stepper>::type::stepper_category;
			return detail::breakable_integrate_adaptive(stepper,system, start_state,start_time, end_time, dt,observer,stepper_category());
		}
	}
}
#
#endif
<|endoftext|>