<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include "doc.hxx"
#include "ndtxt.hxx"
#include "MarkManager.hxx"
#include "docary.hxx"
#include "switerator.hxx"
#include "fmtfld.hxx"
#include "docufld.hxx"

#include <libxml/encoding.h>
#include <libxml/xmlwriter.h>

namespace
{

// Small helper class to ensure that we write to nodes.xml if nothing
// has been explicitly specified.
// Always use at the beginning of dumpAsXml().
// Also, there are some functions to save typing.
class WriterHelper
{
public:
    WriterHelper( xmlTextWriterPtr );
    ~WriterHelper();
    operator xmlTextWriterPtr();
    xmlTextWriterPtr operator->();
    void startElement( const char* element );
    void endElement();
    void writeFormatAttribute( const char* attribute, const char* format, ... )
#ifdef LIBXML_ATTR_FORMAT
        LIBXML_ATTR_FORMAT(3,4)
#endif
        ;
private:
    xmlTextWriterPtr writer;
    bool owns;
};

WriterHelper::WriterHelper( xmlTextWriterPtr w )
    : writer( w )
    , owns( false )
{
    if( writer == NULL )
    {
        writer = xmlNewTextWriterFilename( "nodes.xml", 0 );
        xmlTextWriterStartDocument( writer, NULL, NULL, NULL );
        owns = true;
    }
}

WriterHelper::~WriterHelper()
{
    if( owns )
    {
        xmlTextWriterEndDocument( writer );
        xmlFreeTextWriter( writer );
    }
}

WriterHelper::operator xmlTextWriterPtr()
{
    return writer;
}

xmlTextWriterPtr WriterHelper::operator->()
{
    return writer;
}

void WriterHelper::startElement( const char* element )
{
    xmlTextWriterStartElement( writer, BAD_CAST( element ));
}

void WriterHelper::endElement()
{
    xmlTextWriterEndElement( writer );
}

void WriterHelper::writeFormatAttribute( const char* attribute, const char* format, ... )
{
    va_list va;
    va_start( va, format );
    xmlTextWriterWriteVFormatAttribute( writer, BAD_CAST( attribute ), format, va );
    va_end( va );
}

// Hack: somehow conversion from "..." to va_list does
// bomb on two string litterals in the format.
static const char* TMP_FORMAT = "%" SAL_PRIuUINTPTR;

}

void SwDoc::dumpAsXml( xmlTextWriterPtr w )
{
    WriterHelper writer( w );
    writer.startElement( "doc" );
    writer.writeFormatAttribute( "ptr", "%p", this );
    m_pNodes->dumpAsXml( writer );
    mpMarkManager->dumpAsXml( writer );
    mpFldTypes->dumpAsXml( writer );
    writer.endElement();
}

namespace sw {
namespace mark {
void MarkManager::dumpAsXml( xmlTextWriterPtr w )
{
    WriterHelper writer(w);
    writer.startElement("markManager");
    writer.startElement("fieldmarks");
    for (const_iterator_t it = m_vFieldmarks.begin(); it != m_vFieldmarks.end(); ++it)
    {
        pMark_t pMark = *it;
        writer.startElement("fieldmark");
        writer.writeFormatAttribute("startNode", TMP_FORMAT, pMark->GetMarkStart().nNode.GetIndex());
        writer.writeFormatAttribute("startOffset", "%d", pMark->GetMarkStart().nContent.GetIndex());
        writer.writeFormatAttribute("endNode", TMP_FORMAT, pMark->GetMarkEnd().nNode.GetIndex());
        writer.writeFormatAttribute("endOffset", "%d", pMark->GetMarkEnd().nContent.GetIndex());
        OString txt8 = OUStringToOString(pMark->GetName(), RTL_TEXTENCODING_UTF8);
        writer.writeFormatAttribute("name", "%s", BAD_CAST( txt8.getStr()));
        writer.endElement();
    }
    writer.endElement();
    writer.endElement();
}
} // namespace mark
} // namespace sw

void SwFldTypes::dumpAsXml( xmlTextWriterPtr w )
{
    WriterHelper writer(w);
    writer.startElement("swfldtypes");
    sal_uInt16 nCount = size();
    for (sal_uInt16 nType = 0; nType < nCount; ++nType)
    {
        const SwFieldType *pCurType = (*this)[nType];
        SwIterator<SwFmtFld, SwFieldType> aIter(*pCurType);
        for (const SwFmtFld* pCurFldFmt = aIter.First(); pCurFldFmt; pCurFldFmt = aIter.Next())
        {
            writer.startElement("swfmtfld");
            writer.writeFormatAttribute("ptr", "%p", pCurFldFmt);
            writer.writeFormatAttribute("pTxtAttr", "%p", pCurFldFmt->GetTxtFld());
            const char* name = "???";
            switch(pCurFldFmt->GetFld()->GetTyp()->Which())
            {
                case RES_POSTITFLD:
                    name = "swpostitfield";
                    break;
                default:
                    SAL_INFO("sw.core", "unhandled field type " << pCurFldFmt->GetFld()->GetTyp()->Which());
                    break;
            }
            writer.startElement(name);
            writer.writeFormatAttribute("ptr", "%p", pCurFldFmt->GetFld());
            if (pCurFldFmt->GetFld()->GetTyp()->Which() == RES_POSTITFLD)
            {
                const SwPostItField* pField = dynamic_cast<const SwPostItField*>(pCurFldFmt->GetFld());
                OString txt8 = OUStringToOString(pField->GetName(), RTL_TEXTENCODING_UTF8);
                writer.writeFormatAttribute("name", "%s", BAD_CAST( txt8.getStr()));
            }
            writer.endElement();
            writer.endElement();
        }
    }
    writer.endElement();
}

void SwNodes::dumpAsXml( xmlTextWriterPtr w )
{
    WriterHelper writer( w );
    writer.startElement( "swnodes" );
    writer.writeFormatAttribute( "ptr", "%p", this );
    for( unsigned int i = 0; i < Count(); ++i )
    {
        ( *this )[ i ]->dumpAsXml( writer );
    }
    writer.endElement();
}

void SwNode::dumpAsXml( xmlTextWriterPtr w )
{
    WriterHelper writer( w );
    const char* name = "???";
    switch( GetNodeType())
    {
        case ND_ENDNODE:
            name = "end";
            break;
        case ND_STARTNODE:
        case ND_TEXTNODE:
            abort(); // overriden
        case ND_TABLENODE:
            name = "table";
            break;
        case ND_GRFNODE:
            name = "grf";
            break;
        case ND_OLENODE:
            name = "ole";
            break;
    }
    writer.startElement( name );
    writer.writeFormatAttribute( "ptr", "%p", this );
    writer.writeFormatAttribute( "index", TMP_FORMAT, GetIndex() );
    writer.endElement();
    if( GetNodeType() == ND_ENDNODE )
        writer.endElement(); // end start node
}

void SwStartNode::dumpAsXml( xmlTextWriterPtr w )
{
    WriterHelper writer( w );
    const char* name = "???";
    switch( GetStartNodeType())
    {
        case SwNormalStartNode:
            name = "start";
            break;
        case SwTableBoxStartNode:
            name = "tablebox";
            break;
        case SwFlyStartNode:
            name = "fly";
            break;
        case SwFootnoteStartNode:
            name = "footnote";
            break;
        case SwHeaderStartNode:
            name = "header";
            break;
        case SwFooterStartNode:
            name = "footer";
            break;
    }
    writer.startElement( name );
    writer.writeFormatAttribute( "ptr", "%p", this );
    writer.writeFormatAttribute( "index", TMP_FORMAT, GetIndex() );
    // writer.endElement(); - it is a start node, so don't end, will make xml better nested
}

void SwTxtNode::dumpAsXml( xmlTextWriterPtr w )
{
    WriterHelper writer( w );
    writer.startElement( "text" );
    writer.writeFormatAttribute( "ptr", "%p", this );
    writer.writeFormatAttribute( "index", TMP_FORMAT, GetIndex() );
    OUString txt = GetTxt();
    for( int i = 0; i < 32; ++i )
        txt = txt.replace( i, '*' );
    OString txt8 = OUStringToOString( txt, RTL_TEXTENCODING_UTF8 );
    xmlTextWriterWriteString( writer, BAD_CAST( txt8.getStr()));
    writer.endElement();
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>don't show section/table nodes as plain start nodes in debug dump<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include "doc.hxx"
#include "ndtxt.hxx"
#include "MarkManager.hxx"
#include "docary.hxx"
#include "switerator.hxx"
#include "fmtfld.hxx"
#include "docufld.hxx"

#include <libxml/encoding.h>
#include <libxml/xmlwriter.h>

namespace
{

// Small helper class to ensure that we write to nodes.xml if nothing
// has been explicitly specified.
// Always use at the beginning of dumpAsXml().
// Also, there are some functions to save typing.
class WriterHelper
{
public:
    WriterHelper( xmlTextWriterPtr );
    ~WriterHelper();
    operator xmlTextWriterPtr();
    xmlTextWriterPtr operator->();
    void startElement( const char* element );
    void endElement();
    void writeFormatAttribute( const char* attribute, const char* format, ... )
#ifdef LIBXML_ATTR_FORMAT
        LIBXML_ATTR_FORMAT(3,4)
#endif
        ;
private:
    xmlTextWriterPtr writer;
    bool owns;
};

WriterHelper::WriterHelper( xmlTextWriterPtr w )
    : writer( w )
    , owns( false )
{
    if( writer == NULL )
    {
        writer = xmlNewTextWriterFilename( "nodes.xml", 0 );
        xmlTextWriterStartDocument( writer, NULL, NULL, NULL );
        owns = true;
    }
}

WriterHelper::~WriterHelper()
{
    if( owns )
    {
        xmlTextWriterEndDocument( writer );
        xmlFreeTextWriter( writer );
    }
}

WriterHelper::operator xmlTextWriterPtr()
{
    return writer;
}

xmlTextWriterPtr WriterHelper::operator->()
{
    return writer;
}

void WriterHelper::startElement( const char* element )
{
    xmlTextWriterStartElement( writer, BAD_CAST( element ));
}

void WriterHelper::endElement()
{
    xmlTextWriterEndElement( writer );
}

void WriterHelper::writeFormatAttribute( const char* attribute, const char* format, ... )
{
    va_list va;
    va_start( va, format );
    xmlTextWriterWriteVFormatAttribute( writer, BAD_CAST( attribute ), format, va );
    va_end( va );
}

// Hack: somehow conversion from "..." to va_list does
// bomb on two string litterals in the format.
static const char* TMP_FORMAT = "%" SAL_PRIuUINTPTR;

}

void SwDoc::dumpAsXml( xmlTextWriterPtr w )
{
    WriterHelper writer( w );
    writer.startElement( "doc" );
    writer.writeFormatAttribute( "ptr", "%p", this );
    m_pNodes->dumpAsXml( writer );
    mpMarkManager->dumpAsXml( writer );
    mpFldTypes->dumpAsXml( writer );
    writer.endElement();
}

namespace sw {
namespace mark {
void MarkManager::dumpAsXml( xmlTextWriterPtr w )
{
    WriterHelper writer(w);
    writer.startElement("markManager");
    writer.startElement("fieldmarks");
    for (const_iterator_t it = m_vFieldmarks.begin(); it != m_vFieldmarks.end(); ++it)
    {
        pMark_t pMark = *it;
        writer.startElement("fieldmark");
        writer.writeFormatAttribute("startNode", TMP_FORMAT, pMark->GetMarkStart().nNode.GetIndex());
        writer.writeFormatAttribute("startOffset", "%d", pMark->GetMarkStart().nContent.GetIndex());
        writer.writeFormatAttribute("endNode", TMP_FORMAT, pMark->GetMarkEnd().nNode.GetIndex());
        writer.writeFormatAttribute("endOffset", "%d", pMark->GetMarkEnd().nContent.GetIndex());
        OString txt8 = OUStringToOString(pMark->GetName(), RTL_TEXTENCODING_UTF8);
        writer.writeFormatAttribute("name", "%s", BAD_CAST( txt8.getStr()));
        writer.endElement();
    }
    writer.endElement();
    writer.endElement();
}
} // namespace mark
} // namespace sw

void SwFldTypes::dumpAsXml( xmlTextWriterPtr w )
{
    WriterHelper writer(w);
    writer.startElement("swfldtypes");
    sal_uInt16 nCount = size();
    for (sal_uInt16 nType = 0; nType < nCount; ++nType)
    {
        const SwFieldType *pCurType = (*this)[nType];
        SwIterator<SwFmtFld, SwFieldType> aIter(*pCurType);
        for (const SwFmtFld* pCurFldFmt = aIter.First(); pCurFldFmt; pCurFldFmt = aIter.Next())
        {
            writer.startElement("swfmtfld");
            writer.writeFormatAttribute("ptr", "%p", pCurFldFmt);
            writer.writeFormatAttribute("pTxtAttr", "%p", pCurFldFmt->GetTxtFld());
            const char* name = "???";
            switch(pCurFldFmt->GetFld()->GetTyp()->Which())
            {
                case RES_POSTITFLD:
                    name = "swpostitfield";
                    break;
                default:
                    SAL_INFO("sw.core", "unhandled field type " << pCurFldFmt->GetFld()->GetTyp()->Which());
                    break;
            }
            writer.startElement(name);
            writer.writeFormatAttribute("ptr", "%p", pCurFldFmt->GetFld());
            if (pCurFldFmt->GetFld()->GetTyp()->Which() == RES_POSTITFLD)
            {
                const SwPostItField* pField = dynamic_cast<const SwPostItField*>(pCurFldFmt->GetFld());
                OString txt8 = OUStringToOString(pField->GetName(), RTL_TEXTENCODING_UTF8);
                writer.writeFormatAttribute("name", "%s", BAD_CAST( txt8.getStr()));
            }
            writer.endElement();
            writer.endElement();
        }
    }
    writer.endElement();
}

void SwNodes::dumpAsXml( xmlTextWriterPtr w )
{
    WriterHelper writer( w );
    writer.startElement( "swnodes" );
    writer.writeFormatAttribute( "ptr", "%p", this );
    for( unsigned int i = 0; i < Count(); ++i )
    {
        ( *this )[ i ]->dumpAsXml( writer );
    }
    writer.endElement();
}

void SwNode::dumpAsXml( xmlTextWriterPtr w )
{
    WriterHelper writer( w );
    const char* name = "???";
    switch( GetNodeType())
    {
        case ND_ENDNODE:
            name = "end";
            break;
        case ND_STARTNODE:
        case ND_TEXTNODE:
            abort(); // overriden
        case ND_TABLENODE:
            name = "table";
            break;
        case ND_GRFNODE:
            name = "grf";
            break;
        case ND_OLENODE:
            name = "ole";
            break;
    }
    writer.startElement( name );
    writer.writeFormatAttribute( "ptr", "%p", this );
    writer.writeFormatAttribute( "index", TMP_FORMAT, GetIndex() );
    writer.endElement();
    if( GetNodeType() == ND_ENDNODE )
        writer.endElement(); // end start node
}

void SwStartNode::dumpAsXml( xmlTextWriterPtr w )
{
    WriterHelper writer( w );
    const char* name = "???";
    switch( GetNodeType() )
    {
        case ND_TABLENODE:
            name = "table";
            break;
        case ND_SECTIONNODE:
            name = "section";
            break;
        default:
            switch( GetStartNodeType())
            {
                case SwNormalStartNode:
                    name = "start";
                    break;
                case SwTableBoxStartNode:
                    name = "tablebox";
                    break;
                case SwFlyStartNode:
                    name = "fly";
                    break;
                case SwFootnoteStartNode:
                    name = "footnote";
                    break;
                case SwHeaderStartNode:
                    name = "header";
                    break;
                case SwFooterStartNode:
                    name = "footer";
                    break;
            }
            break;
    }
    writer.startElement( name );
    writer.writeFormatAttribute( "ptr", "%p", this );
    writer.writeFormatAttribute( "index", TMP_FORMAT, GetIndex() );
    // writer.endElement(); - it is a start node, so don't end, will make xml better nested
}

void SwTxtNode::dumpAsXml( xmlTextWriterPtr w )
{
    WriterHelper writer( w );
    writer.startElement( "text" );
    writer.writeFormatAttribute( "ptr", "%p", this );
    writer.writeFormatAttribute( "index", TMP_FORMAT, GetIndex() );
    OUString txt = GetTxt();
    for( int i = 0; i < 32; ++i )
        txt = txt.replace( i, '*' );
    OString txt8 = OUStringToOString( txt, RTL_TEXTENCODING_UTF8 );
    xmlTextWriterWriteString( writer, BAD_CAST( txt8.getStr()));
    writer.endElement();
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>// Uses a normalized image of green LEGO backplane
//  then converts it to a text schedule.

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

#include <iostream>
#include <string.h>
#include <climits>

#define XRES 32
#define YRES 64

using namespace cv;
using namespace std;

enum Color {WHITE, RED, ORANGE, YELLOW, GREEN, BLUE, PURPLE};

const Scalar color_map[] = {Scalar(255,255,255), Scalar(255,  0,  0),
                            Scalar(255,127,  0), Scalar(  0,255,  0),
                            Scalar(  0,  0,255), Scalar(  0,  0,255),
                            Scalar(255,  0,255)};

static void help()
{
    cout <<
    "Using OpenCV version " << CV_VERSION << endl << endl;
}

const char* wndname = "LEGO Schedule";

// returns closest color of given cell.
static Color getCellColor( const Mat& image, const Rect& cell) {
    Mat roiImg = image(cell);

    Mat hsv;
    cvtColor(roiImg, hsv, CV_BGR2HSV);

    // Nearest colors are red (0 deg) and orange(30 deg).
    //  Need 15 deg of accuracy. 360/15 = 24.
    int hbins=24;

    // Need saturation histogram to detect white.
    //  If most pixels have saturation less than 32 (256/8)
    //  then cell is white.
    int sbins=8;

    // Hue varies from 0 to 179 NOT 0 to 255.
    const float hrange0[] = {0, 180};
    const float srange0[] = {0, 256};

    const float* hrange = {hrange0};
    const float* srange = {srange0};

    const int hchan = 0;
    const int schan = 1;

    Mat h_hist, s_hist;
    calcHist(&hsv, 1, &hchan, Mat(), h_hist, 1, &hbins, &hrange);
    calcHist(&hsv, 1, &schan, Mat(), s_hist, 1, &sbins, &srange);

    Point huePt, satPt;
    minMaxLoc(h_hist, NULL, NULL, NULL, &huePt);
    minMaxLoc(s_hist, NULL, NULL, NULL, &satPt);

    int hue = huePt.y;
    int sat = satPt.y;

    cerr << s_hist << endl;
    cerr << 'H' << hue << 'S' << sat << ' ' << cell << endl;

    if(sat == 0 || sat == 1)
    {
        return WHITE;
    }
    else
    {
        if(hue == 22 || hue == 23 || hue == 0)
        {
            return RED;
        }
        else if(hue == 1 || hue == 2)
        {
            return ORANGE;
        }
        else if(hue >= 3 && hue <= 5)
        {
            return YELLOW;
        }
        else if(hue >= 6 && hue <= 11)
        {
            return GREEN;
        }
        else if(hue >= 12 && hue <= 17)
        {
            return BLUE;
        }
        else if(hue >= 18 && hue <= 21)
        {
            return PURPLE;
        }
    }
}

int main( int argc, char** argv) {
    help();
    namedWindow( wndname, 1 );

    for( int i = 1; i < argc; i++ )
    {
        vector<Point> object;
        vector<Point2f> src_anchors;
        vector<Point2f> dst_anchors;

        // Read image
        Mat out_image;
        Mat image = imread(argv[i], 1);
        if( image.empty() )
        {
            cout << "Couldn't load " << argv[i] << endl;
            continue;
        }

        cout << argv[i] << endl;
        Size cellSize = Size(image.size().width/XRES, image.size().height/YRES);
        // Generate grid
        for( int y = 0; y < YRES; y += 1)
        {
            for( int x = 0; x < XRES; x += 1)
            {
                Rect cell = Rect(Point(x*cellSize.width,y*cellSize.height), cellSize);
                Color color = getCellColor(image, cell);
                cout << color;
            }
            cout << endl;
        }
        cout << endl;
    }

    return 0;
}
<commit_msg>Adjusted saturation threshold.<commit_after>// Uses a normalized image of green LEGO backplane
//  then converts it to a text schedule.

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

#include <iostream>
#include <string.h>
#include <climits>

#define XRES 32
#define YRES 64

using namespace cv;
using namespace std;

enum Color {WHITE, RED, ORANGE, YELLOW, GREEN, BLUE, PURPLE};

const Scalar color_map[] = {Scalar(255,255,255), Scalar(255,  0,  0),
                            Scalar(255,127,  0), Scalar(  0,255,  0),
                            Scalar(  0,  0,255), Scalar(  0,  0,255),
                            Scalar(255,  0,255)};

static void help()
{
    cout <<
    "Using OpenCV version " << CV_VERSION << endl << endl;
}

const char* wndname = "LEGO Schedule";

// returns closest color of given cell.
static Color getCellColor( const Mat& image, const Rect& cell) {
    Mat roiImg = image(cell);

    Mat hsv;
    cvtColor(roiImg, hsv, CV_BGR2HSV);

    // Nearest colors are red (0 deg) and orange(30 deg).
    //  Need 15 deg of accuracy. 360/15 = 24.
    int hbins=24;

    // Need saturation histogram to detect white.
    //  If most pixels have saturation less than 32 (256/8)
    //  then cell is white.
    int sbins=8;

    // Hue varies from 0 to 179 NOT 0 to 255.
    const float hrange0[] = {0, 180};
    const float srange0[] = {0, 256};

    const float* hrange = {hrange0};
    const float* srange = {srange0};

    const int hchan = 0;
    const int schan = 1;

    Mat h_hist, s_hist;
    calcHist(&hsv, 1, &hchan, Mat(), h_hist, 1, &hbins, &hrange);
    calcHist(&hsv, 1, &schan, Mat(), s_hist, 1, &sbins, &srange);

    Point huePt, satPt;
    minMaxLoc(h_hist, NULL, NULL, NULL, &huePt);
    minMaxLoc(s_hist, NULL, NULL, NULL, &satPt);

    int hue = huePt.y;
    int sat = satPt.y;

//    cerr << 'H' << hue << 'S' << sat << ' ' << cell << endl;

    if(sat <= 2)
    {
        return WHITE;
    }
    else
    {
        if(hue == 22 || hue == 23 || hue == 0)
        {
            return RED;
        }
        else if(hue == 1 || hue == 2)
        {
            return ORANGE;
        }
        else if(hue >= 3 && hue <= 5)
        {
            return YELLOW;
        }
        else if(hue >= 6 && hue <= 11)
        {
            return GREEN;
        }
        else if(hue >= 12 && hue <= 17)
        {
            return BLUE;
        }
        else if(hue >= 18 && hue <= 21)
        {
            return PURPLE;
        }
    }
}

int main( int argc, char** argv) {
    help();
    namedWindow( wndname, 1 );

    for( int i = 1; i < argc; i++ )
    {
        vector<Point> object;
        vector<Point2f> src_anchors;
        vector<Point2f> dst_anchors;

        // Read image
        Mat out_image;
        Mat image = imread(argv[i], 1);
        if( image.empty() )
        {
            cout << "Couldn't load " << argv[i] << endl;
            continue;
        }

        cout << argv[i] << endl;
        Size cellSize = Size(image.size().width/XRES, image.size().height/YRES);
        // Generate grid
        for( int y = 0; y < YRES; y += 1)
        {
            for( int x = 0; x < XRES; x += 1)
            {
                Rect cell = Rect(Point(x*cellSize.width,y*cellSize.height), cellSize);
                Color color = getCellColor(image, cell);
                cout << color;
            }
            cout << endl;
        }
        cout << endl;
    }

    return 0;
}
<|endoftext|>


<commit_before>//  test tools header  -------------------------------------------------------//

//  (C) Copyright Beman Dawes 2000. Permission to copy, use, modify, sell
//  and distribute this software is granted provided this copyright notice
//  appears in all copies. This software is provided "as is" without express or
//  implied warranty, and with no claim as to its suitability for any purpose.

//  See http://www.boost.org for updates, documentation, and revision history.

//  Revision History
//   26 Feb 01  Numerous changes suggested during formal review. (Beman)
//    7 Feb 01  #include <boost/test/test_main.cpp> if requested. (Beman)
//   22 Jan 01  Remove all header dependencies. (Beman)
//    3 Dec 00  Remove function definitions. (Ed Brey)
//    5 Nov 00  Initial boost version (Beman Dawes)

#ifndef BOOST_TEST_TOOLS_HPP
#define BOOST_TEST_TOOLS_HPP

//  for convenience, allow the user to request inclusion of lower-level layers
#ifdef BOOST_INCLUDE_MAIN
#include <boost/test/cpp_main.cpp>
#include <boost/test/test_main.cpp>
#endif

//  header dependencies eliminated to reducing coupling.

//  macros (gasp!) ease use of reporting functions

#define BOOST_TEST(exp) ((exp) ? static_cast<void>(0) : boost::report_error(#exp,__FILE__,__LINE__))
//  Effects: if (!exp) call report_error().

#define BOOST_CRITICAL_TEST(exp) ((exp) ? static_cast<void>(0) : boost::report_critical_error(#exp,__FILE__,__LINE__))
//  Effects: if (!exp) call report_critical_error().

#define BOOST_ERROR(msg) boost::report_error((msg),__FILE__,__LINE__)

#define BOOST_CRITICAL_ERROR(msg) boost::report_critical_error((msg),__FILE__,__LINE__)

namespace boost
{
  //  Function implementations are not inline because it is better design to
  //  decouple implementation, and because space is more important than speed
  //  since error functions get called relatively infrequently.  Note that
  //  separating implementatiion means that this header could be useful
  //  without using the boost/test_main.hpp header for a main() function,
  //  and/or a different implementation could be supplied at link time.

  void report_error( const char * msg, const char * file, int line );
  //  Effects: increment test_tools_error counter, write error message to cout.

  void report_critical_error( const char * msg, const char * file, int line );
  //  Effects: report_error(msg,file,line), throw test_tools_exception.
}

#endif // BOOST_TEST_TOOLS_HPP
<commit_msg>Move includes of .cpp files to bottom to avoid warnings when using "required prototypes" options.<commit_after>//  test tools header  -------------------------------------------------------//

//  (C) Copyright Beman Dawes 2000. Permission to copy, use, modify, sell
//  and distribute this software is granted provided this copyright notice
//  appears in all copies. This software is provided "as is" without express or
//  implied warranty, and with no claim as to its suitability for any purpose.

//  See http://www.boost.org for updates, documentation, and revision history.

//  Revision History
//   26 Feb 01  Numerous changes suggested during formal review. (Beman)
//    7 Feb 01  #include <boost/test/test_main.cpp> if requested. (Beman)
//   22 Jan 01  Remove all header dependencies. (Beman)
//    3 Dec 00  Remove function definitions. (Ed Brey)
//    5 Nov 00  Initial boost version (Beman Dawes)

#ifndef BOOST_TEST_TOOLS_HPP
#define BOOST_TEST_TOOLS_HPP

//  header dependencies eliminated to reducing coupling.

//  macros (gasp!) ease use of reporting functions

#define BOOST_TEST(exp) ((exp) ? static_cast<void>(0) : boost::report_error(#exp,__FILE__,__LINE__))
//  Effects: if (!exp) call report_error().

#define BOOST_CRITICAL_TEST(exp) ((exp) ? static_cast<void>(0) : boost::report_critical_error(#exp,__FILE__,__LINE__))
//  Effects: if (!exp) call report_critical_error().

#define BOOST_ERROR(msg) boost::report_error((msg),__FILE__,__LINE__)

#define BOOST_CRITICAL_ERROR(msg) boost::report_critical_error((msg),__FILE__,__LINE__)

namespace boost
{
  //  Function implementations are not inline because it is better design to
  //  decouple implementation, and because space is more important than speed
  //  since error functions get called relatively infrequently.  Note that
  //  separating implementatiion means that this header could be useful
  //  without using the boost/test_main.hpp header for a main() function,
  //  and/or a different implementation could be supplied at link time.

  void report_error( const char * msg, const char * file, int line );
  //  Effects: increment test_tools_error counter, write error message to cout.

  void report_critical_error( const char * msg, const char * file, int line );
  //  Effects: report_error(msg,file,line), throw test_tools_exception.
}

//  for convenience, allow the user to request inclusion of lower-level layers
#ifdef BOOST_INCLUDE_MAIN
#include <boost/test/cpp_main.cpp>
#include <boost/test/test_main.cpp>
#endif

#endif // BOOST_TEST_TOOLS_HPP
<|endoftext|>


<commit_before>#include <ctime>
#include <cctype>

#include "core/RoleFactory.h"
#include "EventLogger.h"

static ConfigVariable<std::string> bind_addr("bind", "0.0.0.0:7197");
static ConfigVariable<std::string> output_format("output", "events-%Y%m%d-%H%M%S.csv");

EventLogger::EventLogger(RoleConfig roleconfig) : Role(roleconfig), m_log("eventlogger", "Event Logger")
{
	bind(bind_addr.get_rval(roleconfig));

	m_file_format = output_format.get_rval(roleconfig);
	open_log();
	std::vector<std::string> msg;
	msg.push_back("EventLogger");
	msg.push_back("log_opened");
	msg.push_back("Log opened upon Event Logger startup.");
	write_log(msg);

	start_receive();
}

void EventLogger::bind(const std::string &addr)
{
	m_log.info() << "Opening UDP socket..." << std::endl;
	std::string str_ip = addr;
	std::string str_port = str_ip.substr(str_ip.find(':', 0)+1, std::string::npos);
	str_ip = str_ip.substr(0, str_ip.find(':', 0));
	udp::resolver resolver(io_service);
	udp::resolver::query query(str_ip, str_port);
	udp::resolver::iterator it = resolver.resolve(query);
	m_socket = new udp::socket(io_service, *it);
}

void EventLogger::open_log()
{
	time_t rawtime;
	time(&rawtime);

	char filename[1024];
	strftime(filename, 1024, m_file_format.c_str(), localtime(&rawtime));
	m_log.debug() << "New log filename: " << filename << std::endl;

	if(m_file)
		m_file->close();

	m_file = new ofstream(filename);

	m_log.info() << "Opened new log." << std::endl;
}

void EventLogger::cycle_log()
{
	open_log();

	std::vector<std::string> msg;
	msg.push_back("EventLogger");
	msg.push_back("log_opened");
	msg.push_back("Log cycled.");
	write_log(msg);
}

void EventLogger::write_log(const std::vector<std::string> &msg)
{
	time_t rawtime;
	time(&rawtime);

	char timestamp[1024];
	strftime(timestamp, 1024, "\"%Y-%m-%d %H:%M:%S\"", localtime(&rawtime));

	*m_file << timestamp;

	for(auto it = msg.begin(); it != msg.end(); ++it)
	{
		// If the column consists purely of alphanumerics, we can just dump it
		// without quoting it...
		bool alnum = true;
		for(const char *c = it->c_str(); *c; ++c)
		{
			if(!isalnum(*c) && *c != '_')
			{
				alnum = false;
				break;
			}
		}
		if(alnum)
		{
			*m_file << ',' << *it;
			continue;
		}

		// Okay, there's other stuff in this column, so we're going to quote:

		char *cleaned = new char[it->length()*2+1];

		char *p = cleaned;
		for(const char *c = it->c_str(); *c; ++c)
		{
			if(*c == '"')
			{
				*(p++) = '"';
				*(p++) = '"';
			}
			else
			{
				*(p++) = *c;
			}
		}
		*p = 0;

		*m_file << ",\"" << cleaned << '"';
		delete cleaned;
	}

	*m_file << "\r\n" << std::flush;
}

void EventLogger::process_packet(const Datagram &dg)
{
	DatagramIterator dgi(dg);

	std::vector<std::string> msg;

	while(dgi.tell() != dg.size())
	{
		try
		{
			msg.push_back(dgi.read_string());
		}
		catch(std::exception &e)
		{
			m_log.error() << "Received truncated packet from "
			              << m_remote.address() << ":" << m_remote.port() << std::endl;
			return;
		}
	}

	write_log(msg);
}

void EventLogger::start_receive()
{
	m_socket->async_receive_from(boost::asio::buffer(m_buffer, EVENTLOG_BUFSIZE),
	                             m_remote, boost::bind(&EventLogger::handle_receive, this,
	                             boost::asio::placeholders::error,
	                             boost::asio::placeholders::bytes_transferred));
}

void EventLogger::handle_receive(const boost::system::error_code &ec, std::size_t bytes)
{
	if(ec.value())
	{
		m_log.warning() << "While receiving packet from "
		                << m_remote.address() << ":" << m_remote.port()
		                << ", an error occurred: "
		                << ec.value() << std::endl;
		return;
	}

	m_log.spam() << "Got packet from "
	             << m_remote.address() << ":" << m_remote.port() << std::endl;

	Datagram dg(m_buffer, bytes);
	process_packet(dg);

	start_receive();
}

static RoleFactoryItem<EventLogger> el_fact("eventlogger");
<commit_msg>Linter: Fix delete type in EventLogger<commit_after>#include <ctime>
#include <cctype>

#include "core/RoleFactory.h"
#include "EventLogger.h"

static ConfigVariable<std::string> bind_addr("bind", "0.0.0.0:7197");
static ConfigVariable<std::string> output_format("output", "events-%Y%m%d-%H%M%S.csv");

EventLogger::EventLogger(RoleConfig roleconfig) : Role(roleconfig), m_log("eventlogger", "Event Logger")
{
	bind(bind_addr.get_rval(roleconfig));

	m_file_format = output_format.get_rval(roleconfig);
	open_log();
	std::vector<std::string> msg;
	msg.push_back("EventLogger");
	msg.push_back("log_opened");
	msg.push_back("Log opened upon Event Logger startup.");
	write_log(msg);

	start_receive();
}

void EventLogger::bind(const std::string &addr)
{
	m_log.info() << "Opening UDP socket..." << std::endl;
	std::string str_ip = addr;
	std::string str_port = str_ip.substr(str_ip.find(':', 0)+1, std::string::npos);
	str_ip = str_ip.substr(0, str_ip.find(':', 0));
	udp::resolver resolver(io_service);
	udp::resolver::query query(str_ip, str_port);
	udp::resolver::iterator it = resolver.resolve(query);
	m_socket = new udp::socket(io_service, *it);
}

void EventLogger::open_log()
{
	time_t rawtime;
	time(&rawtime);

	char filename[1024];
	strftime(filename, 1024, m_file_format.c_str(), localtime(&rawtime));
	m_log.debug() << "New log filename: " << filename << std::endl;

	if(m_file)
		m_file->close();

	m_file = new ofstream(filename);

	m_log.info() << "Opened new log." << std::endl;
}

void EventLogger::cycle_log()
{
	open_log();

	std::vector<std::string> msg;
	msg.push_back("EventLogger");
	msg.push_back("log_opened");
	msg.push_back("Log cycled.");
	write_log(msg);
}

void EventLogger::write_log(const std::vector<std::string> &msg)
{
	time_t rawtime;
	time(&rawtime);

	char timestamp[1024];
	strftime(timestamp, 1024, "\"%Y-%m-%d %H:%M:%S\"", localtime(&rawtime));

	*m_file << timestamp;

	for(auto it = msg.begin(); it != msg.end(); ++it)
	{
		// If the column consists purely of alphanumerics, we can just dump it
		// without quoting it...
		bool alnum = true;
		for(const char *c = it->c_str(); *c; ++c)
		{
			if(!isalnum(*c) && *c != '_')
			{
				alnum = false;
				break;
			}
		}
		if(alnum)
		{
			*m_file << ',' << *it;
			continue;
		}

		// Okay, there's other stuff in this column, so we're going to quote:

		char *cleaned = new char[it->length()*2+1];

		char *p = cleaned;
		for(const char *c = it->c_str(); *c; ++c)
		{
			if(*c == '"')
			{
				*(p++) = '"';
				*(p++) = '"';
			}
			else
			{
				*(p++) = *c;
			}
		}
		*p = 0;

		*m_file << ",\"" << cleaned << '"';
		delete [] cleaned;
	}

	*m_file << "\r\n" << std::flush;
}

void EventLogger::process_packet(const Datagram &dg)
{
	DatagramIterator dgi(dg);

	std::vector<std::string> msg;

	while(dgi.tell() != dg.size())
	{
		try
		{
			msg.push_back(dgi.read_string());
		}
		catch(std::exception &e)
		{
			m_log.error() << "Received truncated packet from "
			              << m_remote.address() << ":" << m_remote.port() << std::endl;
			return;
		}
	}

	write_log(msg);
}

void EventLogger::start_receive()
{
	m_socket->async_receive_from(boost::asio::buffer(m_buffer, EVENTLOG_BUFSIZE),
	                             m_remote, boost::bind(&EventLogger::handle_receive, this,
	                             boost::asio::placeholders::error,
	                             boost::asio::placeholders::bytes_transferred));
}

void EventLogger::handle_receive(const boost::system::error_code &ec, std::size_t bytes)
{
	if(ec.value())
	{
		m_log.warning() << "While receiving packet from "
		                << m_remote.address() << ":" << m_remote.port()
		                << ", an error occurred: "
		                << ec.value() << std::endl;
		return;
	}

	m_log.spam() << "Got packet from "
	             << m_remote.address() << ":" << m_remote.port() << std::endl;

	Datagram dg(m_buffer, bytes);
	process_packet(dg);

	start_receive();
}

static RoleFactoryItem<EventLogger> el_fact("eventlogger");
<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2014-2015 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#pragma once

#include <immintrin.h>

#ifdef VECT_DEBUG
#include <iostream>
#endif

#ifdef __clang__
#define ETL_INLINE_VEC_128 inline __m128 __attribute__((__always_inline__, __nodebug__))
#define ETL_INLINE_VEC_128D inline __m128d __attribute__((__always_inline__, __nodebug__))
#else
#define ETL_INLINE_VEC_128 inline __m128 __attribute__((__always_inline__))
#define ETL_INLINE_VEC_128D inline __m128d __attribute__((__always_inline__))
#endif

namespace etl {

template<>
struct intrinsic_traits <float> {
    static constexpr const bool vectorizable = true;
    static constexpr const std::size_t size = 4;
    static constexpr const std::size_t alignment = 16;

    using intrinsic_type = __m128;
};

template<>
struct intrinsic_traits <double> {
    static constexpr const bool vectorizable = true;
    static constexpr const std::size_t size = 2;
    static constexpr const std::size_t alignment = 16;

    using intrinsic_type = __m128d;
};

template<>
struct intrinsic_traits <std::complex<float>> {
    static constexpr const bool vectorizable = true;
    static constexpr const std::size_t size = 2;
    static constexpr const std::size_t alignment = 16;

    using intrinsic_type = __m128;
};

template<>
struct intrinsic_traits <std::complex<double>> {
    static constexpr const bool vectorizable = true;
    static constexpr const std::size_t size = 1;
    static constexpr const std::size_t alignment = 16;

    using intrinsic_type = __m128d;
};

namespace vec {

#ifdef VEC_DEBUG

template<typename T>
void debug_d(T value){
    union test {
        __m128d vec; // a data field, maybe a register, maybe not
        double array[2];
        test(__m128d vec) : vec(vec) {}
    };

    test u_value = value;
    std::cout << "[" << u_value.array[0] << "," << u_value.array[1] << "]" << std::endl;
}

template<typename T>
void debug_s(T value){
    union test {
        __m128 vec; // a data field, maybe a register, maybe not
        float array[4];
        test(__m128 vec) : vec(vec) {}
    };

    test u_value = value;
    std::cout << "[" << u_value.array[0] << "," << u_value.array[1] << ","<< u_value.array[2] << ","<< u_value.array[3] << "]" << std::endl;
}

#else

template<typename T>
std::string debug_d(T){}

template<typename T>
std::string debug_s(T){}

#endif

inline void storeu(float* memory, __m128 value){
    _mm_storeu_ps(memory, value);
}

inline void storeu(double* memory, __m128d value){
    _mm_storeu_pd(memory, value);
}

inline void storeu(std::complex<float>* memory, __m128 value){
    _mm_storeu_ps(reinterpret_cast<float*>(memory), value);
}

inline void storeu(std::complex<double>* memory, __m128d value){
    _mm_storeu_pd(reinterpret_cast<double*>(memory), value);
}

inline void store(float* memory, __m128 value){
    _mm_store_ps(memory, value);
}

inline void store(double* memory, __m128d value){
    _mm_store_pd(memory, value);
}

inline void store(std::complex<float>* memory, __m128 value){
    _mm_store_ps(reinterpret_cast<float*>(memory), value);
}

inline void store(std::complex<double>* memory, __m128d value){
    _mm_store_pd(reinterpret_cast<double*>(memory), value);
}

ETL_INLINE_VEC_128 loadu(const float* memory){
    return _mm_loadu_ps(memory);
}

ETL_INLINE_VEC_128D loadu(const double* memory){
    return _mm_loadu_pd(memory);
}

ETL_INLINE_VEC_128 loadu(const std::complex<float>* memory){
    return _mm_loadu_ps(reinterpret_cast<const float*>(memory));
}

ETL_INLINE_VEC_128D loadu(const std::complex<double>* memory){
    return _mm_loadu_pd(reinterpret_cast<const double*>(memory));
}

ETL_INLINE_VEC_128D set(double value){
    return _mm_set1_pd(value);
}

ETL_INLINE_VEC_128 set(float value){
    return _mm_set1_ps(value);
}

ETL_INLINE_VEC_128D add(__m128d lhs, __m128d rhs){
    return _mm_add_pd(lhs, rhs);
}

ETL_INLINE_VEC_128D sub(__m128d lhs, __m128d rhs){
    return _mm_sub_pd(lhs, rhs);
}

ETL_INLINE_VEC_128D sqrt(__m128d x){
    return _mm_sqrt_pd(x);
}

ETL_INLINE_VEC_128D minus(__m128d x){
    return _mm_xor_pd(x, _mm_set1_pd(-0.f));
}

ETL_INLINE_VEC_128 add(__m128 lhs, __m128 rhs){
    return _mm_add_ps(lhs, rhs);
}

ETL_INLINE_VEC_128 sub(__m128 lhs, __m128 rhs){
    return _mm_sub_ps(lhs, rhs);
}

ETL_INLINE_VEC_128 sqrt(__m128 x){
    return _mm_sqrt_ps(x);
}

ETL_INLINE_VEC_128 minus(__m128 x){
    return _mm_xor_ps(x, _mm_set1_ps(-0.f));
}

template<bool Complex = false>
ETL_INLINE_VEC_128 mul(__m128 lhs, __m128 rhs){
    return _mm_mul_ps(lhs, rhs);
}

template<>
ETL_INLINE_VEC_128 mul<true>(__m128 lhs, __m128 rhs){
    //lhs = [x1.real, x1.img, x2.real, x2.img]
    //rhs = [y1.real, y1.img, y2.real, y2.img]

    //ymm1 = [y1.real, y1.real, y2.real, y2.real]
    __m128 ymm1 = _mm_moveldup_ps(rhs);

    //ymm2 = lhs * ymm1
    __m128 ymm2 = _mm_mul_ps(lhs, ymm1);

    //ymm3 = [x1.img, x1.real, x2.img, x2.real]
    __m128 ymm3 = _mm_shuffle_ps(lhs, lhs, _MM_SHUFFLE(2, 3, 0, 1));

    //ymm1 = [y1.imag, y1.imag, y2.imag, y2.imag]
    ymm1 = _mm_movehdup_ps(rhs);

    //ymm4 = ymm3 * ymm1
    __m128 ymm4 = _mm_mul_ps(ymm3, ymm1);

    //result = [ymm2 -+ ymm4];
    return _mm_addsub_ps(ymm2, ymm4);
}

template<bool Complex = false>
ETL_INLINE_VEC_128D mul(__m128d lhs, __m128d rhs){
    return _mm_mul_pd(lhs, rhs);
}

template<>
ETL_INLINE_VEC_128D mul<true>(__m128d lhs, __m128d rhs){
    //lhs = [x.real, x.img]
    //rhs = [y.real, y.img]

    //ymm1 = [y.real, y.real]
    __m128d ymm1 = _mm_movedup_pd(rhs);

    //ymm2 = [x.real * y.real, x.img * y.real]
    __m128d ymm2 = _mm_mul_pd(lhs, ymm1);

    //ymm1 = [x.img, x.real]
    ymm1 = _mm_shuffle_pd(lhs, lhs, _MM_SHUFFLE2(0, 1));

    //ymm3 =  [y.img, y.img]
    __m128d ymm3 = _mm_shuffle_pd(rhs, rhs, _MM_SHUFFLE2(1, 1));

    //ymm4 = [x.img * y.img, x.real * y.img]
    __m128d ymm4 = _mm_mul_pd(ymm1, ymm3);

    //result = [x.real * y.real - x.img * y.img, x.img * y.real - x.real * y.img]
    return _mm_addsub_pd(ymm2, ymm4);
}

template<bool Complex = false>
ETL_INLINE_VEC_128 div(__m128 lhs, __m128 rhs){
    return _mm_div_ps(lhs, rhs);
}

template<>
ETL_INLINE_VEC_128 div<true>(__m128 lhs, __m128 rhs){
    //lhs = [x1.real, x1.img, x2.real, x2.img]
    //rhs = [y1.real, y1.img, y2.real, y2.img]

    //ymm1 = [y1.real, y1.real, y2.real, y2.real]
    __m128 ymm0 = _mm_moveldup_ps(rhs);

    //ymm1 = [y1.imag, y1.imag, y2.imag, y2.imag]
    __m128 ymm1 = _mm_movehdup_ps(rhs);

    //ymm2 = [x.real * y.real, x.img * y.real, ...]
    __m128 ymm2 = _mm_mul_ps(lhs, ymm0);

    //ymm3 = [x1.img, x1.real, x2.img, x2.real]
    __m128 ymm3 = _mm_shuffle_ps(lhs, lhs, _MM_SHUFFLE(2, 3, 0, 1));

    //ymm4 = [x.img * y.img, x.real * y.img, ...]
    __m128 ymm4 = _mm_mul_ps(ymm3, ymm1);

    //ymm4 = subadd(ymm2, ymm1)
    ymm3 = _mm_sub_ps(_mm_set1_ps(0.0), ymm4);
    ymm4 = _mm_addsub_ps(ymm2, ymm3);

    //ymm2 = [y.real^2, y.real^2]
    ymm2 = _mm_mul_ps(ymm0, ymm0);

    //ymm3 = [y.imag^2, y.imag^2]
    ymm3 = _mm_mul_ps(ymm1, ymm1);

    //ymm0 = [y.real^2 + y.imag^2, y.real^2 + y.imag^2]
    ymm0 = _mm_add_ps(ymm2, ymm3);

    //result = ymm4 / ymm0
    return _mm_div_ps(ymm4, ymm0);
}

template<bool Complex = false>
ETL_INLINE_VEC_128D div(__m128d lhs, __m128d rhs){
    return _mm_div_pd(lhs, rhs);
}

template<>
ETL_INLINE_VEC_128D div<true>(__m128d lhs, __m128d rhs){
    //lhs = [x.real, x.img]
    //rhs = [y.real, y.img]

    //ymm0 = [y.real, y.real]
    __m128d ymm0 = _mm_movedup_pd(rhs);

    //ymm1 =  [y.img, y.img]
    __m128d ymm1 = _mm_shuffle_pd(rhs, rhs, _MM_SHUFFLE2(1, 1));

    //ymm2 = [x.real * y.real, x.img * y.real]
    __m128d ymm2 = _mm_mul_pd(lhs, ymm0);

    //ymm3 = [x.img, x.real]
    __m128d ymm3 = _mm_shuffle_pd(lhs, lhs, _MM_SHUFFLE2(0, 1));

    //ymm4 = [x.img * y.img, x.real * y.img]
    __m128d ymm4 = _mm_mul_pd(ymm3, ymm1);

    //ymm4 = subadd(ymm2, ymm4)
    ymm3 = _mm_sub_pd(_mm_set1_pd(0.0), ymm4);
    ymm4 = _mm_addsub_pd(ymm2, ymm3);

    //ymm2 = [y.real^2, y.real^2]
    ymm2 = _mm_mul_pd(ymm0, ymm0);

    //ymm3 = [y.imag^2, y.imag^2]
    ymm3 = _mm_mul_pd(ymm1, ymm1);

    //ymm0 = [y.real^2 + y.imag^2, y.real^2 + y.imag^2]
    ymm0 = _mm_add_pd(ymm2, ymm3);

    //result = ymm4 / ymm0
    return _mm_div_pd(ymm4, ymm0);
}

//The Intel C++ Compiler (icc) has more intrinsics.
//ETL uses them when compiled with icc

#ifdef __INTEL_COMPILER

//Exponential

ETL_INLINE_VEC_128D exp(__m128d x){
    return _mm_exp_pd(x);
}

ETL_INLINE_VEC_128 exp(__m128 x){
    return _mm_exp_ps(x);
}

//Logarithm

ETL_INLINE_VEC_128D log(__m128d x){
    return _mm_log_pd(x);
}

ETL_INLINE_VEC_128 log(__m128 x){
    return _mm_log_ps(x);
}

//Min

ETL_INLINE_VEC_128D min(__m128d lhs, __m128d rhs){
    return _mm_min_pd(lhs, rhs);
}

ETL_INLINE_VEC_128 min(__m128 lhs, __m128 rhs){
    return _mm_min_ps(lhs, rhs);
}

//Max

ETL_INLINE_VEC_128D max(__m128d lhs, __m128d rhs){
    return _mm_max_pd(lhs, rhs);
}

ETL_INLINE_VEC_128 max(__m128 lhs, __m128 rhs){
    return _mm_max_ps(lhs, rhs);
}

#endif

} //end of namespace vec

} //end of namespace etl
<commit_msg>Fixes<commit_after>//=======================================================================
// Copyright (c) 2014-2015 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#pragma once

#include <immintrin.h>

#ifdef VECT_DEBUG
#include <iostream>
#endif

#ifdef __clang__
#define ETL_INLINE_VEC_128 inline __m128 __attribute__((__always_inline__, __nodebug__))
#define ETL_INLINE_VEC_128D inline __m128d __attribute__((__always_inline__, __nodebug__))
#else
#define ETL_INLINE_VEC_128 inline __m128 __attribute__((__always_inline__))
#define ETL_INLINE_VEC_128D inline __m128d __attribute__((__always_inline__))
#endif

namespace etl {

template<>
struct intrinsic_traits <float> {
    static constexpr const bool vectorizable = true;
    static constexpr const std::size_t size = 4;
    static constexpr const std::size_t alignment = 16;

    using intrinsic_type = __m128;
};

template<>
struct intrinsic_traits <double> {
    static constexpr const bool vectorizable = true;
    static constexpr const std::size_t size = 2;
    static constexpr const std::size_t alignment = 16;

    using intrinsic_type = __m128d;
};

template<>
struct intrinsic_traits <std::complex<float>> {
    static constexpr const bool vectorizable = true;
    static constexpr const std::size_t size = 2;
    static constexpr const std::size_t alignment = 16;

    using intrinsic_type = __m128;
};

template<>
struct intrinsic_traits <std::complex<double>> {
    static constexpr const bool vectorizable = true;
    static constexpr const std::size_t size = 1;
    static constexpr const std::size_t alignment = 16;

    using intrinsic_type = __m128d;
};

namespace vec {

#ifdef VEC_DEBUG

template<typename T>
void debug_d(T value){
    union test {
        __m128d vec; // a data field, maybe a register, maybe not
        double array[2];
        test(__m128d vec) : vec(vec) {}
    };

    test u_value = value;
    std::cout << "[" << u_value.array[0] << "," << u_value.array[1] << "]" << std::endl;
}

template<typename T>
void debug_s(T value){
    union test {
        __m128 vec; // a data field, maybe a register, maybe not
        float array[4];
        test(__m128 vec) : vec(vec) {}
    };

    test u_value = value;
    std::cout << "[" << u_value.array[0] << "," << u_value.array[1] << ","<< u_value.array[2] << ","<< u_value.array[3] << "]" << std::endl;
}

#else

template<typename T>
std::string debug_d(T){}

template<typename T>
std::string debug_s(T){}

#endif

inline void storeu(float* memory, __m128 value){
    _mm_storeu_ps(memory, value);
}

inline void storeu(double* memory, __m128d value){
    _mm_storeu_pd(memory, value);
}

inline void storeu(std::complex<float>* memory, __m128 value){
    _mm_storeu_ps(reinterpret_cast<float*>(memory), value);
}

inline void storeu(std::complex<double>* memory, __m128d value){
    _mm_storeu_pd(reinterpret_cast<double*>(memory), value);
}

inline void store(float* memory, __m128 value){
    _mm_store_ps(memory, value);
}

inline void store(double* memory, __m128d value){
    _mm_store_pd(memory, value);
}

inline void store(std::complex<float>* memory, __m128 value){
    _mm_store_ps(reinterpret_cast<float*>(memory), value);
}

inline void store(std::complex<double>* memory, __m128d value){
    _mm_store_pd(reinterpret_cast<double*>(memory), value);
}

ETL_INLINE_VEC_128 loadu(const float* memory){
    return _mm_loadu_ps(memory);
}

ETL_INLINE_VEC_128D loadu(const double* memory){
    return _mm_loadu_pd(memory);
}

ETL_INLINE_VEC_128 loadu(const std::complex<float>* memory){
    return _mm_loadu_ps(reinterpret_cast<const float*>(memory));
}

ETL_INLINE_VEC_128D loadu(const std::complex<double>* memory){
    return _mm_loadu_pd(reinterpret_cast<const double*>(memory));
}

ETL_INLINE_VEC_128D set(double value){
    return _mm_set1_pd(value);
}

ETL_INLINE_VEC_128 set(float value){
    return _mm_set1_ps(value);
}

ETL_INLINE_VEC_128D add(__m128d lhs, __m128d rhs){
    return _mm_add_pd(lhs, rhs);
}

ETL_INLINE_VEC_128D sub(__m128d lhs, __m128d rhs){
    return _mm_sub_pd(lhs, rhs);
}

ETL_INLINE_VEC_128D sqrt(__m128d x){
    return _mm_sqrt_pd(x);
}

ETL_INLINE_VEC_128D minus(__m128d x){
    return _mm_xor_pd(x, _mm_set1_pd(-0.f));
}

ETL_INLINE_VEC_128 add(__m128 lhs, __m128 rhs){
    return _mm_add_ps(lhs, rhs);
}

ETL_INLINE_VEC_128 sub(__m128 lhs, __m128 rhs){
    return _mm_sub_ps(lhs, rhs);
}

ETL_INLINE_VEC_128 sqrt(__m128 x){
    return _mm_sqrt_ps(x);
}

ETL_INLINE_VEC_128 minus(__m128 x){
    return _mm_xor_ps(x, _mm_set1_ps(-0.f));
}

template<bool Complex = false>
ETL_INLINE_VEC_128 mul(__m128 lhs, __m128 rhs){
    return _mm_mul_ps(lhs, rhs);
}

template<>
ETL_INLINE_VEC_128 mul<true>(__m128 lhs, __m128 rhs){
    //lhs = [x1.real, x1.img, x2.real, x2.img]
    //rhs = [y1.real, y1.img, y2.real, y2.img]

    //ymm1 = [y1.real, y1.real, y2.real, y2.real]
    __m128 ymm1 = _mm_moveldup_ps(rhs);

    //ymm2 = lhs * ymm1
    __m128 ymm2 = _mm_mul_ps(lhs, ymm1);

    //ymm3 = [x1.img, x1.real, x2.img, x2.real]
    __m128 ymm3 = _mm_shuffle_ps(lhs, lhs, _MM_SHUFFLE(2, 3, 0, 1));

    //ymm1 = [y1.imag, y1.imag, y2.imag, y2.imag]
    ymm1 = _mm_movehdup_ps(rhs);

    //ymm4 = ymm3 * ymm1
    __m128 ymm4 = _mm_mul_ps(ymm3, ymm1);

    //result = [ymm2 -+ ymm4];
    return _mm_addsub_ps(ymm2, ymm4);
}

template<bool Complex = false>
ETL_INLINE_VEC_128D mul(__m128d lhs, __m128d rhs){
    return _mm_mul_pd(lhs, rhs);
}

template<>
ETL_INLINE_VEC_128D mul<true>(__m128d lhs, __m128d rhs){
    //lhs = [x.real, x.img]
    //rhs = [y.real, y.img]

    //ymm1 = [y.real, y.real]
    __m128d ymm1 = _mm_movedup_pd(rhs);

    //ymm2 = [x.real * y.real, x.img * y.real]
    __m128d ymm2 = _mm_mul_pd(lhs, ymm1);

    //ymm1 = [x.img, x.real]
    ymm1 = _mm_shuffle_pd(lhs, lhs, _MM_SHUFFLE2(0, 1));

    //ymm3 =  [y.img, y.img]
    __m128d ymm3 = _mm_shuffle_pd(rhs, rhs, _MM_SHUFFLE2(1, 1));

    //ymm4 = [x.img * y.img, x.real * y.img]
    __m128d ymm4 = _mm_mul_pd(ymm1, ymm3);

    //result = [x.real * y.real - x.img * y.img, x.img * y.real - x.real * y.img]
    return _mm_addsub_pd(ymm2, ymm4);
}

template<bool Complex = false>
ETL_INLINE_VEC_128 div(__m128 lhs, __m128 rhs){
    return _mm_div_ps(lhs, rhs);
}

template<>
ETL_INLINE_VEC_128 div<true>(__m128 lhs, __m128 rhs){
    //lhs = [x1.real, x1.img, x2.real, x2.img]
    //rhs = [y1.real, y1.img, y2.real, y2.img]

    //ymm0 = [y1.real, y1.real, y2.real, y2.real]
    __m128 ymm0 = _mm_moveldup_ps(rhs);

    //ymm1 = [y1.imag, y1.imag, y2.imag, y2.imag]
    __m128 ymm1 = _mm_movehdup_ps(rhs);

    //ymm2 = [x.real * y.real, x.img * y.real, ...]
    __m128 ymm2 = _mm_mul_ps(lhs, ymm0);

    //ymm3 = [x1.img, x1.real, x2.img, x2.real]
    __m128 ymm3 = _mm_shuffle_ps(lhs, lhs, _MM_SHUFFLE(2, 3, 0, 1));

    //ymm4 = [x.img * y.img, x.real * y.img, ...]
    __m128 ymm4 = _mm_mul_ps(ymm3, ymm1);

    //ymm4 = subadd(ymm2, ymm4)
    ymm3 = _mm_sub_ps(_mm_set1_ps(0.0), ymm4);
    ymm4 = _mm_addsub_ps(ymm2, ymm3);

    //ymm2 = [y.real^2, y.real^2]
    ymm2 = _mm_mul_ps(ymm0, ymm0);

    //ymm3 = [y.imag^2, y.imag^2]
    ymm3 = _mm_mul_ps(ymm1, ymm1);

    //ymm0 = [y.real^2 + y.imag^2, y.real^2 + y.imag^2]
    ymm0 = _mm_add_ps(ymm2, ymm3);

    //result = ymm4 / ymm0
    return _mm_div_ps(ymm4, ymm0);
}

template<bool Complex = false>
ETL_INLINE_VEC_128D div(__m128d lhs, __m128d rhs){
    return _mm_div_pd(lhs, rhs);
}

template<>
ETL_INLINE_VEC_128D div<true>(__m128d lhs, __m128d rhs){
    //lhs = [x.real, x.img]
    //rhs = [y.real, y.img]

    //ymm0 = [y.real, y.real]
    __m128d ymm0 = _mm_movedup_pd(rhs);

    //ymm1 =  [y.img, y.img]
    __m128d ymm1 = _mm_shuffle_pd(rhs, rhs, _MM_SHUFFLE2(1, 1));

    //ymm2 = [x.real * y.real, x.img * y.real]
    __m128d ymm2 = _mm_mul_pd(lhs, ymm0);

    //ymm3 = [x.img, x.real]
    __m128d ymm3 = _mm_shuffle_pd(lhs, lhs, _MM_SHUFFLE2(0, 1));

    //ymm4 = [x.img * y.img, x.real * y.img]
    __m128d ymm4 = _mm_mul_pd(ymm3, ymm1);

    //ymm4 = subadd(ymm2, ymm4)
    ymm3 = _mm_sub_pd(_mm_set1_pd(0.0), ymm4);
    ymm4 = _mm_addsub_pd(ymm2, ymm3);

    //ymm2 = [y.real^2, y.real^2]
    ymm2 = _mm_mul_pd(ymm0, ymm0);

    //ymm3 = [y.imag^2, y.imag^2]
    ymm3 = _mm_mul_pd(ymm1, ymm1);

    //ymm0 = [y.real^2 + y.imag^2, y.real^2 + y.imag^2]
    ymm0 = _mm_add_pd(ymm2, ymm3);

    //result = ymm4 / ymm0
    return _mm_div_pd(ymm4, ymm0);
}

//The Intel C++ Compiler (icc) has more intrinsics.
//ETL uses them when compiled with icc

#ifdef __INTEL_COMPILER

//Exponential

ETL_INLINE_VEC_128D exp(__m128d x){
    return _mm_exp_pd(x);
}

ETL_INLINE_VEC_128 exp(__m128 x){
    return _mm_exp_ps(x);
}

//Logarithm

ETL_INLINE_VEC_128D log(__m128d x){
    return _mm_log_pd(x);
}

ETL_INLINE_VEC_128 log(__m128 x){
    return _mm_log_ps(x);
}

//Min

ETL_INLINE_VEC_128D min(__m128d lhs, __m128d rhs){
    return _mm_min_pd(lhs, rhs);
}

ETL_INLINE_VEC_128 min(__m128 lhs, __m128 rhs){
    return _mm_min_ps(lhs, rhs);
}

//Max

ETL_INLINE_VEC_128D max(__m128d lhs, __m128d rhs){
    return _mm_max_pd(lhs, rhs);
}

ETL_INLINE_VEC_128 max(__m128 lhs, __m128 rhs){
    return _mm_max_ps(lhs, rhs);
}

#endif

} //end of namespace vec

} //end of namespace etl
<|endoftext|>


<commit_before>#ifndef iter_solver_base_hpp
#define iter_solver_base_hpp

#include "hmat.hpp" // preconditioner type
#include "timer.hpp"
#include "macros.hpp"

typedef HMat Pcond;

// this interface, especially the solve() funtion is inspired by
//  matlab syntax and probably Eigen iterative solver interface
class IterSolverBase {
public:
  // constructor
  IterSolverBase();

  virtual EMatrix solve(const EMatrix&, const EVector&) = 0;
  virtual EMatrix solve(const EMatrix&, const EVector&, const Pcond&) = 0;

  /*
  //EMatrix solve(const EMatrix&, const EMatrix&, );
  EMatrix solve(const EMatrix&, const EMatrix&, const double);
  EMatrix solve(const EMatrix&, const EMatrix&, const double,
		const int);
  EMatrix solve(const EMatrix&, const EMatrix&, const double,
		const int, );
  */
public:
  // stopping criteria for iterative solve
  static int    ITER_MAX_NUM;
  static double ITER_TOL;

protected:
  int num_iter;
  double time;
  double residule;
};

#endif
<commit_msg>small changes<commit_after>#ifndef iter_solver_base_hpp
#define iter_solver_base_hpp

#include "hmat.hpp" // preconditioner type
#include "timer.hpp"
#include "macros.hpp"

typedef HMat Pcond;

// this interface, especially the solve() funtion is inspired by
//  matlab syntax and probably Eigen iterative solver interface
class IterSolverBase {
public:
  // constructor
  IterSolverBase();

  virtual EMatrix solve(const EMatrix&, const EVector&) = 0;
  virtual EMatrix solve(const EMatrix&, const EVector&, const Pcond&) = 0;

public:
  // stopping criteria for iterative solve
  static int    ITER_MAX_NUM;
  static double ITER_TOL;

protected:
  int    num_iter;
  double time;
  double residule;
};

#endif
<|endoftext|>


<commit_before>#pragma once

#include <type_traits>
#include <tuple>
#include "utils.hpp"

namespace kgr {

namespace detail {

// tags for SFINAE
struct InvokeTag {};
struct InvokeCallTag {};

}

template<typename T, T t>
using Method = std::integral_constant<T, t>;

// forward declaration of Invoke
template<typename...>
struct Invoke;

// This class is the last node of the invoke list
template<>
struct Invoke<> {};

// This class is a list of methods.
template<typename M, typename... Others>
struct Invoke<M, Others...> : M, detail::InvokeTag {
	using Next = Invoke<Others...>;
};

// This specialization represent a method and a list of it's parameter.
template<typename M, typename... Others, typename... Ps>
struct Invoke<Invoke<M, Ps...>, Others...> : detail::InvokeCallTag, detail::InvokeTag, M {
	using Params = std::tuple<Ps...>;
	using Next = Invoke<Others...>;
};

template<template<typename> class M, typename... Ts>
struct AutoCall {
	using invoke = Invoke<Ts...>;

	template<typename T>
	using Map = M<T>;
};

template<typename... Ts>
struct AutoCallNoMap {
	using invoke = Invoke<Ts...>;

	template<typename>
	struct Map;
};

namespace detail {

template<template<typename> class Map, typename T, typename = void>
struct SafeMapHelper {
	static_assert(!std::is_same<T, T>::value, "The service sent to the service map is imcomplete. Have you forgot to include your service definition?");
};

template<template<typename> class Map, typename T>
struct SafeMapHelper<Map, T, void_t<typename Map<T>::Service>> {
	using Service = typename Map<T>::Service;
};

template<template<typename> class Map, typename T>
using SafeMap = typename SafeMapHelper<Map, T>::Service;

} // namespace detail
} // namespace kgr
<commit_msg>removed unused tag<commit_after>#pragma once

#include <type_traits>
#include <tuple>
#include "utils.hpp"

namespace kgr {

namespace detail {

// tags for SFINAE
struct InvokeCallTag {};

}

template<typename T, T t>
using Method = std::integral_constant<T, t>;

// forward declaration of Invoke
template<typename...>
struct Invoke;

// This class is the last node of the invoke list
template<>
struct Invoke<> {};

// This class is a list of methods.
template<typename M, typename... Others>
struct Invoke<M, Others...> : M {
	using Next = Invoke<Others...>;
};

// This specialization represent a method and a list of it's parameter.
template<typename M, typename... Others, typename... Ps>
struct Invoke<Invoke<M, Ps...>, Others...> : detail::InvokeCallTag, M {
	using Params = std::tuple<Ps...>;
	using Next = Invoke<Others...>;
};

template<template<typename> class M, typename... Ts>
struct AutoCall {
	using invoke = Invoke<Ts...>;

	template<typename T>
	using Map = M<T>;
};

template<typename... Ts>
struct AutoCallNoMap {
	using invoke = Invoke<Ts...>;

	template<typename>
	struct Map;
};

namespace detail {

template<template<typename> class Map, typename T, typename = void>
struct SafeMapHelper {
	static_assert(!std::is_same<T, T>::value, "The service sent to the service map is imcomplete. Have you forgot to include your service definition?");
};

template<template<typename> class Map, typename T>
struct SafeMapHelper<Map, T, void_t<typename Map<T>::Service>> {
	using Service = typename Map<T>::Service;
};

template<template<typename> class Map, typename T>
using SafeMap = typename SafeMapHelper<Map, T>::Service;

} // namespace detail
} // namespace kgr
<|endoftext|>


<commit_before>/**
 * @file simulation.hpp
 * @author Albert Uchytil, Tomas Coufal
 * @brief Class which takes care of the simulation
 */

#include "simulation.hpp"

Simulation::Simulation() {
    calendar = new Calendar();
    model = new Model();
}
Simulation::~Simulation() {
    delete calendar;
    delete model;
}
void Simulation::Start() {
    // randomize seed
    RandomizeSeed();

    // setup
    this->simtime = 0;

    // initial planning
    this->PlanEvents();

    // simulate
    while (!calendar->Empty() && (this->simtime < this->endtime)) {
        // get event from calendar and simulate the transition
        Event * e = calendar->GetEvent();
        this->simtime = e->GetTime();
        // take action and make the transition
        this->PerformEvent(e);
        // plan newly available events
        this->PlanEvents();
    }
}
void Simulation::SetEndtime(double t) {
    this->endtime = t;
}

void Simulation::PlanEvents() {
    // normal transitions (priority, timed)
    std::vector<Transition*>::iterator trans_it;
    std::vector<Transition*> trans = this->model->GetTransitions();
    Event* event;

    // get all transitions
    for(trans_it = trans.begin(); trans_it != trans.end(); trans_it++) {
        // if transition is feasible, plan it
        if ((*trans_it)->IsFeasible()) {
            event = this->CreateEvent(*trans_it);
            this->calendar->AppendEvent(event);
        }
    }

    // probability transitions, grouped -> pick one based on the roll
    std::vector<ProbTrans*>::iterator probtrans_it;
    std::vector<ProbTrans*> probtrans = this->model->GetProbGroups();
    Transition * t;

    // get all transitions
    for(probtrans_it = probtrans.begin(); probtrans_it != probtrans.end(); probtrans_it++) {
        // roll the dice and pick transition within group
        t = (*probtrans)->PickTransition(RollPercentage());
        // if transition is feasible, plan it
        if (t->IsFeasible()) {
            event = this->CreateEvent(t);
            this->calendar->AppendEvent(event);
        }
    }
}

Event * Simulation::CreateEvent(Transition * trans) {
    //reserve tokens
    std::vector<Connection*>::iterator conn_it;
    std::vector<Token*> tokens;
    Token * token;
    // for each input connection grab all tokens needed
    for (conn_it = trans->Inputs.begin(); conn_it != trans->Inputs.end(); conn_it++) {
        for (int i = 0; i < (*conn_it)->Capacity; i++) {
            token = (*conn_it)->Pl->GetToken();
            tokens.push_back(token);
            token->SetPlanned();
        }
    }

    //set time
    //default time is for instant transition TransType::Priority
    double time = this->simtime;
    if (trans->Type == TransType::TimeConstant) {
        time = time + trans->Value;
    }
    else if (trans->Type == TransType::TimeGenerated) {
        time = time + GenerateDelayExp(trans->Value);
    }
    Event * event = new Event(time, trans, tokens);
    return event;
}
void Simulation::PerformEvent(Event * event) {
    return;
}<commit_msg>[simluation] hotfix<commit_after>/**
 * @file simulation.hpp
 * @author Albert Uchytil, Tomas Coufal
 * @brief Class which takes care of the simulation
 */

#include "simulation.hpp"

Simulation::Simulation() {
    calendar = new Calendar();
    model = new Model();
}
Simulation::~Simulation() {
    delete calendar;
    delete model;
}
void Simulation::Start() {
    // randomize seed
    RandomizeSeed();

    // setup
    this->simtime = 0;

    // initial planning
    this->PlanEvents();

    // simulate
    while (!calendar->Empty() && (this->simtime < this->endtime)) {
        // get event from calendar and simulate the transition
        Event * e = calendar->GetEvent();
        this->simtime = e->GetTime();
        // take action and make the transition
        this->PerformEvent(e);
        // plan newly available events
        this->PlanEvents();
    }
}
void Simulation::SetEndtime(double t) {
    this->endtime = t;
}

void Simulation::PlanEvents() {
    // normal transitions (priority, timed)
    std::vector<Transition*>::iterator trans_it;
    std::vector<Transition*> trans = this->model->GetTransitions();
    Event* event;

    // get all transitions
    for(trans_it = trans.begin(); trans_it != trans.end(); trans_it++) {
        // if transition is feasible, plan it
        if ((*trans_it)->IsFeasible()) {
            event = this->CreateEvent(*trans_it);
            this->calendar->AppendEvent(event);
        }
    }

    // probability transitions, grouped -> pick one based on the roll
    std::vector<ProbTrans*>::iterator probtrans_it;
    std::vector<ProbTrans*> probtrans = this->model->GetProbGroups();
    Transition * t;

    // get all transitions
    for(probtrans_it = probtrans.begin(); probtrans_it != probtrans.end(); probtrans_it++) {
        // roll the dice and pick transition within group
        t = probtrans->PickTransition(RollPercentage());
        // if transition is feasible, plan it
        if (t->IsFeasible()) {
            event = this->CreateEvent(t);
            this->calendar->AppendEvent(event);
        }
    }
}

Event * Simulation::CreateEvent(Transition * trans) {
    //reserve tokens
    std::vector<Connection*>::iterator conn_it;
    std::vector<Token*> tokens;
    Token * token;
    // for each input connection grab all tokens needed
    for (conn_it = trans->Inputs.begin(); conn_it != trans->Inputs.end(); conn_it++) {
        for (int i = 0; i < (*conn_it)->Capacity; i++) {
            token = (*conn_it)->Pl->GetToken();
            tokens.push_back(token);
            token->SetPlanned();
        }
    }

    //set time
    //default time is for instant transition TransType::Priority
    double time = this->simtime;
    if (trans->Type == TransType::TimeConstant) {
        time = time + trans->Value;
    }
    else if (trans->Type == TransType::TimeGenerated) {
        time = time + GenerateDelayExp(trans->Value);
    }
    Event * event = new Event(time, trans, tokens);
    return event;
}
void Simulation::PerformEvent(Event * event) {
    return;
}<|endoftext|>


<commit_before>#ifndef CPPMATH_VECTOR_2_HPP
#define CPPMATH_VECTOR_2_HPP

#include <math.h>

#if (defined(__GNUC__) && __cplusplus < 201103) || (defined(_WIN32) && _MSC_VER<1900)
#define constexpr
#endif

namespace geometry
{
    template <class T>
    class Vector2
    {
        public:
            constexpr Vector2() : Vector2(0, 0) {}
            constexpr Vector2(const Vector2<T>& vec) : Vector2(vec.x, vec.y) {}
            constexpr Vector2(const T& x_, const T& y_) : x(x_), y(y_) {}

        public:
            constexpr double abs() const
            {
                return sqrt(x * x + y * y);
            }

            void normalize()
            {
                *this /= abs();
            }

            constexpr T scalar(const Vector2<T>& vec) const
            {
                return x * vec.x + y * vec.y;
            }

            constexpr double dir() const
            {
                //angle between 2 vectors: scalar(vec1, vec2) / abs(vec1) * abs(vec2)
                //-> direction = angle between vec(x, y) and the x-axis vec(1, 0)
                return acos(x / abs()) / M_PI * 180;
            }

            void set(const T& x_, const T& y_)
            {
                x = x_;
                y = y_;
            }

            void set(const T& val)
            {
                x = y = val;
            }

            template <class T2>
            constexpr Vector2<T> operator+(const Vector2<T2>& p) const
            {
                return Vector2<T>(x + p.x, y + p.y);
            }

            template <class T2>
            Vector2<T>& operator+=(const Vector2<T2>& p)
            {
                return *this = *this + p;
            }

            constexpr Vector2<T> operator-() const
            {
                return Vector2<T>(-x, -y);
            }

            template <class T2>
            constexpr Vector2<T> operator-(const Vector2<T2>& p) const
            {
                return Vector2<T>(x - p.x, y - p.y);
            }

            template <class T2>
            Vector2<T>& operator-=(const Vector2<T2>& p)
            {
                return *this = *this - p;
            }

            //This is NOT scalar multiplication, use scalar() instead
            template <class T2>
            constexpr Vector2<T> operator*(const Vector2<T2>& p) const
            {
                return Vector2<T>(x * p.x, y * p.y);
            }

            template <class T2>
            constexpr Vector2<T> operator*(const T2& val) const
            {
                return Vector2<T>(x * val, y * val);
            }

            template <class T2>
            Vector2<T>& operator*=(const Vector2<T2>& p)
            {
                return *this = *this * p;
            }

            template <class T2>
            Vector2<T>& operator*=(const T2& val)
            {
                return *this = *this * val;
            }

            template <class T2>
            constexpr Vector2<T> operator/(const T2& val) const
            {
                return Vector2<T>(x / val, y / val);
            }

            template <class T2>
            constexpr Vector2<T> operator/(const Vector2<T2>& p) const
            {
                return Vector2<T>(x / p.x, y / p.y);
            }

            template <class T2>
            Vector2<T>& operator/=(const Vector2<T2>& p)
            {
                return *this = *this / p;
            }

            template <class T2>
            Vector2<T>& operator/=(const T2& val)
            {
                return *this = *this / val;
            }

            constexpr bool operator<(const Vector2<T>& p) const
            {
                return x < p.x && y < p.y;
            }

            constexpr bool operator>(const Vector2<T>& p) const
            {
                return x > p.x && y > p.y;
            }

            constexpr bool operator<=(const Vector2<T>& p) const
            {
                return x <= p.x && y <= p.y;
            }

            constexpr bool operator>=(const Vector2<T>& p) const
            {
                return x >= p.x && y >= p.y;
            }

            constexpr bool operator!=(const Vector2<T>& p) const
            {
                return x != p.x || y != p.y;
            }

            constexpr bool operator==(const Vector2<T>& p) const
            {
                return x == p.x && y == p.y;
            }

            constexpr operator bool() const
            {
                return x || y;
            }

            template <class T2>
            constexpr operator Vector2<T2>() const
            {
                return Vector2<T2>(static_cast<T2>(x), static_cast<T2>(y));
            }

        public:
            T x, y;

    };

    template <class T>
    Vector2<T> fromDirection(float length, float dir)
    {
        return Vector2<T>(length * cos(dir * M_PI / 180), length * sin(dir * M_PI / 180));
    }
}

#endif

<commit_msg>Extend Vector2 class by several functions<commit_after>#ifndef CPPMATH_VECTOR_2_HPP
#define CPPMATH_VECTOR_2_HPP

#include "../math.hpp"
#include "../TypeTraits.hpp"

#if (defined(__GNUC__) && __cplusplus < 201103) || (defined(_WIN32) && _MSC_VER<1900)
#define constexpr
#endif

namespace geometry
{
    template <class T>
    class Vector2
    {
        public:
            constexpr Vector2() : Vector2(0, 0) {}
            constexpr Vector2(const T& x_, const T& y_) : x(x_), y(y_) {}

            constexpr static Vector2<T> fromDirection(float length, float dir)
            {
                return Vector2<T>(length * cos(dir * M_PI / 180),
                        length * sin(dir * M_PI / 180));
            }

        public:
            constexpr double abs() const
            {
                return sqrt(x * x + y * y);
            }

            // Magnitude without sqrt
            constexpr double abs_sqr() const
            {
                return x * x + y * y;
            }

            void normalize()
            {
                *this /= abs();
            }

            Vector2<T> normalized()
            {
                return *this / abs();
            }

            constexpr T scalar(const Vector2<T>& vec) const
            {
                return x * vec.x + y * vec.y;
            }

            // Returns the magnitude of the resulting 3D vector of a
            // 3D cross product with z = 0.
            constexpr T cross(const Vector2<T>& vec) const
            {
                return vec.y * x - vec.x * y;
            }

            // Produces less rounding errors when checking the cross product for 0
            constexpr inline bool crossAlmostZero(const Vector2<T>& vec) const
            {
                return math::almostEquals(vec.y * x, vec.x * y);
            }

            // Returns a vector with the elements' signs.
            constexpr Vector2<T> signs() const
            {
                return Vector2<T>(math::sign(x), math::sign(y));
            }

            constexpr double dir() const
            {
                //angle between 2 vectors: scalar(vec1, vec2) / abs(vec1) * abs(vec2)
                //-> direction = angle between vec(x, y) and the x-axis vec(1, 0)
                return acos(x / abs()) / M_PI * 180;
            }

            void set(const T& x_, const T& y_)
            {
                x = x_;
                y = y_;
            }

            void set(const T& val)
            {
                x = y = val;
            }

            // Useful for floating point number comparison
            bool almostEquals(const Vector2<T>& p) const
            {
                return math::almostEquals(x, p.x) && math::almostEquals(y, p.y);
            }

            bool almostEquals(const Vector2<T>& p, T tolerance) const
            {
                return math::almostEquals(x, p.x, tolerance) && math::almostEquals(y, p.y, tolerance);
            }

            template <class T2>
            constexpr Vector2<T> operator+(const Vector2<T2>& p) const
            {
                return Vector2<T>(x + p.x, y + p.y);
            }

            template <class T2>
            Vector2<T>& operator+=(const Vector2<T2>& p)
            {
                return *this = *this + p;
            }

            constexpr Vector2<T> operator-() const
            {
                return Vector2<T>(-x, -y);
            }

            template <class T2>
            constexpr Vector2<T> operator-(const Vector2<T2>& p) const
            {
                return Vector2<T>(x - p.x, y - p.y);
            }

            template <class T2>
            Vector2<T>& operator-=(const Vector2<T2>& p)
            {
                return *this = *this - p;
            }

            //This is NOT scalar multiplication, use scalar() instead
            template <class T2>
            constexpr Vector2<T> operator*(const Vector2<T2>& p) const
            {
                return Vector2<T>(x * p.x, y * p.y);
            }

            template <class T2>
            constexpr Vector2<T> operator*(const T2& val) const
            {
                return Vector2<T>(x * val, y * val);
            }

            template <class T2>
            Vector2<T>& operator*=(const Vector2<T2>& p)
            {
                return *this = *this * p;
            }

            template <class T2>
            Vector2<T>& operator*=(const T2& val)
            {
                return *this = *this * val;
            }

            template <class T2>
            constexpr Vector2<T> operator/(const T2& val) const
            {
                return Vector2<T>(x / val, y / val);
            }

            template <class T2>
            constexpr Vector2<T> operator/(const Vector2<T2>& p) const
            {
                return Vector2<T>(x / p.x, y / p.y);
            }

            template <class T2>
            Vector2<T>& operator/=(const Vector2<T2>& p)
            {
                return *this = *this / p;
            }

            template <class T2>
            Vector2<T>& operator/=(const T2& val)
            {
                return *this = *this / val;
            }

            constexpr bool operator<(const Vector2<T>& p) const
            {
                return x < p.x && y < p.y;
            }

            constexpr bool operator>(const Vector2<T>& p) const
            {
                return x > p.x && y > p.y;
            }

            constexpr bool operator<=(const Vector2<T>& p) const
            {
                return x <= p.x && y <= p.y;
            }

            constexpr bool operator>=(const Vector2<T>& p) const
            {
                return x >= p.x && y >= p.y;
            }

            constexpr bool operator!=(const Vector2<T>& p) const
            {
                return x != p.x || y != p.y;
            }

            constexpr bool operator==(const Vector2<T>& p) const
            {
                return x == p.x && y == p.y;
            }

            constexpr operator bool() const
            {
                return x || y;
            }

            template <class T2>
            constexpr operator Vector2<T2>() const
            {
                return Vector2<T2>(static_cast<T2>(x), static_cast<T2>(y));
            }

        public:
            T x, y;

    };
}

#endif

<|endoftext|>


<commit_before>#include <microscopes/models/base.hpp>
#include <microscopes/common/entity_state.hpp>
#include <microscopes/common/group_manager.hpp>
#include <microscopes/common/variadic/dataview.hpp>
#include <microscopes/common/util.hpp>
#include <microscopes/common/typedefs.hpp>
#include <microscopes/common/assert.hpp>
#include <microscopes/io/schema.pb.h>
#include <distributions/special.hpp>
#include <distributions/models/dd.hpp>

#include <cmath>
#include <vector>
#include <set>
#include <functional>
#include <map>
#include <memory>
#include <sstream>
#include <utility>
#include <stdexcept>

namespace microscopes {
namespace lda {

typedef std::vector<std::shared_ptr<models::group>> group_type;

class model_definition {
public:
    model_definition(size_t n, size_t v)
        : n_(n), v_(v)
    {
        MICROSCOPES_DCHECK(n > 0, "no docs");
        MICROSCOPES_DCHECK(v > 0, "no terms");
    }

    std::vector<std::shared_ptr<models::hypers>>
            create_hypers() const
    {
        std::vector<common::runtime_type> ret = std::vector<common::runtime_type>();
    }

    inline size_t n() const { return n_; }
    inline size_t v() const { return v_; }
private:
    size_t n_;
    size_t v_;
};

class state {
public:
    // Quick and dirty constructor for Shuyo implementation.
    state(const model_definition &def,
        float alpha,
        float beta,
        float gamma,
        const std::vector<std::vector<size_t>> &docs,
        common::rng_t &rng)
            : alpha_(alpha), beta_(beta), gamma_(gamma) {
        V = def.v();
        M = def.n();
        rng_ = rng;
        for(size_t i = 0; i < M; ++i) {
            using_t.push_back({{0, true}});
        }
        using_k = {{0, true}};

        x_ji = std::vector<std::vector<size_t>>(docs);
        for(size_t j = 0; j < M; ++j) {
            k_jt.push_back({0});
            n_jt.push_back({0});

            n_jtv.push_back(std::vector< std::map<size_t, size_t>>());
            for (size_t t = 0; t < using_t.size(); ++t)
            {
                std::map<size_t, size_t> term_dict;
                for (size_t i = 0; i < V; ++i)
                {
                    term_dict[i] = 0;
                }
                n_jtv[j].push_back(term_dict);
            }
        }

        m = 0;
        m_k = std::vector<size_t> {1};
        n_k = std::vector<float> {beta_ * V};

        std::map<size_t, size_t> term_count;
        for (size_t i = 0; i < V; ++i)
        {
            term_count[i] = 0;
        }
        n_kv.push_back(term_count);

        for(size_t i=0; i < docs.size(); i++){

            t_ji.push_back(std::vector<size_t>(docs[i].size(), 0));
        }

    }

    void
    inference(){
        // for j, x_i in enumerate(self.x_ji):
        //     for i in xrange(len(x_i)):
        //         self.sampling_t(j, i)
        // for j in xrange(self.M):
        //     for t in self.using_t[j]:
        //         if t != 0: self.sampling_k(j, t)
    }

    void
    sampling_t(size_t j, size_t i){
        leave_from_table(j, i);
        size_t v = x_ji[j][i];
        std::vector<float> f_k = calc_f_k(v);

        // assert f_k[0] == 0 # f_k[0] is a dummy and will be erased
        std::vector<float> p_t = calc_table_posterior(j, f_k);
        // if len(p_t) > 1 and p_t[1] < 0: self.dump()
        size_t word = common::util::sample_discrete(p_t, rng_);
        size_t t_new = using_t[j][word];
        if (t_new == 0)
        {
            // float p_k = calc_dish_posterior_w(f_k);
            // k_new = self.using_k[numpy.random.multinomial(1, p_k).argmax()]
            // if k_new == 0:
            //     k_new = self.add_new_dish()
            // t_new = self.add_new_table(j, k_new)
        }

    }

private:
    // std::vector<float>
    // calc_dish_posterior_w(std::vector<float> f_k){
    //     std::map<size_t, float> p_k_map;
    //     for(auto k: using_k){
    //         p_k_map[k] = m_k[k] + f_k[k];
    //     }
    //     float sum_p_k = 0;
    //     for(auto& kv: p_k_map){
    //         p_k_map += kv.second;
    //     }
    //     std::vector<float> p_k;
    //     for (size_t i = 0; i < p_k_map.size(); ++i)
    //     {
    //         p_k.push_back(p_k_map[i] / sum_p_k);
    //     }
    //     return p_k;
    // }

    std::vector<float>
    calc_table_posterior(size_t j, std::vector<float> f_k){
        std::map<size_t, bool> using_table = using_t[j];
        std::map<size_t, float> p_t_map;
        for(auto& kv: using_table){
            p_t_map[kv.first] = n_jt[j][kv.first] + f_k[k_jt[j][kv.first]];
        }
        float p_x_ji = gamma_ / (float)V;
        for (size_t k = 0; k < f_k.size(); ++k)
        {
            p_x_ji += m_k[k] * f_k[k];
        }
        float sum_p_t = 0;
        for(auto& kv: p_t_map){
            sum_p_t += kv.second;
        }
        std::vector<float> p_t;
        for (size_t i = 0; i < p_t_map.size(); ++i)
        {
            p_t.push_back(p_t_map[i] / sum_p_t);
        }
        return p_t;
    }

    void
    leave_from_table(size_t j, size_t i){
        size_t t = t_ji[j][i];
        if (t > 0)
        {
            size_t k = k_jt[j][t];
            // decrease counters
            size_t v = x_ji[j][i];
            n_kv[k][v] -= 1;
            n_k[k] -= 1;
            n_jt[j][t] -= 1;
            n_jtv[j][t][v] -= 1;

            if (n_jt[j][t] == 0)
            {
                remove_table(j, t);
            }
        }
    }

    void
    remove_table(size_t j, size_t t){
        size_t k = k_jt[j][t];
        using_t[j].erase(t);
        m_k[k] -= 1;
        m -= 1;
        if (m_k[k] == 0)
        {
            using_k.erase(k);
        }
    }

    std::vector<float>
    calc_f_k(size_t v){
        std::vector<float> f_k {};

        for (size_t k=0; k < n_kv.size(); k++)
        {
            f_k.push_back(n_kv[k][v] / n_k[k]);
        }

        return f_k;
    }

    size_t V; // Vocabulary size
    size_t M; // Num documents
    size_t m;
    float alpha_;
    float beta_;
    float gamma_;
    common::rng_t rng_;
    std::vector<std::map<size_t, bool>> using_t;
    std::map<size_t, bool> using_k;
    std::vector<std::vector<size_t>> x_ji;
    std::vector<std::vector<size_t>> k_jt;
    std::vector<std::vector<size_t>> n_jt;
    std::vector<std::vector<std::map<size_t, size_t>>> n_jtv;
    std::vector<size_t> m_k;
    std::vector<float> n_k;
    std::vector<std::map<size_t, size_t>> n_kv;
    std::vector<std::vector<size_t>> t_ji;

};

}
}<commit_msg>Add calc_table_posterior and add_new_dish<commit_after>#include <microscopes/models/base.hpp>
#include <microscopes/common/entity_state.hpp>
#include <microscopes/common/group_manager.hpp>
#include <microscopes/common/variadic/dataview.hpp>
#include <microscopes/common/util.hpp>
#include <microscopes/common/typedefs.hpp>
#include <microscopes/common/assert.hpp>
#include <microscopes/io/schema.pb.h>
#include <distributions/special.hpp>
#include <distributions/models/dd.hpp>

#include <cmath>
#include <vector>
#include <set>
#include <functional>
#include <map>
#include <memory>
#include <sstream>
#include <utility>
#include <stdexcept>

namespace microscopes {
namespace lda {

typedef std::vector<std::shared_ptr<models::group>> group_type;

template<typename T> void
removeFirst(std::vector<T> &v, T element){
    auto it = std::find(v.begin(),v.end(), element);
    if (it != v.end()) {
      v.erase(it);
    }
}

class model_definition {
public:
    model_definition(size_t n, size_t v)
        : n_(n), v_(v)
    {
        MICROSCOPES_DCHECK(n > 0, "no docs");
        MICROSCOPES_DCHECK(v > 0, "no terms");
    }

    std::vector<std::shared_ptr<models::hypers>>
            create_hypers() const
    {
        std::vector<common::runtime_type> ret = std::vector<common::runtime_type>();
    }

    inline size_t n() const { return n_; }
    inline size_t v() const { return v_; }
private:
    size_t n_;
    size_t v_;
};

class state {
public:
    // Quick and dirty constructor for Shuyo implementation.
    state(const model_definition &def,
        float alpha,
        float beta,
        float gamma,
        const std::vector<std::vector<size_t>> &docs,
        common::rng_t &rng)
            : alpha_(alpha), beta_(beta), gamma_(gamma) {
        V = def.v();
        M = def.n();
        rng_ = rng;
        for(size_t i = 0; i < M; ++i) {
            using_t.push_back({0});
        }
        using_k = {0};

        x_ji = std::vector<std::vector<size_t>>(docs);
        for(size_t j = 0; j < M; ++j) {
            k_jt.push_back({0});
            n_jt.push_back({0});

            n_jtv.push_back(std::vector< std::map<size_t, size_t>>());
            for (size_t t = 0; t < using_t.size(); ++t)
            {
                std::map<size_t, size_t> term_dict;
                for (size_t i = 0; i < V; ++i)
                {
                    term_dict[i] = 0;
                }
                n_jtv[j].push_back(term_dict);
            }
        }

        m = 0;
        m_k = std::vector<size_t> {1};
        n_k = std::vector<float> {beta_ * V};

        std::map<size_t, size_t> term_count;
        for (size_t i = 0; i < V; ++i)
        {
            term_count[i] = 0;
        }
        n_kv.push_back(term_count);

        for(size_t i=0; i < docs.size(); i++){

            t_ji.push_back(std::vector<size_t>(docs[i].size(), 0));
        }

    }

    void
    inference(){
        // for j, x_i in enumerate(self.x_ji):
        //     for i in xrange(len(x_i)):
        //         self.sampling_t(j, i)
        // for j in xrange(self.M):
        //     for t in self.using_t[j]:
        //         if t != 0: self.sampling_k(j, t)
    }

    void
    sampling_t(size_t j, size_t i){
        leave_from_table(j, i);
        size_t v = x_ji[j][i];
        std::vector<float> f_k = calc_f_k(v);

        // assert f_k[0] == 0 # f_k[0] is a dummy and will be erased
        std::vector<float> p_t = calc_table_posterior(j, f_k);
        // if len(p_t) > 1 and p_t[1] < 0: self.dump()
        size_t word = common::util::sample_discrete(p_t, rng_);
        size_t t_new = using_t[j][word];
        if (t_new == 0)
        {
            std::vector<float> p_k = calc_dish_posterior_w(f_k);
            size_t topic_index = common::util::sample_discrete(p_t, rng_);
            size_t k_new = using_k[topic_index];
            if (k_new == 0)
            {
                add_new_dish();
            }
            add_new_table(j, k_new);
        }

    }

private:
    void
    add_new_dish(){
        size_t k_new = using_k.size();
        for (int i = 0; i < using_k.size(); ++i)
        {
            if (i != using_k[i])
            {
                k_new = i;
                break;
            }
        }
        if (k_new == using_k.size())
        {
            n_k.push_back(n_k[0]);
            m_k.push_back(m_k[0]);
            n_kv.push_back(std::map<size_t, size_t>());
        }

        using_k.insert(using_k.begin()+k_new, k_new);
        n_k[k_new] = beta_ * (float)V;
        m_k[k_new] = 0;

        for (size_t i = 0; i < V; ++i)
        {
            n_kv[k_new][i] = 0;
        }

    }

    void
    add_new_table(size_t j, size_t k_new)
    {
        // assert k_new in self.using_k
        // for t_new, t in enumerate(self.using_t[j]):
        //     if t_new != t: break
        // else:
        //     t_new = len(self.using_t[j])
        //     self.n_jt[j].resize(t_new+1)
        //     self.k_jt[j].resize(t_new+1)
        //     self.n_jtv[j].append(None)

        // self.using_t[j].insert(t_new, t_new)
        // self.n_jt[j][t_new] = 0  # to make sure
        // self.n_jtv[j][t_new] = DefaultDict(0)

        // self.k_jt[j][t_new] = k_new
        // self.m_k[k_new] += 1
        // self.m += 1

        // return t_new

    }

    std::vector<float>
    calc_dish_posterior_w(std::vector<float> &f_k){
        std::map<size_t, float> p_k_map;
        for(auto& k: using_k){
            p_k_map[k] = m_k[k] + f_k[k];
        }
        float sum_p_k = 0;
        for(auto& kv: p_k_map){
            sum_p_k += kv.second;
        }
        std::vector<float> p_k;
        for (size_t i = 0; i < p_k_map.size(); ++i)
        {
            p_k.push_back(p_k_map[i] / sum_p_k);
        }
        return p_k;
    }

    std::vector<float>
    calc_table_posterior(size_t j, std::vector<float> &f_k){
        std::vector<size_t> using_table = using_t[j];
        std::vector<float> p_t;
        for(auto& p: using_table){
            p_t.push_back(n_jt[j][p] + f_k[k_jt[j][p]]);
        }
        float p_x_ji = gamma_ / (float)V;
        for (size_t k = 0; k < f_k.size(); ++k)
        {
            p_x_ji += m_k[k] * f_k[k];
        }
        float sum_p_t = 0;
        for(auto& kv: p_t){
            sum_p_t += kv;
        }
        for (int i = 0; i < p_t.size(); ++i)
        {
            p_t[i] /= sum_p_t;
        }
        return p_t ;
    }

    void
    leave_from_table(size_t j, size_t i){
        size_t t = t_ji[j][i];
        if (t > 0)
        {
            size_t k = k_jt[j][t];
            // decrease counters
            size_t v = x_ji[j][i];
            n_kv[k][v] -= 1;
            n_k[k] -= 1;
            n_jt[j][t] -= 1;
            n_jtv[j][t][v] -= 1;

            if (n_jt[j][t] == 0)
            {
                remove_table(j, t);
            }
        }
    }

    void
    remove_table(size_t j, size_t t){
        size_t k = k_jt[j][t];
        removeFirst(using_t[j], t);
        m_k[k] -= 1;
        m -= 1;
        if (m_k[k] == 0)
        {
            removeFirst(using_k, k);
        }
    }

    std::vector<float>
    calc_f_k(size_t v){
        std::vector<float> f_k {};

        for (size_t k=0; k < n_kv.size(); k++)
        {
            f_k.push_back(n_kv[k][v] / n_k[k]);
        }

        return f_k;
    }

    size_t V; // Vocabulary size
    size_t M; // Num documents
    size_t m;
    float alpha_;
    float beta_;
    float gamma_;
    common::rng_t rng_;
    std::vector<std::vector<size_t>> using_t;
    std::vector<size_t> using_k;
    std::vector<std::vector<size_t>> x_ji;
    std::vector<std::vector<size_t>> k_jt;
    std::vector<std::vector<size_t>> n_jt;
    std::vector<std::vector<std::map<size_t, size_t>>> n_jtv;
    std::vector<size_t> m_k;
    std::vector<float> n_k;
    std::vector<std::map<size_t, size_t>> n_kv;
    std::vector<std::vector<size_t>> t_ji;

};

}
}<|endoftext|>