text:
// Copyright 2015-2018 RWTH Aachen University
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/*
* AST class that represets an abstract syntax tree
*
* Author: Sascha Schmerling
* Created: 2015/06/02
*/

#pragma once

#include <iostream>
#include <iomanip>
#include <vector>
#include <boost/variant.hpp>
#include <boost/algorithm/string.hpp>

#include "options.hh"

using namespace std;

class Ast;
class AstVisitor;
class AstVisitableNode;
class AstOperation;
class AstConstant;
class AstId;
class AstFunction;

//Visitor pattern
//base class for the visitor that will used to get the type of a node
class AstVisitor {
    public:
        virtual void visit(AstOperation &) = 0;
        virtual void visit(AstConstant &) = 0;
        virtual void visit(AstId &) = 0;
        virtual void visit(AstFunction &) = 0;
        virtual void visit(Ast &) = 0;

        virtual ~AstVisitor() {};
};

enum class AstNodeType : uint8_t {
    Operation,
    Constant,
    Id,
    Function
};

//Visitor pattern
//base class that allows use to traverse through the AST
//with a generic base type
class AstVisitableNode  {
    public:
        virtual void accept(AstVisitor &v) = 0;
        virtual ~AstVisitableNode() {}
        AstNodeType nodeType;
};

class Ast  {
    public:
        AstVisitableNode *root;

        Ast(AstVisitableNode *initRoot)  {
            root = initRoot;
        }
};

//all types with that will have a binary node (two children)
enum class AstOperationType : uint8_t {
    ELIMINATED_NOT, //status that eliminated NOTs will become
    NOT,
    AND,
    OR,
    EQUAL,
    NEQ,
    LESS,
    LEQ,
    GREATER,
    GEQ,
    IS_TRUE,
    IS_FALSE,
};

//a node that represents an operation with a list of children
class AstOperation : public AstVisitableNode {
    public:
        AstOperationType type;

        //constructor for a operation with only one child
        AstOperation(AstOperationType initType, AstVisitableNode *left)  {
            nodeType = AstNodeType::Operation;
            type = initType;

            addChild(left);
        }

        //constructor for a binary operation (two children)
        AstOperation(AstOperationType initType, AstVisitableNode *left, AstVisitableNode *right)  {
            nodeType = AstNodeType::Operation;
            type = initType;

            addChild(left);
            addChild(right);
        }

        uint8_t getNumberOfChildren()  {
            return children.size();
        }

        vector<AstVisitableNode *> &getChildren() {
            return children;
        }

        AstVisitableNode *getChild(uint8_t pos)  {
            return children.at(pos);
        }

        void setChild(uint8_t pos, AstVisitableNode *node)  {
            children.at(pos) = node;
        }

        void addChild(AstVisitableNode *child)  {
            return children.push_back(child);
        }

        void accept(AstVisitor &visitor)  {
            visitor.visit(*this);
        }

        //delete all children when the node gets destroyed
        ~AstOperation()  {
            for(vector<AstVisitableNode *>::iterator it = children.begin(); it != children.end(); ++it)
                delete *it;
        }

        vector<AstVisitableNode *> children;
};

enum class AstValueType : uint8_t {
	INT8 = 0,
	INT16 = 1,
	INT32 = 2,
	INT64 = 3,
	UINT8 = 4,
	UINT16 = 5,
	UINT32 = 6,
	UINT64 = 7,
	Float = 8,
	Boolean = 9,
	String = 10,
	EnumValue = 11,
    Unknown = 12,
    Integer = 13,
    Id = 14, //just used for the IS_TRUE, IS_FALSE compression feature
};

typedef boost::variant<bool, int64_t, double, string> AstValue;

//Ast leaf for a number
class AstConstant : public AstVisitableNode  {
    public:
        //create a tagged union for the type
        //we need to check every time the type
        //before we access the union, since
        //else we could recieve wrong values
        AstValueType type;
        AstValue value;
        id_type enumValuePosition;

        AstConstant(AstValueType type, AstValue value) : type(type), value(value) {
            nodeType = AstNodeType::Constant;
        }

        void accept(AstVisitor &visitor)  {
            visitor.visit(*this);
        }
};

//Ast leaf for an id
class AstId : public AstVisitableNode  {
    public:
        AstValueType type;
        string name;
        id_type position;
        bool isEnum;

        AstId(AstValueType type, string name) : type(type), name(name), position(0)  {
            nodeType = AstNodeType::Id;
        }

        void accept(AstVisitor &visitor)  {
            visitor.visit(*this);
        }
};

//Ast leaf for a function
class AstFunction : public AstVisitableNode  {
    public:
        AstValueType type;
        string name;
        vector<AstConstant *> parameters;
        id_type position;

        AstFunction(string callString) : position(0)  {
            nodeType = AstNodeType::Function;
            type = AstValueType::Boolean; //currently just functions with a boolean return type are supported

            //extract the function id from the callString
            name = callString.substr(0, callString.find('('));

            string rawParameters = callString.substr(callString.find('(') + 1); //remove the left bracket
            rawParameters = rawParameters.substr(0, rawParameters.find(')')); //remove the right bracket
            for(size_t curPos = 0; curPos < rawParameters.size(); )  {
                //get the current raw parameter
                string curRawParameter;
                size_t commaPos = rawParameters.find(',', curPos);
                if(commaPos != string::npos)  { //get next param (comma is seperator)
                    curRawParameter = rawParameters.substr(curPos, commaPos - curPos);
                    curPos = commaPos + 1;
                }
                else   {//last parameter, since no following comma
                    curRawParameter = rawParameters.substr(curPos, rawParameters.size());
                    curPos += curRawParameter.size();
                }
                //remove unwanted whitespaces
                boost::algorithm::trim(curRawParameter);

                //just store the param with type unknown as string
                //the preprocessor will check and convert the value
                AstConstant *param = new AstConstant(AstValueType::Unknown, curRawParameter);
                parameters.push_back(param);
            }
        }

        void accept(AstVisitor &visitor)  {
            visitor.visit(*this);
        }
};

ext: hh

max_stars_repo_name: SSICLOPS/cppl

max_issues_repo_name: SSICLOPS/cppl

max_forks_repo_name: SSICLOPS/cppl


text:
/**
 * @author Tiago de Freitas Pereira <tiago.pereira@idiap.ch>
 * @date Sun 01 Fev 09:40:00 2015
 *
 * @brief Python API for bob::learn::em
 *
 * Copyright (C) 2011-2014 Idiap Research Institute, Martigny, Switzerland
 */

#include "main.h"
#include <boost/make_shared.hpp>

/******************************************************************/
/************ Constructor Section *********************************/
/******************************************************************/

static int extract_GMMStats_1d(PyObject *list,
                             std::vector<boost::shared_ptr<bob::learn::em::GMMStats> >& training_data)
{
  for (int i=0; i<PyList_GET_SIZE(list); i++){

    PyBobLearnEMGMMStatsObject* stats;
    if (!PyArg_Parse(PyList_GetItem(list, i), "O!", &PyBobLearnEMGMMStats_Type, &stats)){
      PyErr_Format(PyExc_RuntimeError, "Expected GMMStats objects");
      return -1;
    }
    training_data.push_back(stats->cxx);
  }
  return 0;
}

static int extract_GMMStats_2d(PyObject *list,
                             std::vector<std::vector<boost::shared_ptr<bob::learn::em::GMMStats> > >& training_data)
{
  for (int i=0; i<PyList_GET_SIZE(list); i++)
  {
    PyObject* another_list;
    if(!PyArg_Parse(PyList_GetItem(list, i), "O!", &PyList_Type, &another_list)){
      PyErr_Format(PyExc_RuntimeError, "Expected a list of lists of GMMStats objects [[GMMStats,GMMStats],[GMMStats,GMMStats].....[GMMStats,GMMStats]]");
      return -1;
    }

    std::vector<boost::shared_ptr<bob::learn::em::GMMStats> > another_training_data;
    for (int j=0; j<PyList_GET_SIZE(another_list); j++){

      PyBobLearnEMGMMStatsObject* stats;
      if (!PyArg_Parse(PyList_GetItem(another_list, j), "O!", &PyBobLearnEMGMMStats_Type, &stats)){
        PyErr_Format(PyExc_RuntimeError, "Expected GMMStats objects");
        return -1;
      }
      another_training_data.push_back(stats->cxx);
    }
    training_data.push_back(another_training_data);
  }
  return 0;
}

template <int N>
static PyObject* vector_as_list(const std::vector<blitz::Array<double,N> >& vec)
{
  PyObject* list = PyList_New(vec.size());
  for(size_t i=0; i<vec.size(); i++){
    blitz::Array<double,N> numpy_array = vec[i];
    PyObject* numpy_py_object = PyBlitzArrayCxx_AsNumpy(numpy_array);
    PyList_SET_ITEM(list, i, numpy_py_object);
  }
  return list;
}

template <int N>
int list_as_vector(PyObject* list, std::vector<blitz::Array<double,N> >& vec)
{
  for (int i=0; i<PyList_GET_SIZE(list); i++)
  {
    PyBlitzArrayObject* blitz_object;
    if (!PyArg_Parse(PyList_GetItem(list, i), "O&", &PyBlitzArray_Converter, &blitz_object)){
      PyErr_Format(PyExc_RuntimeError, "Expected numpy array object");
      return -1;
    }
    auto blitz_object_ = make_safe(blitz_object);
    vec.push_back(*PyBlitzArrayCxx_AsBlitz<double,N>(blitz_object));
  }
  return 0;
}

static auto JFATrainer_doc = bob::extension::ClassDoc(
  BOB_EXT_MODULE_PREFIX ".JFATrainer",
  "Trains a Joint Factor Analysis (:ref:`JFA <jfa>`) on top of GMMs"
  "",
  ""
).add_constructor(
  bob::extension::FunctionDoc(
    "__init__",
    "Constructor. Builds a new JFATrainer",
    "",
    true
  )
  .add_prototype("other","")
  .add_prototype("","")
  .add_parameter("other", ":py:class:`bob.learn.em.JFATrainer`", "A JFATrainer object to be copied.")
);

static int PyBobLearnEMJFATrainer_init_copy(PyBobLearnEMJFATrainerObject* self, PyObject* args, PyObject* kwargs) {

  char** kwlist = JFATrainer_doc.kwlist(0);
  PyBobLearnEMJFATrainerObject* o;
  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!", kwlist, &PyBobLearnEMJFATrainer_Type, &o)){
    JFATrainer_doc.print_usage();
    return -1;
  }

  self->cxx.reset(new bob::learn::em::JFATrainer(*o->cxx));
  return 0;
}

static int PyBobLearnEMJFATrainer_init(PyBobLearnEMJFATrainerObject* self, PyObject* args, PyObject* kwargs) {
  BOB_TRY

  // get the number of command line arguments
  int nargs = (args?PyTuple_Size(args):0) + (kwargs?PyDict_Size(kwargs):0);

  switch(nargs){
    case 0:{
      self->cxx.reset(new bob::learn::em::JFATrainer());
      return 0;
    }
    case 1:{
      // If the constructor input is JFATrainer object
      return PyBobLearnEMJFATrainer_init_copy(self, args, kwargs);
    }
    default:{
      PyErr_Format(PyExc_RuntimeError, "number of arguments mismatch - %s requires only 0 and 1 argument, but you provided %d (see help)", Py_TYPE(self)->tp_name, nargs);
      JFATrainer_doc.print_usage();
      return -1;
    }
  }
  BOB_CATCH_MEMBER("cannot create JFATrainer", -1)
  return 0;
}

static void PyBobLearnEMJFATrainer_delete(PyBobLearnEMJFATrainerObject* self) {
  self->cxx.reset();
  Py_TYPE(self)->tp_free((PyObject*)self);
}

int PyBobLearnEMJFATrainer_Check(PyObject* o) {
  return PyObject_IsInstance(o, reinterpret_cast<PyObject*>(&PyBobLearnEMJFATrainer_Type));
}

static PyObject* PyBobLearnEMJFATrainer_RichCompare(PyBobLearnEMJFATrainerObject* self, PyObject* other, int op) {
  BOB_TRY

  if (!PyBobLearnEMJFATrainer_Check(other)) {
    PyErr_Format(PyExc_TypeError, "cannot compare `%s' with `%s'", Py_TYPE(self)->tp_name, Py_TYPE(other)->tp_name);
    return 0;
  }
  auto other_ = reinterpret_cast<PyBobLearnEMJFATrainerObject*>(other);
  switch (op) {
    case Py_EQ:
      if (*self->cxx==*other_->cxx) Py_RETURN_TRUE; else Py_RETURN_FALSE;
    case Py_NE:
      if (*self->cxx==*other_->cxx) Py_RETURN_FALSE; else Py_RETURN_TRUE;
    default:
      Py_INCREF(Py_NotImplemented);
      return Py_NotImplemented;
  }
  BOB_CATCH_MEMBER("cannot compare JFATrainer objects", 0)
}

/******************************************************************/
/************ Variables Section ***********************************/
/******************************************************************/

static auto acc_v_a1 = bob::extension::VariableDoc(
  "acc_v_a1",
  "array_like <float, 3D>",
  "Accumulator updated during the E-step",
  ""
);
PyObject* PyBobLearnEMJFATrainer_get_acc_v_a1(PyBobLearnEMJFATrainerObject* self, void*){
  BOB_TRY
  return PyBlitzArrayCxx_AsConstNumpy(self->cxx->getAccVA1());
  BOB_CATCH_MEMBER("acc_v_a1 could not be read", 0)
}
int PyBobLearnEMJFATrainer_set_acc_v_a1(PyBobLearnEMJFATrainerObject* self, PyObject* value, void*){
  BOB_TRY
  PyBlitzArrayObject* input;
  if (!PyBlitzArray_Converter(value, &input)){
    PyErr_Format(PyExc_RuntimeError, "%s %s expects a 3D array of floats", Py_TYPE(self)->tp_name, acc_v_a1.name());
    return -1;
  }
  auto o_ = make_safe(input);

  // perform check on the input
  if (input->type_num != NPY_FLOAT64){
    PyErr_Format(PyExc_TypeError, "`%s' only supports 64-bit float arrays for input array `%s`", Py_TYPE(self)->tp_name, acc_v_a1.name());
    return -1;
  }

  if (input->ndim != 3){
    PyErr_Format(PyExc_TypeError, "`%s' only processes 3D arrays of float64 for `%s`", Py_TYPE(self)->tp_name, acc_v_a1.name());
    return -1;
  }

  if (input->shape[0] != (Py_ssize_t)self->cxx->getAccVA1().extent(0) && input->shape[1] != (Py_ssize_t)self->cxx->getAccVA1().extent(1) && input->shape[2] != (Py_ssize_t)self->cxx->getAccVA1().extent(2)) {
    PyErr_Format(PyExc_TypeError, "`%s' 3D `input` array should have the shape [%" PY_FORMAT_SIZE_T "d, %" PY_FORMAT_SIZE_T "d, %" PY_FORMAT_SIZE_T "d] not [%" PY_FORMAT_SIZE_T "d, %" PY_FORMAT_SIZE_T "d, %" PY_FORMAT_SIZE_T "d] for `%s`", Py_TYPE(self)->tp_name, (Py_ssize_t)self->cxx->getAccVA1().extent(0), (Py_ssize_t)self->cxx->getAccVA1().extent(1), (Py_ssize_t)self->cxx->getAccVA1().extent(2), (Py_ssize_t)input->shape[0], (Py_ssize_t)input->shape[1], (Py_ssize_t)input->shape[2], acc_v_a1.name());
    return -1;
  }

  auto b = PyBlitzArrayCxx_AsBlitz<double,3>(input, "acc_v_a1");
  if (!b) return -1;
  self->cxx->setAccVA1(*b);
  return 0;
  BOB_CATCH_MEMBER("acc_v_a1 could not be set", -1)
}

static auto acc_v_a2 = bob::extension::VariableDoc(
  "acc_v_a2",
  "array_like <float, 2D>",
  "Accumulator updated during the E-step",
  ""
);
PyObject* PyBobLearnEMJFATrainer_get_acc_v_a2(PyBobLearnEMJFATrainerObject* self, void*){
  BOB_TRY
  return PyBlitzArrayCxx_AsConstNumpy(self->cxx->getAccVA2());
  BOB_CATCH_MEMBER("acc_v_a2 could not be read", 0)
}
int PyBobLearnEMJFATrainer_set_acc_v_a2(PyBobLearnEMJFATrainerObject* self, PyObject* value, void*){
  BOB_TRY
  PyBlitzArrayObject* input;
  if (!PyBlitzArray_Converter(value, &input)){
    PyErr_Format(PyExc_RuntimeError, "%s %s expects a 2D array of floats", Py_TYPE(self)->tp_name, acc_v_a2.name());
    return -1;
  }
  auto o_ = make_safe(input);

  // perform check on the input
  if (input->type_num != NPY_FLOAT64){
    PyErr_Format(PyExc_TypeError, "`%s' only supports 64-bit float arrays for input array `%s`", Py_TYPE(self)->tp_name, acc_v_a2.name());
    return -1;
  }

  if (input->ndim != 2){
    PyErr_Format(PyExc_TypeError, "`%s' only processes 2D arrays of float64 for `%s`", Py_TYPE(self)->tp_name, acc_v_a2.name());
    return -1;
  }

  if (input->shape[0] != (Py_ssize_t)self->cxx->getAccVA2().extent(0) && input->shape[1] != (Py_ssize_t)self->cxx->getAccVA2().extent(1)) {
    PyErr_Format(PyExc_TypeError, "`%s' 2D `input` array should have the shape [%" PY_FORMAT_SIZE_T "d, %" PY_FORMAT_SIZE_T "d] not [%" PY_FORMAT_SIZE_T "d, %" PY_FORMAT_SIZE_T "d] for `%s`", Py_TYPE(self)->tp_name, (Py_ssize_t)self->cxx->getAccVA2().extent(0), (Py_ssize_t)self->cxx->getAccVA2().extent(1), input->shape[0], input->shape[1], acc_v_a2.name());
    return -1;
  }

  auto b = PyBlitzArrayCxx_AsBlitz<double,2>(input, "acc_v_a2");
  if (!b) return -1;
  self->cxx->setAccVA2(*b);
  return 0;
  BOB_CATCH_MEMBER("acc_v_a2 could not be set", -1)
}

static auto acc_u_a1 = bob::extension::VariableDoc(
  "acc_u_a1",
  "array_like <float, 3D>",
  "Accumulator updated during the E-step",
  ""
);
PyObject* PyBobLearnEMJFATrainer_get_acc_u_a1(PyBobLearnEMJFATrainerObject* self, void*){
  BOB_TRY
  return PyBlitzArrayCxx_AsConstNumpy(self->cxx->getAccUA1());
  BOB_CATCH_MEMBER("acc_u_a1 could not be read", 0)
}
int PyBobLearnEMJFATrainer_set_acc_u_a1(PyBobLearnEMJFATrainerObject* self, PyObject* value, void*){
  BOB_TRY
  PyBlitzArrayObject* input;
  if (!PyBlitzArray_Converter(value, &input)){
    PyErr_Format(PyExc_RuntimeError, "%s %s expects a 3D array of floats", Py_TYPE(self)->tp_name, acc_u_a1.name());
    return -1;
  }
  auto o_ = make_safe(input);

  // perform check on the input
  if (input->type_num != NPY_FLOAT64){
    PyErr_Format(PyExc_TypeError, "`%s' only supports 64-bit float arrays for input array `%s`", Py_TYPE(self)->tp_name, acc_u_a1.name());
    return -1;
  }

  if (input->ndim != 3){
    PyErr_Format(PyExc_TypeError, "`%s' only processes 3D arrays of float64 for `%s`", Py_TYPE(self)->tp_name, acc_u_a1.name());
    return -1;
  }

  if (input->shape[0] != (Py_ssize_t)self->cxx->getAccUA1().extent(0) && input->shape[1] != (Py_ssize_t)self->cxx->getAccUA1().extent(1) && input->shape[2] != (Py_ssize_t)self->cxx->getAccUA1().extent(2)) {
    PyErr_Format(PyExc_TypeError, "`%s' 3D `input` array should have the shape [%" PY_FORMAT_SIZE_T "d, %" PY_FORMAT_SIZE_T "d, %" PY_FORMAT_SIZE_T "d] not [%" PY_FORMAT_SIZE_T "d, %" PY_FORMAT_SIZE_T "d, %" PY_FORMAT_SIZE_T "d] for `%s`", Py_TYPE(self)->tp_name, (Py_ssize_t)self->cxx->getAccUA1().extent(0), (Py_ssize_t)self->cxx->getAccUA1().extent(1), (Py_ssize_t)self->cxx->getAccUA1().extent(2), (Py_ssize_t)input->shape[0], (Py_ssize_t)input->shape[1], (Py_ssize_t)input->shape[2], acc_u_a1.name());
    return -1;
  }

  auto b = PyBlitzArrayCxx_AsBlitz<double,3>(input, "acc_u_a1");
  if (!b) return -1;
  self->cxx->setAccUA1(*b);
  return 0;
  BOB_CATCH_MEMBER("acc_u_a1 could not be set", -1)
}

static auto acc_u_a2 = bob::extension::VariableDoc(
  "acc_u_a2",
  "array_like <float, 2D>",
  "Accumulator updated during the E-step",
  ""
);
PyObject* PyBobLearnEMJFATrainer_get_acc_u_a2(PyBobLearnEMJFATrainerObject* self, void*){
  BOB_TRY
  return PyBlitzArrayCxx_AsConstNumpy(self->cxx->getAccUA2());
  BOB_CATCH_MEMBER("acc_u_a2 could not be read", 0)
}
int PyBobLearnEMJFATrainer_set_acc_u_a2(PyBobLearnEMJFATrainerObject* self, PyObject* value, void*){
  BOB_TRY
  PyBlitzArrayObject* input;
  if (!PyBlitzArray_Converter(value, &input)){
    PyErr_Format(PyExc_RuntimeError, "%s %s expects a 2D array of floats", Py_TYPE(self)->tp_name, acc_u_a2.name());
    return -1;
  }
  auto o_ = make_safe(input);

  // perform check on the input
  if (input->type_num != NPY_FLOAT64){
    PyErr_Format(PyExc_TypeError, "`%s' only supports 64-bit float arrays for input array `%s`", Py_TYPE(self)->tp_name, acc_u_a2.name());
    return -1;
  }

  if (input->ndim != 2){
    PyErr_Format(PyExc_TypeError, "`%s' only processes 2D arrays of float64 for `%s`", Py_TYPE(self)->tp_name, acc_u_a2.name());
    return -1;
  }

  if (input->shape[0] != (Py_ssize_t)self->cxx->getAccUA2().extent(0) && input->shape[1] != (Py_ssize_t)self->cxx->getAccUA2().extent(1)) {
    PyErr_Format(PyExc_TypeError, "`%s' 3D `input` array should have the shape [%" PY_FORMAT_SIZE_T "d, %" PY_FORMAT_SIZE_T "d] not [%" PY_FORMAT_SIZE_T "d, %" PY_FORMAT_SIZE_T "d] for `%s`", Py_TYPE(self)->tp_name, (Py_ssize_t)self->cxx->getAccUA2().extent(0), (Py_ssize_t)self->cxx->getAccUA2().extent(1), input->shape[0], input->shape[1], acc_u_a2.name());
    return -1;
  }

  auto b = PyBlitzArrayCxx_AsBlitz<double,2>(input, "acc_u_a2");
  if (!b) return -1;
  self->cxx->setAccUA2(*b);
  return 0;
  BOB_CATCH_MEMBER("acc_u_a2 could not be set", -1)
}

static auto acc_d_a1 = bob::extension::VariableDoc(
  "acc_d_a1",
  "array_like <float, 1D>",
  "Accumulator updated during the E-step",
  ""
);
PyObject* PyBobLearnEMJFATrainer_get_acc_d_a1(PyBobLearnEMJFATrainerObject* self, void*){
  BOB_TRY
  return PyBlitzArrayCxx_AsConstNumpy(self->cxx->getAccDA1());
  BOB_CATCH_MEMBER("acc_d_a1 could not be read", 0)
}
int PyBobLearnEMJFATrainer_set_acc_d_a1(PyBobLearnEMJFATrainerObject* self, PyObject* value, void*){
  BOB_TRY
  PyBlitzArrayObject* input;
  if (!PyBlitzArray_Converter(value, &input)){
    PyErr_Format(PyExc_RuntimeError, "%s %s expects a 1D array of floats", Py_TYPE(self)->tp_name, acc_d_a1.name());
    return -1;
  }
  auto o_ = make_safe(input);

  // perform check on the input
  if (input->type_num != NPY_FLOAT64){
    PyErr_Format(PyExc_TypeError, "`%s' only supports 64-bit float arrays for input array `%s`", Py_TYPE(self)->tp_name, acc_d_a1.name());
    return -1;
  }

  if (input->ndim != 1){
    PyErr_Format(PyExc_TypeError, "`%s' only processes 1D arrays of float64 for `%s`", Py_TYPE(self)->tp_name, acc_d_a1.name());
    return -1;
  }

  if (input->shape[0] != (Py_ssize_t)self->cxx->getAccDA1().extent(0)) {
    PyErr_Format(PyExc_TypeError, "`%s' 1D `input` array should have %" PY_FORMAT_SIZE_T "d elements, not %" PY_FORMAT_SIZE_T "d for `%s`", Py_TYPE(self)->tp_name, (Py_ssize_t)self->cxx->getAccDA1().extent(0), input->shape[0], acc_d_a1.name());
    return -1;
  }

  auto b = PyBlitzArrayCxx_AsBlitz<double,1>(input, "acc_d_a1");
  if (!b) return -1;
  self->cxx->setAccDA1(*b);
  return 0;
  BOB_CATCH_MEMBER("acc_d_a1 could not be set", -1)
}

static auto acc_d_a2 = bob::extension::VariableDoc(
  "acc_d_a2",
  "array_like <float, 1D>",
  "Accumulator updated during the E-step",
  ""
);
PyObject* PyBobLearnEMJFATrainer_get_acc_d_a2(PyBobLearnEMJFATrainerObject* self, void*){
  BOB_TRY
  return PyBlitzArrayCxx_AsConstNumpy(self->cxx->getAccDA2());
  BOB_CATCH_MEMBER("acc_d_a2 could not be read", 0)
}
int PyBobLearnEMJFATrainer_set_acc_d_a2(PyBobLearnEMJFATrainerObject* self, PyObject* value, void*){
  BOB_TRY
  PyBlitzArrayObject* input;
  if (!PyBlitzArray_Converter(value, &input)){
    PyErr_Format(PyExc_RuntimeError, "%s %s expects a 1D array of floats", Py_TYPE(self)->tp_name, acc_d_a1.name());
    return -1;
  }
  auto o_ = make_safe(input);

  // perform check on the input
  if (input->type_num != NPY_FLOAT64){
    PyErr_Format(PyExc_TypeError, "`%s' only supports 64-bit float arrays for input array `%s`", Py_TYPE(self)->tp_name, acc_d_a2.name());
    return -1;
  }

  if (input->ndim != 1){
    PyErr_Format(PyExc_TypeError, "`%s' only processes 1D arrays of float64 for `%s`", Py_TYPE(self)->tp_name, acc_d_a2.name());
    return -1;
  }

  if (input->shape[0] != (Py_ssize_t)self->cxx->getAccDA2().extent(0)) {
    PyErr_Format(PyExc_TypeError, "`%s' 1D `input` array should have %" PY_FORMAT_SIZE_T "d elements, not %" PY_FORMAT_SIZE_T "d for `%s`", Py_TYPE(self)->tp_name, (Py_ssize_t)self->cxx->getAccDA2().extent(0), input->shape[0], acc_d_a2.name());
    return -1;
  }

  auto b = PyBlitzArrayCxx_AsBlitz<double,1>(input, "acc_d_a2");
  if (!b) return -1;
  self->cxx->setAccDA2(*b);
  return 0;
  BOB_CATCH_MEMBER("acc_d_a2 could not be set", -1)
}

static auto __X__ = bob::extension::VariableDoc(
  "__X__",
  "list",
  "",
  ""
);
PyObject* PyBobLearnEMJFATrainer_get_X(PyBobLearnEMJFATrainerObject* self, void*){
  BOB_TRY
  return vector_as_list(self->cxx->getX());
  BOB_CATCH_MEMBER("__X__ could not be read", 0)
}
int PyBobLearnEMJFATrainer_set_X(PyBobLearnEMJFATrainerObject* self, PyObject* value, void*){
  BOB_TRY

  // Parses input arguments in a single shot
  if (!PyList_Check(value)){
    PyErr_Format(PyExc_TypeError, "Expected a list in `%s'", __X__.name());
    return -1;
  }

  std::vector<blitz::Array<double,2> > data;
  if(list_as_vector(value ,data)==0){
    self->cxx->setX(data);
  }

  return 0;
  BOB_CATCH_MEMBER("__X__ could not be written", -1)
}

static auto __Y__ = bob::extension::VariableDoc(
  "__Y__",
  "list",
  "",
  ""
);
PyObject* PyBobLearnEMJFATrainer_get_Y(PyBobLearnEMJFATrainerObject* self, void*){
  BOB_TRY
  return vector_as_list(self->cxx->getY());
  BOB_CATCH_MEMBER("__Y__ could not be read", 0)
}
int PyBobLearnEMJFATrainer_set_Y(PyBobLearnEMJFATrainerObject* self, PyObject* value, void*){
  BOB_TRY

  // Parses input arguments in a single shot
  if (!PyList_Check(value)){
    PyErr_Format(PyExc_TypeError, "Expected a list in `%s'", __Y__.name());
    return -1;
  }

  std::vector<blitz::Array<double,1> > data;
  if(list_as_vector(value ,data)==0){
    self->cxx->setY(data);
  }

  return 0;
  BOB_CATCH_MEMBER("__Y__ could not be written", -1)
}

static auto __Z__ = bob::extension::VariableDoc(
  "__Z__",
  "list",
  "",
  ""
);
PyObject* PyBobLearnEMJFATrainer_get_Z(PyBobLearnEMJFATrainerObject* self, void*){
  BOB_TRY
  return vector_as_list(self->cxx->getZ());
  BOB_CATCH_MEMBER("__Z__ could not be read", 0)
}
int PyBobLearnEMJFATrainer_set_Z(PyBobLearnEMJFATrainerObject* self, PyObject* value, void*){
  BOB_TRY

  // Parses input arguments in a single shot
  if (!PyList_Check(value)){
    PyErr_Format(PyExc_TypeError, "Expected a list in `%s'", __Z__.name());
    return -1;
  }

  std::vector<blitz::Array<double,1> > data;
  if(list_as_vector(value ,data)==0){
    self->cxx->setZ(data);
  }

  return 0;
  BOB_CATCH_MEMBER("__Z__ could not be written", -1)
}

static PyGetSetDef PyBobLearnEMJFATrainer_getseters[] = {
  {
   acc_v_a1.name(),
   (getter)PyBobLearnEMJFATrainer_get_acc_v_a1,
   (setter)PyBobLearnEMJFATrainer_set_acc_v_a1,
   acc_v_a1.doc(),
   0
  },
  {
   acc_v_a2.name(),
   (getter)PyBobLearnEMJFATrainer_get_acc_v_a2,
   (setter)PyBobLearnEMJFATrainer_set_acc_v_a2,
   acc_v_a2.doc(),
   0
  },
  {
   acc_u_a1.name(),
   (getter)PyBobLearnEMJFATrainer_get_acc_u_a1,
   (setter)PyBobLearnEMJFATrainer_set_acc_u_a1,
   acc_u_a1.doc(),
   0
  },
  {
   acc_u_a2.name(),
   (getter)PyBobLearnEMJFATrainer_get_acc_u_a2,
   (setter)PyBobLearnEMJFATrainer_set_acc_u_a2,
   acc_u_a2.doc(),
   0
  },
  {
   acc_d_a1.name(),
   (getter)PyBobLearnEMJFATrainer_get_acc_d_a1,
   (setter)PyBobLearnEMJFATrainer_set_acc_d_a1,
   acc_d_a1.doc(),
   0
  },
  {
   acc_d_a2.name(),
   (getter)PyBobLearnEMJFATrainer_get_acc_d_a2,
   (setter)PyBobLearnEMJFATrainer_set_acc_d_a2,
   acc_d_a2.doc(),
   0
  },
  {
   __X__.name(),
   (getter)PyBobLearnEMJFATrainer_get_X,
   (setter)PyBobLearnEMJFATrainer_set_X,
   __X__.doc(),
   0
  },
  {
   __Y__.name(),
   (getter)PyBobLearnEMJFATrainer_get_Y,
   (setter)PyBobLearnEMJFATrainer_set_Y,
   __Y__.doc(),
   0
  },
  {
   __Z__.name(),
   (getter)PyBobLearnEMJFATrainer_get_Z,
   (setter)PyBobLearnEMJFATrainer_set_Z,
   __Z__.doc(),
   0
  },

  {0}  // Sentinel
};

/******************************************************************/
/************ Functions Section ***********************************/
/******************************************************************/

/*** initialize ***/
static auto initialize = bob::extension::FunctionDoc(
  "initialize",
  "Initialization before the EM steps",
  "",
  true
)
.add_prototype("jfa_base, stats, [rng]")
.add_parameter("jfa_base", ":py:class:`bob.learn.em.JFABase`", "JFABase Object")
.add_parameter("stats", ":py:class:`bob.learn.em.GMMStats`", "GMMStats Object")
.add_parameter("rng", ":py:class:`bob.core.random.mt19937`", "The Mersenne Twister mt19937 random generator used for the initialization of subspaces/arrays before the EM loop.");
static PyObject* PyBobLearnEMJFATrainer_initialize(PyBobLearnEMJFATrainerObject* self, PyObject* args, PyObject* kwargs) {
  BOB_TRY

  /* Parses input arguments in a single shot */
  char** kwlist = initialize.kwlist(0);

  PyBobLearnEMJFABaseObject* jfa_base = 0;
  PyObject* stats = 0;
  PyBoostMt19937Object* rng = 0;

  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!O!|O!", kwlist, &PyBobLearnEMJFABase_Type, &jfa_base,
                                                                 &PyList_Type, &stats,
                                                                 &PyBoostMt19937_Type, &rng)) return 0;

  if(rng){
    self->cxx->setRng(rng->rng);
  }

  std::vector<std::vector<boost::shared_ptr<bob::learn::em::GMMStats> > > training_data;
  if(extract_GMMStats_2d(stats ,training_data)==0)
    self->cxx->initialize(*jfa_base->cxx, training_data);
  else
    return 0;

  BOB_CATCH_MEMBER("cannot perform the initialize method", 0)

  Py_RETURN_NONE;
}

/*** e_stepv ***/
static auto e_step_v = bob::extension::FunctionDoc(
  "e_step_v",
  "Call the 1st e-step procedure (for the V subspace).",
  "",
  true
)
.add_prototype("jfa_base,stats")
.add_parameter("jfa_base", ":py:class:`bob.learn.em.JFABase`", "JFABase Object")
.add_parameter("stats", ":py:class:`bob.learn.em.GMMStats`", "GMMStats Object");
static PyObject* PyBobLearnEMJFATrainer_e_step_v(PyBobLearnEMJFATrainerObject* self, PyObject* args, PyObject* kwargs) {
  BOB_TRY

  //Parses input arguments in a single shot
  char** kwlist = e_step_v.kwlist(0);

  PyBobLearnEMJFABaseObject* jfa_base = 0;
  PyObject* stats = 0;

  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!O!", kwlist, &PyBobLearnEMJFABase_Type, &jfa_base,
                                                                 &PyList_Type, &stats)) return 0;

  std::vector<std::vector<boost::shared_ptr<bob::learn::em::GMMStats> > > training_data;
  if(extract_GMMStats_2d(stats ,training_data)==0)
    self->cxx->eStep1(*jfa_base->cxx, training_data);
  else
    return 0;

  BOB_CATCH_MEMBER("cannot perform the e_step_v method", 0)

  Py_RETURN_NONE;
}

/*** m_step_v ***/
static auto m_step_v = bob::extension::FunctionDoc(
  "m_step_v",
  "Call the 1st m-step procedure (for the V subspace).",
  "",
  true
)
.add_prototype("jfa_base,stats")
.add_parameter("jfa_base", ":py:class:`bob.learn.em.JFABase`", "JFABase Object")
.add_parameter("stats", ":py:class:`bob.learn.em.GMMStats`", "GMMStats Object");
static PyObject* PyBobLearnEMJFATrainer_m_step_v(PyBobLearnEMJFATrainerObject* self, PyObject* args, PyObject* kwargs) {
  BOB_TRY

  // Parses input arguments in a single shot
  char** kwlist = m_step_v.kwlist(0);

  PyBobLearnEMJFABaseObject* jfa_base = 0;
  PyObject* stats = 0;

  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!O!", kwlist, &PyBobLearnEMJFABase_Type, &jfa_base,
                                                                 &PyList_Type, &stats)) return 0;

  std::vector<std::vector<boost::shared_ptr<bob::learn::em::GMMStats> > > training_data;
  if(extract_GMMStats_2d(stats ,training_data)==0)
    self->cxx->mStep1(*jfa_base->cxx, training_data);
  else
    return 0;

  BOB_CATCH_MEMBER("cannot perform the m_step_v method", 0)

  Py_RETURN_NONE;
}

/*** finalize_v ***/
static auto finalize_v = bob::extension::FunctionDoc(
  "finalize_v",
  "Call the 1st finalize procedure (for the V subspace).",
  "",
  true
)
.add_prototype("jfa_base,stats")
.add_parameter("jfa_base", ":py:class:`bob.learn.em.JFABase`", "JFABase Object")
.add_parameter("stats", ":py:class:`bob.learn.em.GMMStats`", "GMMStats Object");
static PyObject* PyBobLearnEMJFATrainer_finalize_v(PyBobLearnEMJFATrainerObject* self, PyObject* args, PyObject* kwargs) {
  BOB_TRY

  //Parses input arguments in a single shot
  char** kwlist = finalize_v.kwlist(0);

  PyBobLearnEMJFABaseObject* jfa_base = 0;
  PyObject* stats = 0;

  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!O!", kwlist, &PyBobLearnEMJFABase_Type, &jfa_base,
                                                                 &PyList_Type, &stats)) return 0;

  std::vector<std::vector<boost::shared_ptr<bob::learn::em::GMMStats> > > training_data;
  if(extract_GMMStats_2d(stats ,training_data)==0)
    self->cxx->finalize1(*jfa_base->cxx, training_data);
  else
    return 0;

  BOB_CATCH_MEMBER("cannot perform the finalize_v method", 0)

  Py_RETURN_NONE;
}

/*** e_step_u ***/
static auto e_step_u = bob::extension::FunctionDoc(
  "e_step_u",
  "Call the 2nd e-step procedure (for the U subspace).",
  "",
  true
)
.add_prototype("jfa_base,stats")
.add_parameter("jfa_base", ":py:class:`bob.learn.em.JFABase`", "JFABase Object")
.add_parameter("stats", ":py:class:`bob.learn.em.GMMStats`", "GMMStats Object");
static PyObject* PyBobLearnEMJFATrainer_e_step_u(PyBobLearnEMJFATrainerObject* self, PyObject* args, PyObject* kwargs) {
  BOB_TRY

  // Parses input arguments in a single shot
  char** kwlist = e_step_u.kwlist(0);

  PyBobLearnEMJFABaseObject* jfa_base = 0;
  PyObject* stats = 0;

  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!O!", kwlist, &PyBobLearnEMJFABase_Type, &jfa_base,
                                                                 &PyList_Type, &stats)) return 0;

  std::vector<std::vector<boost::shared_ptr<bob::learn::em::GMMStats> > > training_data;
  if(extract_GMMStats_2d(stats ,training_data)==0)
    self->cxx->eStep2(*jfa_base->cxx, training_data);
  else
    return 0;

  BOB_CATCH_MEMBER("cannot perform the e_step_u method", 0)

  Py_RETURN_NONE;
}

/*** m_step_u ***/
static auto m_step_u = bob::extension::FunctionDoc(
  "m_step_u",
  "Call the 2nd m-step procedure (for the U subspace).",
  "",
  true
)
.add_prototype("jfa_base,stats")
.add_parameter("jfa_base", ":py:class:`bob.learn.em.JFABase`", "JFABase Object")
.add_parameter("stats", ":py:class:`bob.learn.em.GMMStats`", "GMMStats Object");
static PyObject* PyBobLearnEMJFATrainer_m_step_u(PyBobLearnEMJFATrainerObject* self, PyObject* args, PyObject* kwargs) {
  BOB_TRY

  // Parses input arguments in a single shot
  char** kwlist = m_step_u.kwlist(0);

  PyBobLearnEMJFABaseObject* jfa_base = 0;
  PyObject* stats = 0;

  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!O!", kwlist, &PyBobLearnEMJFABase_Type, &jfa_base,
                                                                 &PyList_Type, &stats)) return 0;

  std::vector<std::vector<boost::shared_ptr<bob::learn::em::GMMStats> > > training_data;
  if(extract_GMMStats_2d(stats ,training_data)==0)
    self->cxx->mStep2(*jfa_base->cxx, training_data);
  else
    return 0;

  BOB_CATCH_MEMBER("cannot perform the m_step_u method", 0)

  Py_RETURN_NONE;
}

/*** finalize_u ***/
static auto finalize_u = bob::extension::FunctionDoc(
  "finalize_u",
  "Call the 2nd finalize procedure (for the U subspace).",
  "",
  true
)
.add_prototype("jfa_base,stats")
.add_parameter("jfa_base", ":py:class:`bob.learn.em.JFABase`", "JFABase Object")
.add_parameter("stats", ":py:class:`bob.learn.em.GMMStats`", "GMMStats Object");
static PyObject* PyBobLearnEMJFATrainer_finalize_u(PyBobLearnEMJFATrainerObject* self, PyObject* args, PyObject* kwargs) {
  BOB_TRY

  // Parses input arguments in a single shot
  char** kwlist = finalize_u.kwlist(0);

  PyBobLearnEMJFABaseObject* jfa_base = 0;
  PyObject* stats = 0;

  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!O!", kwlist, &PyBobLearnEMJFABase_Type, &jfa_base,
                                                                 &PyList_Type, &stats)) return 0;

  std::vector<std::vector<boost::shared_ptr<bob::learn::em::GMMStats> > > training_data;
  if(extract_GMMStats_2d(stats ,training_data)==0)
    self->cxx->finalize2(*jfa_base->cxx, training_data);
  else
    return 0;

  BOB_CATCH_MEMBER("cannot perform the finalize_u method", 0)

  Py_RETURN_NONE;
}

/*** e_step_d ***/
static auto e_step_d = bob::extension::FunctionDoc(
  "e_step_d",
  "Call the 3rd e-step procedure (for the d subspace).",
  "",
  true
)
.add_prototype("jfa_base,stats")
.add_parameter("jfa_base", ":py:class:`bob.learn.em.JFABase`", "JFABase Object")
.add_parameter("stats", ":py:class:`bob.learn.em.GMMStats`", "GMMStats Object");
static PyObject* PyBobLearnEMJFATrainer_e_step_d(PyBobLearnEMJFATrainerObject* self, PyObject* args, PyObject* kwargs) {
  BOB_TRY

  // Parses input arguments in a single shot
  char** kwlist = e_step_d.kwlist(0);

  PyBobLearnEMJFABaseObject* jfa_base = 0;
  PyObject* stats = 0;

  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!O!", kwlist, &PyBobLearnEMJFABase_Type, &jfa_base,
                                                                 &PyList_Type, &stats)) return 0;

  std::vector<std::vector<boost::shared_ptr<bob::learn::em::GMMStats> > > training_data;
  if(extract_GMMStats_2d(stats ,training_data)==0)
    self->cxx->eStep3(*jfa_base->cxx, training_data);
  else
    return 0;

  BOB_CATCH_MEMBER("cannot perform the e_step_d method", 0)

  Py_RETURN_NONE;
}

/*** m_step_d ***/
static auto m_step_d = bob::extension::FunctionDoc(
  "m_step_d",
  "Call the 3rd m-step procedure (for the d subspace).",
  "",
  true
)
.add_prototype("jfa_base,stats")
.add_parameter("jfa_base", ":py:class:`bob.learn.em.JFABase`", "JFABase Object")
.add_parameter("stats", ":py:class:`bob.learn.em.GMMStats`", "GMMStats Object");
static PyObject* PyBobLearnEMJFATrainer_m_step_d(PyBobLearnEMJFATrainerObject* self, PyObject* args, PyObject* kwargs) {
  BOB_TRY

  // Parses input arguments in a single shot
  char** kwlist = m_step_d.kwlist(0);

  PyBobLearnEMJFABaseObject* jfa_base = 0;
  PyObject* stats = 0;

  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!O!", kwlist, &PyBobLearnEMJFABase_Type, &jfa_base,
                                                                 &PyList_Type, &stats)) return 0;

  std::vector<std::vector<boost::shared_ptr<bob::learn::em::GMMStats> > > training_data;
  if(extract_GMMStats_2d(stats ,training_data)==0)
    self->cxx->mStep3(*jfa_base->cxx, training_data);
  else
    return 0;

  BOB_CATCH_MEMBER("cannot perform the m_step_d method", 0)

  Py_RETURN_NONE;
}

/*** finalize_d ***/
static auto finalize_d = bob::extension::FunctionDoc(
  "finalize_d",
  "Call the 3rd finalize procedure (for the d subspace).",
  "",
  true
)
.add_prototype("jfa_base,stats")
.add_parameter("jfa_base", ":py:class:`bob.learn.em.JFABase`", "JFABase Object")
.add_parameter("stats", ":py:class:`bob.learn.em.GMMStats`", "GMMStats Object");
static PyObject* PyBobLearnEMJFATrainer_finalize_d(PyBobLearnEMJFATrainerObject* self, PyObject* args, PyObject* kwargs) {
  BOB_TRY

  // Parses input arguments in a single shot
  char** kwlist = finalize_d.kwlist(0);

  PyBobLearnEMJFABaseObject* jfa_base = 0;
  PyObject* stats = 0;

  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!O!", kwlist, &PyBobLearnEMJFABase_Type, &jfa_base,
                                                                 &PyList_Type, &stats)) return 0;

  std::vector<std::vector<boost::shared_ptr<bob::learn::em::GMMStats> > > training_data;
  if(extract_GMMStats_2d(stats ,training_data)==0)
    self->cxx->finalize3(*jfa_base->cxx, training_data);
  else
    return 0;

  BOB_CATCH_MEMBER("cannot perform the finalize_d method", 0)

  Py_RETURN_NONE;
}

/*** enroll ***/
static auto enroll = bob::extension::FunctionDoc(
  "enroll",
  "",
  "",
  true
)
.add_prototype("jfa_machine,features,n_iter")
.add_parameter("jfa_machine", ":py:class:`bob.learn.em.JFAMachine`", "JFAMachine Object")
.add_parameter("features", "[:py:class:`bob.learn.em.GMMStats`]", "")
.add_parameter("n_iter", "int", "Number of iterations");
static PyObject* PyBobLearnEMJFATrainer_enroll(PyBobLearnEMJFATrainerObject* self, PyObject* args, PyObject* kwargs) {
  BOB_TRY

  // Parses input arguments in a single shot
  char** kwlist = enroll.kwlist(0);

  PyBobLearnEMJFAMachineObject* jfa_machine = 0;
  PyObject* stats = 0;
  int n_iter = 1;

  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!O!i", kwlist, &PyBobLearnEMJFAMachine_Type, &jfa_machine,
                                                                  &PyList_Type, &stats, &n_iter)) return 0;

  std::vector<boost::shared_ptr<bob::learn::em::GMMStats> > training_data;
  if(extract_GMMStats_1d(stats ,training_data)==0)
    self->cxx->enroll(*jfa_machine->cxx, training_data, n_iter);
  else
    return 0;

  BOB_CATCH_MEMBER("cannot perform the enroll method", 0)

  Py_RETURN_NONE;
}

static PyMethodDef PyBobLearnEMJFATrainer_methods[] = {
  {
    initialize.name(),
    (PyCFunction)PyBobLearnEMJFATrainer_initialize,
    METH_VARARGS|METH_KEYWORDS,
    initialize.doc()
  },
  {
    e_step_v.name(),
    (PyCFunction)PyBobLearnEMJFATrainer_e_step_v,
    METH_VARARGS|METH_KEYWORDS,
    e_step_v.doc()
  },
  {
    e_step_u.name(),
    (PyCFunction)PyBobLearnEMJFATrainer_e_step_u,
    METH_VARARGS|METH_KEYWORDS,
    e_step_u.doc()
  },
  {
    e_step_d.name(),
    (PyCFunction)PyBobLearnEMJFATrainer_e_step_d,
    METH_VARARGS|METH_KEYWORDS,
    e_step_d.doc()
  },
  {
    m_step_v.name(),
    (PyCFunction)PyBobLearnEMJFATrainer_m_step_v,
    METH_VARARGS|METH_KEYWORDS,
    m_step_v.doc()
  },
  {
    m_step_u.name(),
    (PyCFunction)PyBobLearnEMJFATrainer_m_step_u,
    METH_VARARGS|METH_KEYWORDS,
    m_step_u.doc()
  },
  {
    m_step_d.name(),
    (PyCFunction)PyBobLearnEMJFATrainer_m_step_d,
    METH_VARARGS|METH_KEYWORDS,
    m_step_d.doc()
  },
  {
    finalize_v.name(),
    (PyCFunction)PyBobLearnEMJFATrainer_finalize_v,
    METH_VARARGS|METH_KEYWORDS,
    finalize_v.doc()
  },
  {
    finalize_u.name(),
    (PyCFunction)PyBobLearnEMJFATrainer_finalize_u,
    METH_VARARGS|METH_KEYWORDS,
    finalize_u.doc()
  },
  {
    finalize_d.name(),
    (PyCFunction)PyBobLearnEMJFATrainer_finalize_d,
    METH_VARARGS|METH_KEYWORDS,
    finalize_d.doc()
  },
  {
    enroll.name(),
    (PyCFunction)PyBobLearnEMJFATrainer_enroll,
    METH_VARARGS|METH_KEYWORDS,
    enroll.doc()
  },
  {0} /* Sentinel */
};

/******************************************************************/
/************ Module Section **************************************/
/******************************************************************/

// Define the Gaussian type struct; will be initialized later
PyTypeObject PyBobLearnEMJFATrainer_Type = {
  PyVarObject_HEAD_INIT(0,0)
  0
};

bool init_BobLearnEMJFATrainer(PyObject* module)
{
  // initialize the type JFATrainer
  PyBobLearnEMJFATrainer_Type.tp_name      = JFATrainer_doc.name();
  PyBobLearnEMJFATrainer_Type.tp_basicsize = sizeof(PyBobLearnEMJFATrainerObject);
  PyBobLearnEMJFATrainer_Type.tp_flags     = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;//Enable the class inheritance;
  PyBobLearnEMJFATrainer_Type.tp_doc       = JFATrainer_doc.doc();

  // set the functions
  PyBobLearnEMJFATrainer_Type.tp_new          = PyType_GenericNew;
  PyBobLearnEMJFATrainer_Type.tp_init         = reinterpret_cast<initproc>(PyBobLearnEMJFATrainer_init);
  PyBobLearnEMJFATrainer_Type.tp_dealloc      = reinterpret_cast<destructor>(PyBobLearnEMJFATrainer_delete);
  PyBobLearnEMJFATrainer_Type.tp_richcompare = reinterpret_cast<richcmpfunc>(PyBobLearnEMJFATrainer_RichCompare);
  PyBobLearnEMJFATrainer_Type.tp_methods      = PyBobLearnEMJFATrainer_methods;
  PyBobLearnEMJFATrainer_Type.tp_getset       = PyBobLearnEMJFATrainer_getseters;
  //PyBobLearnEMJFATrainer_Type.tp_call         = reinterpret_cast<ternaryfunc>(PyBobLearnEMJFATrainer_compute_likelihood);

  // check that everything is fine
  if (PyType_Ready(&PyBobLearnEMJFATrainer_Type) < 0) return false;

  // add the type to the module
  Py_INCREF(&PyBobLearnEMJFATrainer_Type);
  return PyModule_AddObject(module, "JFATrainer", (PyObject*)&PyBobLearnEMJFATrainer_Type) >= 0;
}

ext: cpp


text:
///////////////////////////////////////////////////////////////////////////////
/// \file stats.hpp
/// Contains the stats<> template.
///
//  Copyright 2005 Eric Niebler. Distributed under the Boost
//  Software License, Version 1.0. (See accompanying file
//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_ACCUMULATORS_STATISTICS_STATS_HPP_EAN_28_10_2005
#define BOOST_ACCUMULATORS_STATISTICS_STATS_HPP_EAN_28_10_2005

#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/accumulators/statistics_fwd.hpp>

namespace boost { namespace accumulators
{

///////////////////////////////////////////////////////////////////////////////
/// An MPL sequence of statistics.
template<BOOST_PP_ENUM_PARAMS(BOOST_ACCUMULATORS_MAX_FEATURES, typename Stat)>
struct stats
  : mpl::vector<BOOST_PP_ENUM_PARAMS(BOOST_ACCUMULATORS_MAX_FEATURES, Stat)>
{
};

}} // namespace boost::accumulators

#endif

ext: hpp

max_stars_repo_name: randolphwong/mcsema

max_issues_repo_name: randolphwong/mcsema

max_forks_repo_name: randolphwong/mcsema


text:
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <iostream>

#include <chrono>
#include <ctime>
#include <thread>
#include <mutex>
#include <functional>

#include <boost/asio.hpp>
#include <boost/array.hpp>
#include "common.h"

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

#ifndef sys_HlsLfcd2LidarConnector
#define sys_HlsLfcd2LidarConnector

class Lds01LidarConnector
{

public:
    uint16_t rpms; ///< @brief RPMS derived from the rpm bytes in an LFCD packet

    std::string port_;                ///< @brief The serial port the driver is attached to
    uint32_t baud_rate_;              ///< @brief The baud rate for the serial connection
    bool shutting_down_;              ///< @brief Flag for whether the driver is supposed to be shutting down or not
    boost::asio::serial_port serial_; ///< @brief Actual serial port object for reading/writing to the LFCD Laser Scanner
    ///< @brief current motor speed as reported by the LFCD.

    uint16_t motor_speed_;

    /**
     * @brief angle, distance
     *
     */
    std::function<void(float, float)> _onLidarCapture = NULL;
    /**
     * @brief x,y, Lidar.x, Lidar.y, mapRatio, scanDeameter, angle, distance
     *
     */
    std::function<void(RplidarPoint)> _onLidarPositionCalculated = NULL;

    std::function<void(RplidarPoint[], int)> _onFrameCaptured = NULL;

    int _scanRadius;
    int _scanDiameterMilimet;
    float _mapRatio;
    int _mapWidth;
    int _mapHeight;

    /**
     * @brief Construct a new Hls Lfcd 2 Lidar Connector object
     * https://emanual.robotis.com/docs/en/platform/turtlebot3/appendix_lds_01/
     *
     * @param io
     * @param scanRadiusMilimet
     * @param mapRatio
     * @param port
     * @param baud_rate
     */

    Lds01LidarConnector(boost::asio::io_service &io, int scanRadiusMilimet = 5000, float mapRatio = 0.0f, std::string port = "\\\\.\\COM4", uint32_t baud_rate = 230400)
        : serial_(io, port)
    {
        shutting_down_ = false;

        _scanRadius = scanRadiusMilimet;
        _scanDiameterMilimet = _scanRadius * 2;

        if (mapRatio == 0.0f)
            _mapRatio = (float)_scanDiameterMilimet / 1000.0f;
        else
            _mapRatio = mapRatio;

        _mapWidth = _scanDiameterMilimet;
        _mapHeight = _scanDiameterMilimet;

        // baud_rate = 230400;
        port_ = port;
        baud_rate_ = baud_rate;

        serial_.set_option(boost::asio::serial_port_base::baud_rate(baud_rate_));

        // Below command is not required after firmware upgrade (2017.10)
        boost::asio::write(serial_, boost::asio::buffer("b", 1)); // start motor

        std::cout << "\r\nLidar init " << port_ << " " << std::to_string(baud_rate_);
    }

    ~Lds01LidarConnector()
    {
        stop();
        boost::asio::write(serial_, boost::asio::buffer("e", 1)); // stop motor
    }

    void init(std::string portCOM_Connect, int opt_com_baudrate = 230400, int scanRadiusMilimet = 5000, float mapRatio = 0)
    {
        std::cout << "Declare in constructor, define this function for compatible to other LidarConnector";
    }

    void registerHandle(std::function<void(RplidarPoint[], int)> onFrameCaptured,
                        std::function<void(RplidarPoint)> onLidarPositionCalculated = NULL,
                        std::function<void(float, float)> onLidarCapture = NULL)
    {
        _onFrameCaptured = onFrameCaptured;
        _onLidarCapture = onLidarCapture;
        _onLidarPositionCalculated = onLidarPositionCalculated;
    }

    void start()
    {

        std::cout << "\r\nLidar started " << port_ << " " << std::to_string(baud_rate_) << std::to_string(shutting_down_);

        float pi = _pi31416;

        int x = 0, y = 0;
        int newX = _mapWidth / 2;
        int newY = _mapHeight / 2;

        // time_t now = time(0);
        // char *dt = ctime(&now);
        bool got_scan = false;
        uint8_t start_count = 0;
        uint8_t good_sets = 0;
        uint32_t motor_speed = 0;
        int index;
        const int maxPoint = 360;
        boost::array<uint8_t, 2520> raw_bytes;

        // while (!shutting_down_ && !got_scan)
        while (!shutting_down_)
        {
            // now = time(0);
            // dt = ctime(&now);
            // cv::Mat image = cv::Mat::zeros(1000, 1000, CV_8UC3);

            // Wait until first data sync of frame: 0xFA, 0xA0
            boost::asio::read(serial_, boost::asio::buffer(&raw_bytes[start_count], 1));

            if (start_count == 0)
            {
                if (raw_bytes[start_count] == 0xFA)
                {
                    start_count = 1;
                }
            }
            else if (start_count == 1)
            {
                if (raw_bytes[start_count] == 0xA0)
                {
                    start_count = 0;
                    // Now that entire start sequence has been found, read in the rest of the message
                    got_scan = true;

                    // boost::asio::read(serial_, boost::asio::buffer(&raw_bytes[2], 2518));
                    boost::asio::read(serial_, boost::asio::buffer(&raw_bytes[2], 2518));

                    // scan->angle_min = 0.0;
                    // scan->angle_max = 2.0*M_PI;
                    // scan->angle_increment = (2.0*M_PI/360.0);
                    // scan->range_min = 0.12;
                    // scan->range_max = 3.5;
                    // scan->ranges.resize(360);
                    // scan->intensities.resize(360);

                    RplidarPoint frame[maxPoint];

                    // read data in sets of 6
                    for (uint16_t i = 0; i < raw_bytes.size(); i = i + 42)
                    {
                        if (raw_bytes[i] == 0xFA && raw_bytes[i + 1] == (0xA0 + i / 42)) //&& CRC check
                        {
                            good_sets++;
                            motor_speed += (raw_bytes[i + 3] << 8) + raw_bytes[i + 2]; // accumulate count for avg. time increment
                            rpms = (raw_bytes[i + 3] << 8 | raw_bytes[i + 2]) / 10;

                            for (uint16_t j = i + 4; j < i + 40; j = j + 6)
                            {
                                index = 6 * (i / 42) + (j - 4 - i) / 6;

                                // Four bytes per reading
                                uint8_t byte0 = raw_bytes[j];
                                uint8_t byte1 = raw_bytes[j + 1];
                                uint8_t byte2 = raw_bytes[j + 2];
                                uint8_t byte3 = raw_bytes[j + 3];

                                // Remaining bits are the range in mm
                                uint16_t intensity = (byte1 << 8) + byte0;

                                // Last two bytes represent the uncertanty or intensity, might also be pixel area of target...
                                // uint16_t intensity = (byte3 << 8) + byte2;
                                uint16_t range = (byte3 << 8) + byte2;

                                // scan->ranges[359-index] = range / 1000.0;
                                // scan->intensities[359-index] = intensity;

                                float tmpDis = range;
                                int tmpAng = index;

                                //std::cout << "\r\na: " << std::to_string(tmpAng) << " i: " << std::to_string(intensity) << " r: " << std::to_string(range);

                                // frame[pos] = RplidarPoint(0, 0, 0, 0, 0, 0, range, intensity);
                                //  frame[pos] = RplidarPoint(x, y, newX, newY, _mapRatio, _scanDiameterMilimet, tmpAng, tmpDis);
                                if (tmpAng >= 0 && tmpAng <= 90)
                                {
                                    x = cos((90 - tmpAng) * pi / 180) * tmpDis;
                                    y = cos(tmpAng * pi / 180) * tmpDis;
                                    x = newX + std::abs(x);
                                    y = newY - std::abs(y);
                                }
                                else if (tmpAng > 90 && tmpAng <= 180)
                                {
                                    x = cos((tmpAng - 90) * pi / 180) * tmpDis;
                                    y = cos((180 - tmpAng) * pi / 180) * tmpDis;
                                    x = newX + std::abs(x);
                                    y = newY + std::abs(y);
                                }
                                else if (tmpAng > 180 && tmpAng <= 270)
                                {
                                    x = cos((270 - tmpAng) * pi / 180) * tmpDis;
                                    y = cos((tmpAng - 180) * pi / 180) * tmpDis;
                                    x = newX - std::abs(x);
                                    y = newY + std::abs(y);
                                }
                                else
                                {
                                    x = cos((tmpAng - 270) * pi / 180) * tmpDis;
                                    y = cos((360 - tmpAng) * pi / 180) * tmpDis;
                                    x = newX - std::abs(x);
                                    y = newY - std::abs(y);
                                }

                                if (x == 0 && y == 0)
                                    continue;

                                if (x < 0 || y < 0)
                                    continue;

                                frame[index] = RplidarPoint(x, y, newX, newY, _mapRatio, _scanDiameterMilimet, (float)tmpAng, tmpDis);

                                // cv::line(image, cv::Point(x, y), cv::Point(x + 2, y + 2), cv::Scalar(255, 0, 255), 3, 8);

                                // cv::line(image, cv::Point(newX, newY), cv::Point(newX + 2, newY + 2), cv::Scalar(0, 0, 255), 3, 8);

                                // cv::imshow("img", image);
                                // cv::waitKey(1);
                            }
                        }

                        // scan->time_increment = motor_speed/good_sets/1e8;

                        // std::cout << "\r\n"<< dt << "\r\n";
                    }
                    if (_onFrameCaptured && _onFrameCaptured != NULL)
                        try
                        {
                            _onFrameCaptured(frame, maxPoint);
                        }
                        catch (...)
                        {
                        }
                }
                else
                {
                    start_count = 0;
                }
            }
        }
    }
    void stop()
    {
        shutting_down_ = true;
    }
};

#endif

max_stars_repo_name: badpaybad/rplidaropencv

max_issues_repo_name: badpaybad/rplidaropencv

max_forks_repo_name: badpaybad/rplidaropencv


text:
// Copyright (c) 2017 Daniel Cooke
// Use of this source code is governed by the MIT license that can be found in the LICENSE file.

#include <boost/test/unit_test.hpp>

#include <iostream>
#include <string>
#include <iterator>
#include <vector>

#include <boost/filesystem.hpp>

#include "basics/genomic_region.hpp"
#include "basics/aligned_read.hpp"
#include "io/read/read_manager.hpp"
#include "test_common.hpp"
#include "mock_objects.hpp"

namespace octopus { namespace test {

namespace fs = boost::filesystem;

BOOST_AUTO_TEST_SUITE(io)
BOOST_AUTO_TEST_SUITE(read_manager)

BOOST_AUTO_TEST_CASE(can_extract_reads_from_BAM_files)
{
    BOOST_REQUIRE(test_file_exists(NA12878_low_coverage));

    ReadManager read_manager {NA12878_low_coverage};

    BOOST_REQUIRE(read_manager.num_samples() == 1);

    const auto sample = read_manager.samples().front();

    const GenomicRegion region1 {"1", 9'990, 10'000};
    const GenomicRegion region2 {"10", 1'000'000, 1'000'100};
    const GenomicRegion region3 {"3", 100'000, 100'100};

    const auto reads1 = read_manager.fetch_reads(sample, region1);

    BOOST_CHECK(reads1.size() == 1);

    const auto reads2 = read_manager.fetch_reads(sample, region2);

    BOOST_CHECK(reads2.size() == 7);

    const auto reads3 = read_manager.fetch_reads(sample, region3);

    BOOST_CHECK(reads3.size() == 21);
}

BOOST_AUTO_TEST_CASE(can_extract_reads_from_CRAM_files)
{
    BOOST_REQUIRE(test_file_exists(NA12878_low_coverage_cram));

    ReadManager read_manager {NA12878_low_coverage_cram};

    BOOST_REQUIRE(read_manager.num_samples() == 1);

    const auto sample = read_manager.samples().front();

    const GenomicRegion region1 {"1", 9'990, 10'000};
    const GenomicRegion region2 {"10", 1'000'000, 1'000'100};
    const GenomicRegion region3 {"3", 100'000, 100'100};

    const auto reads1 = read_manager.fetch_reads(sample, region1);

    BOOST_CHECK(reads1.size() == 1);

    const auto reads2 = read_manager.fetch_reads(sample, region2);

    BOOST_CHECK(reads2.size() == 7);

    const auto reads3 = read_manager.fetch_reads(sample, region3);

    BOOST_CHECK(reads3.size() == 21);
}

BOOST_AUTO_TEST_CASE(read_manager_multiple_files_below_max_file_limit_test)
{
    BOOST_REQUIRE(test_file_exists(NA12878_low_coverage));
    BOOST_REQUIRE(test_file_exists(HG00101));

    std::vector<fs::path> read_paths {NA12878_low_coverage, HG00101};

    constexpr unsigned maxOpenFiles {2};

    ReadManager read_manager(read_paths, maxOpenFiles);

    BOOST_REQUIRE(read_manager.num_samples() == 2);

    const auto samples = read_manager.samples();

    BOOST_REQUIRE(samples.size() == 2);

    const GenomicRegion a_big_region {"1", 2000000, 3000000};
    const GenomicRegion a_small_region {"10", 1000000, 1000100};

    const auto first_sample = samples.front();

    const auto big_region_reads1   = read_manager.fetch_reads(first_sample, a_big_region);
    const auto small_region_reads1 = read_manager.fetch_reads(first_sample, a_small_region);

    BOOST_CHECK(big_region_reads1.size() == 61225);
    BOOST_CHECK(small_region_reads1.size() == 10);

    const auto second_sample = samples.back();

    const auto big_region_reads2   = read_manager.fetch_reads(second_sample, a_big_region);
    const auto small_region_reads2 = read_manager.fetch_reads(second_sample, a_small_region);

    BOOST_CHECK(big_region_reads2.size() == 39200);
    BOOST_CHECK(small_region_reads2.size() == 7);
}

BOOST_AUTO_TEST_CASE(read_manager_multiple_files_above_max_file_limit_test)
{
    BOOST_REQUIRE(test_file_exists(NA12878_low_coverage));
    BOOST_REQUIRE(test_file_exists(HG00101));
    BOOST_REQUIRE(test_file_exists(HG00102));

    std::vector<fs::path> read_paths {NA12878_low_coverage, HG00101, HG00102};

    constexpr unsigned maxOpenFiles {2};

    ReadManager read_manager(read_paths, maxOpenFiles);

    BOOST_REQUIRE(read_manager.num_samples() == 3);

    const auto samples = read_manager.samples();

    const GenomicRegion a_big_region {"1", 2000000, 3000000};
    const GenomicRegion a_small_region {"10", 1000000, 1000100};

    const auto big_reads1 = read_manager.fetch_reads(samples[0], a_big_region);
    const auto big_reads2 = read_manager.fetch_reads(samples[1], a_big_region);
    const auto big_reads3 = read_manager.fetch_reads(samples[2], a_big_region);

    BOOST_CHECK(big_reads1.size() == 61225);
    BOOST_CHECK(big_reads2.size() == 49810);
    BOOST_CHECK(big_reads3.size() == 39200);

    const auto small_reads1 = read_manager.fetch_reads(samples[0], a_small_region);
    const auto small_reads2 = read_manager.fetch_reads(samples[1], a_small_region);
    const auto small_reads3 = read_manager.fetch_reads(samples[2], a_small_region);

    BOOST_CHECK(small_reads1.size() == 10);
    BOOST_CHECK(small_reads2.size() == 9);
    BOOST_CHECK(small_reads3.size() == 7);
}

BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_SUITE_END()

} // namespace test
} // namespace octopus

max_stars_repo_name: gunjanbaid/octopus

max_issues_repo_name: gunjanbaid/octopus

max_forks_repo_name: gunjanbaid/octopus


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

#include <gtest/gtest.h>

#include <boost/numeric/odeint.hpp>

#include "smooth/compat/odeint.hpp"
#include "smooth/so3.hpp"

using namespace smooth;

TEST(OdeInt, Construct)
{
  ASSERT_NO_THROW(smooth::BoostOdeintOps::scale_sum2<double>(1., 2.));
  ASSERT_THROW(smooth::BoostOdeintOps::scale_sum2<double>(2., 2.), std::runtime_error);
}

TEST(OdeInt, Euler)
{
  using state_t = smooth::SO3d;
  using deriv_t = typename state_t::Tangent;

  auto system = [] (const state_t &, deriv_t & d, double) {
    d.setConstant(1);
  };

 boost::numeric::odeint::euler<state_t, double, deriv_t, double, boost::numeric::odeint::vector_space_algebra> stepper;

 state_t s;
 s.setIdentity();

 stepper.do_step(system, s, 0, 1);

 ASSERT_TRUE(s.isApprox(smooth::SO3d::exp(Eigen::Vector3d::Ones())));
}

TEST(OdeInt, RunkeKutta4)
{
  using state_t = smooth::SO3d;
  using deriv_t = typename state_t::Tangent;

  auto system = [] (const state_t &, deriv_t & d, double) {
    d.setConstant(1);
  };

 boost::numeric::odeint::runge_kutta4<state_t, double, deriv_t, double, boost::numeric::odeint::vector_space_algebra> stepper;

 state_t s;
 s.setIdentity();

 stepper.do_step(system, s, 0, 1);

 ASSERT_TRUE(s.isApprox(smooth::SO3d::exp(Eigen::Vector3d::Ones())));
}

TEST(OdeInt, CashKarp54)
{
  using state_t = smooth::SO3d;
  using deriv_t = typename state_t::Tangent;

  auto system = [] (const state_t &, deriv_t & d, double) {
    d.setConstant(1);
  };

 boost::numeric::odeint::runge_kutta_cash_karp54<state_t, double, deriv_t, double, boost::numeric::odeint::vector_space_algebra> stepper;

 state_t s;
 s.setIdentity();

 stepper.do_step(system, s, 0, 1);

 ASSERT_TRUE(s.isApprox(smooth::SO3d::exp(Eigen::Vector3d::Ones())));
}

TEST(OdeInt, Fehlberg78)
{
  using state_t = smooth::SO3d;
  using deriv_t = typename state_t::Tangent;

  auto system = [] (const state_t &, deriv_t & d, double) {
    d.setConstant(1);
  };

 boost::numeric::odeint::runge_kutta_fehlberg78<state_t, double, deriv_t, double, boost::numeric::odeint::vector_space_algebra> stepper;

 state_t s;
 s.setIdentity();

 stepper.do_step(system, s, 0, 1);

 ASSERT_TRUE(s.isApprox(smooth::SO3d::exp(Eigen::Vector3d::Ones())));
}

max_stars_repo_name: NamDinhRobotics/smooth

max_issues_repo_name: NamDinhRobotics/smooth

max_forks_repo_name: NamDinhRobotics/smooth


text:
//=============================================================================
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//=============================================================================

#include <string>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <utility>
#include <vector>
#include <algorithm>
#include <cassert>

#include <boost/range.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <boost/io/ios_state.hpp>
#include <boost/program_options.hpp>

#include <raptor/b/var.hpp>

#include <raptor/sha.hpp>
#include <raptor/hexdump.hpp>
#include <raptor/char_array.hpp>
#include <raptor/file_size.hpp>
#include "info_hash.hpp"

using raptor::b::var;
using raptor::sha1;
using raptor::file_size;
using raptor::info_hash;
using raptor::hexdump;
using raptor::char_array;

static const std::size_t default_piece_length = 1UL << 18; // 256 KiB

var::str make_torrent_pieces ( std::istream& file
                             , std::size_t piece_length )
{
  const std::size_t fsize = file_size ( file );
  const std::size_t piece_count = ( fsize + ( piece_length - 1 ) ) / piece_length;
  std::string pieces;
  pieces.reserve ( raptor::sha1_digest_size * piece_count );

  file.clear();

  std::vector < char > buf ( piece_length );
  for ( std::size_t remain = fsize
      ; remain
      ; remain -= std::min ( piece_length, remain ) )
  {
    const std::size_t piece_size = std::min ( piece_length, remain );
    const bool read_ok = static_cast < bool > ( file.read ( buf.data(), piece_size ) );
    //assert ( read_ok ); // TODO proper error handling

    sha1 sha;
    sha1::digest_type dig = sha.digest ( buf.begin(), buf.begin() + piece_size );
    pieces.append ( boost::begin ( char_array ( dig ) )
                  , boost::end ( char_array ( dig ) ) );
  }
  return pieces;
}

var::dict make_torrent_info ( std::string const& name
                            , std::istream& file
                            , std::size_t piece_length )
{
  typedef var::dict::value_type kv;

  const std::istream::pos_type fsize = file_size ( file );
  const var::str pieces = make_torrent_pieces ( file, piece_length );
  var::dict info;
  info.insert ( kv ( "name", name ) );
  info.insert ( kv ( "length", fsize ) );
  info.insert ( kv ( "piece length", piece_length ) );
  info.insert ( kv ( "pieces", pieces ) );
  return info;
}

var make_torrent ( std::string const& announce
                 , std::string const& name
                 , std::istream& file
                 , std::size_t piece_length )
{
  typedef var::dict::value_type kv;
  var::dict root;

  if ( ! announce.empty() )
  {
    root.insert ( kv ( "announce", announce ) );
  }
  const var::dict info = make_torrent_info ( name, file, piece_length );
  root.insert ( kv ( "info", info ) );

  return var ( root );
}

int main ( int argc, char** argv )
{
  using std::cout;
  using std::cerr;
  using std::string;
  namespace po = boost::program_options;

  try
  {
    po::options_description desc ( "Allowed options" );
    desc.add_options()
      ( "help,h", "Produce help message." )
      ( "quiet,q", po::value < bool >()->default_value ( false ), "Quiet mode." )
      ( "announce,a", po::value < string >()->default_value ( "" ), "Tracker announce URL." )
      ( "name,n", po::value < string >(), "Name of torrent content." )
      ( "file,f", po::value < string >(), "Torrent output file name.")
      ( "piece-length", po::value < std::size_t >()->default_value ( default_piece_length), "Piece length." )
      ( "input-file", po::value < string >(), "Input file for the torrent." );

    po::positional_options_description p;
    p.add ( "input-file", -1 );

    po::variables_map vm;
    po::store ( po::command_line_parser ( argc, argv )
        .options ( desc )
        .positional ( p ).run()
      , vm );
    po::notify ( vm );

    const bool need_help = false
      || ! vm.count ( "name" )
      || ! vm.count ( "file" )
      || ! vm.count ( "input-file" );

    if ( vm.count ( "help" ) || need_help )
    {
      cout << desc << "\n";
      return 1;
    }

    const string announce = vm [ "announce" ].as < string >();
    const string name = vm [ "name" ].as < string >();
    const std::size_t piece_length = vm [ "piece-length" ].as < std::size_t >();
    std::ifstream file ( vm [ "input-file" ].as < string >().c_str() );

    var torrent = make_torrent ( announce, name, file, piece_length );
    std::ofstream of ( vm [ "file" ].as < string >().c_str(), std::ios_base::binary );
    of << torrent;

    if ( ! vm [ "quiet" ].as < bool >() )
    {
      const sha1::digest_type dig = info_hash ( torrent );

      cout << "info_hash = " << hexdump ( char_array ( dig ) ) << "\n";
    }

  }
  catch ( std::exception const& e)
  {
    cerr << "Exception: " << e.what() << "\n";
    return 1;
  }

  return 0;
}


text:
// Database for APC
// Author: Christian Lenz <chrislenz@uni-bonn.de>
#include <apc_control/apc_database.h>
#include <boost/lexical_cast.hpp>

void Shelf::loadTaskFile(std::istream& stream)
{

	YAML::Node doc = YAML::Load(stream);
	if(doc.IsNull())
	{
		ROS_WARN("APC_CONTROL: Could not get YAML Task File");
		return;
	}
	try
	{

		const YAML::Node& bin_contents = doc["bin_contents"];

		for(int i=0;i<4;++i){
			for(int j=0;j<3;++j){
				char t='A' + 3 * i + j;
				std::vector<std::string> content;
				std::string bin="bin_";
				bin += t;
				content = bin_contents[bin].as<std::vector<std::string> >();
				Box box;
				box.name = boost::lexical_cast<std::string>(t);
				box.row = i;
				box.col = j;
				for(size_t k = 0; k < content.size(); ++k){
					Item item(content[k]);
					item.objectData=getItemData(item.name);
					box.items.push_back(item);
				}
				boxes[i][j]=box;
			}
		}

		std::vector<std::string> tote_contents;
		tote_contents= doc["tote_contents"].as<std::vector<std::string> >();
		for(unsigned int i=0;i<tote_contents.size();++i){
			Item item(tote_contents[i]);
			item.objectData=getItemData(item.name);
			tote.push_back(item);
		}

		const YAML::Node& work_order = doc["work_order"];

		for(unsigned int i=0;i<work_order.size();++i){
			std::string bin;
			std::string name;
			bin = work_order[i]["bin"].as<std::string>();
			name = work_order[i]["item"].as<std::string>();

			int pos=(int)bin[4]-'A';
			int row,col;
			row=pos/3;
			col=pos%3;

			WorkItem item(name,row,col,-1,-1,bin.substr(4,1),"tote", getItemData(name));
			workOrder.push_back(item);
		}

		return;
	}
	catch(YAML::Exception& e)
	{
		ROS_WARN("Could not parse YAML: %s", e.what());
		return;
	}

}

void Shelf::writeResultFile(std::ofstream& stream)
{
	stream << "{" << std::endl;
	stream << "\t\"bin_contents\": {" << std::endl;

	for(unsigned int i=0;i<4;i++){
		for(unsigned int j=0;j<3;j++){
			if(boxes[i][j].items.size()<1)
				stream << "\t\t\"bin_" << (char)('A' + 3*i+j) << "\": []";
			else{

				stream << "\t\t\"bin_" << (char)('A' + 3*i+j) << "\": [" << std::endl;
				for(unsigned int k=0;k<boxes[i][j].items.size()-1;k++){
					stream << "\t\t\t\"" << boxes[i][j].items[k].name << "\"," << std::endl;
				}
				stream << "\t\t\t\"" << boxes[i][j].items[boxes[i][j].items.size()-1].name << "\"" << std::endl;
				stream << "\t\t]";
			}

			if(!(i==3 && j==2)) stream << ",";
			stream << std::endl;
		}
	}
	stream << "\t}," << std::endl;
	if(tote.size()==0){
		stream << "\t\"tote_contents\": []" << std::endl;
	}
	else{
		stream << "\t\"tote_contents\": [" << std::endl;
		for(unsigned int k=0;k<tote.size()-1;k++){
			stream << "\t\t\"" << tote[k].name << "\"," << std::endl;
		}
		stream << "\t\t\"" << tote[tote.size()-1].name << "\"" << std::endl;
		stream << "\t]" << std::endl;

	}

	stream << "}" << std::endl;

}

void Shelf::moveItem(WorkItem item)
{
	//Item was in tote
	if(item.location == "tote")
	{
		if(tote.size()<1){
			ROS_ERROR("No items in tote!");
			return;
		}
		if(item.destination == "tote") return;

		for(unsigned int i=0;i<tote.size();i++){
			if(tote[i].name==item.name){
				tote.erase(tote.begin()+i);
				boxes[item.dest_row][item.dest_col].items.push_back(Item(item.name));
				return;
			}
		}
		ROS_ERROR("Could not find Item '%s' in tote.",item.name.c_str());
	}
	//Item was in Shelf
	else
	{
		for(unsigned int k=0;k<boxes[item.loc_row][item.loc_col].items.size();k++){
			if(item.name==boxes[item.loc_row][item.loc_col].items[k].name){
				boxes[item.loc_row][item.loc_col].items.erase(boxes[item.loc_row][item.loc_col].items.begin()+k);
				if(item.destination == "tote")
				{
					tote.push_back(Item(item.name));
				}
				else if(item.dest_col>=0 && item.dest_row >=0)
				{
					boxes[item.dest_row][item.dest_col].items.push_back(Item(item.name));
				}
				else
				{
					ROS_ERROR("Wrong item destination specified for item %s.", item.name.c_str());
				}

				return;
			}
		}
		ROS_ERROR("Could not find Item '%s' in box(%i,%i).",item.name.c_str(),item.loc_row,item.loc_col);
	}
}

void Shelf::removeItem(WorkItem item)
{
	//Item was in tote
	if(item.location == "tote")
	{
		if(tote.size()<1){
			ROS_ERROR("No items in tote!");
			return;
		}
		for(unsigned int i=0;i<tote.size();i++){
			if(tote[i].name==item.name){
				tote.erase(tote.begin()+i);
				return;
			}
		}
		ROS_ERROR("Could not find Item '%s' in tote.",item.name.c_str());
	}

	//Item was in shelf
	else
	{
		for(unsigned int k=0;k<boxes[item.loc_row][item.loc_col].items.size();k++){
			if(item.name==boxes[item.loc_row][item.loc_col].items[k].name){
				boxes[item.loc_row][item.loc_col].items.erase(boxes[item.loc_row][item.loc_col].items.begin()+k);
				return;
			}
		}
		ROS_ERROR("Could not find Item '%s' in box(%i,%i).",item.name.c_str(),item.loc_row,item.loc_col);
	}
}

bool Shelf::checkBoxSize(int row, int col){
	if(row<0 || row >3 || col <0 || col > 2) return false;
	return true;
}

const apc_objects::APCObject* Shelf::getItemData(std::string name)
{
	auto it = apc_objects::objects().find(name);
	if(it == apc_objects::objects().end())
	{
		ROS_ERROR("Specified unknown object '%s'. Can't compute item volume.", name.c_str());
		return new apc_objects::APCObject;
	}
	return &it->second;
}

void Shelf::ItemScoreDifficulty()
{
	for(unsigned int i=0;i<workOrder.size();i++)
	{
		switch(boxes[workOrder[i].loc_row][workOrder[i].loc_col].items.size())
		{
			case 1: case 2:
				workOrder[i].shelfScore = 10;
				break;
			case 3: case 4:
				workOrder[i].shelfScore = 15;
				break;
			case 5: case 6: case 7: case 8:
			case 9: case 10:
				workOrder[i].shelfScore = 20;
				break;
			default: workOrder[i].shelfScore = 0;
		};
	}
}

void Shelf::PointsAndVolume()
{
	for(unsigned int row=0;row<4;row++)
	{
		for(unsigned int col=0;col<3;col++)
		{

			float vol=42;			//x-axis
			if(row%3==0) vol*=23.5; //Height=z-axis 1st and 4th row
			else vol*=19.5; 		//Height=z-axis 2nd and 3th row

			if(col%2==0) vol*=27;   //width=y-axis 1st and 3rd col
			else vol*=30; 			//middle col

			boxes[row][col].predictedVolume=vol;

// 			ROS_INFO("Box Vol: %f.",vol);

			for(auto item: boxes[row][col].items)
			{
				boxes[row][col].predictedVolume -= item.objectData->volume();
				if(item.name == "scotch_bubble_mailer"
						|| item.name == "kleenex_paper_towels"
						|| item.name == "hanes_tube_socks")
					boxes[row][col].containBigItem = true;
			}

			switch(boxes[row][col].items.size())
			{
				case 1: case 2:
					boxes[row][col].stowPoints = 10;
					break;
				case 3: case 4:
					boxes[row][col].stowPoints = 15;
					break;
				case 5: case 6: case 7: case 8:
				case 9: case 10:
					boxes[row][col].stowPoints = 20;
					break;
				default: boxes[row][col].stowPoints = 0;
			};

// 			ROS_WARN("# items: %i. points: %i. Vol: %f",boxes[row][col].items.size(),boxes[row][col].stowPoints,boxes[row][col].predictedVolume);
		}
	}
}

Shelf::Shelf(){}

Box::Box():
stowPoints(0),
predictedVolume(0)
{
}

bool Box::containItem(std::string itemName)
{
	for(auto item: items)
	{
		if(item.name == itemName)
			return true;
	}
	return false;
}

Item::Item(std::string n):
name(n)
{
}

WorkItem::WorkItem(std::string name, int loc_row, int loc_col, int dest_row, int dest_col, std::string location, std::string destination, const apc_objects::APCObject* objectData):
name(name),
location(location),
destination(destination),
loc_row(loc_row),
loc_col(loc_col),
dest_row(dest_row),
dest_col(dest_col),
objectData(objectData)
{}

int WorkItem::getItemScore()
{
	return shelfScore + objectData->bonusPoints;
}


text:
#include <chrono>
#include <boost/bind.hpp>

#include "PoolManager.h"

using namespace energi;

PoolManager::PoolManager(boost::asio::io_service& io_service,
                         PoolClient* client,
                         energi::MinePlant &farm,
                         const MinerExecutionMode& minerType,
                         unsigned maxTries,
                         unsigned failoverTimeout)
    : Worker("main")
    , m_io_strand(io_service)
    , m_failovertimer(io_service)
    , m_farm(farm)
    , m_minerType(minerType)
{
	p_client = client;
    m_maxConnectionAttempts = maxTries;
    m_failoverTimeout = failoverTimeout;

	p_client->onConnected([&]()
	{
        m_connectionAttempt = 0;
        m_activeConnectionHost = m_connections[m_activeConnectionIdx].Host();
        cnote << "Connected to " << p_client->ActiveEndPoint();
        // Rough implementation to return to primary pool
        // after specified amount of time
        if (m_activeConnectionIdx != 0 && m_failoverTimeout > 0) {
            m_failovertimer.expires_from_now(boost::posix_time::minutes(m_failoverTimeout));
            m_failovertimer.async_wait(m_io_strand.wrap(boost::bind(&PoolManager::check_failover_timeout, this, boost::asio::placeholders::error)));
        } else {
            m_failovertimer.cancel();
        }

        if (!m_farm.isMining()) {
            cnote << "Spinning up miners...";
            auto vEngineModes = getEngineModes(m_minerType);
            m_farm.start(vEngineModes);
    }
	});
	p_client->onResetWork([&]()
	{
        m_farm.resetWork();
	});
	p_client->onDisconnected([&]()
	{
        setThreadName("main");
        cnote << "Disconnected from " << p_client->ActiveEndPoint();
        // Do not stop mining here
        // Workloop will determine if we're trying a fast reconnect to same pool
        // or if we're switching to failover(s)
	});
    p_client->onWorkReceived([&](const Work& wp)
    {
        m_farm.setWork(wp);
    });
	p_client->onSolutionAccepted([&](const bool& stale, const std::chrono::milliseconds& elapsedMs)
	{
		using namespace std::chrono;
		std::stringstream ss;
		ss << std::setw(4) << std::setfill(' ') << elapsedMs.count();
		ss << " ms." << "   " << m_connections[m_activeConnectionIdx].Host() + p_client->ActiveEndPoint();
		cnote << EthLime "**Accepted  " EthReset << (stale ? "(stale)" : "") << ss.str();
		m_farm.acceptedSolution(stale);
	});
	p_client->onSolutionRejected([&](const bool& stale, std::chrono::milliseconds const& elapsedMs)
	{
		using namespace std::chrono;
		std::stringstream ss;
		ss << std::setw(4) << std::setfill(' ') << elapsedMs.count();
		ss << " ms." << "   " << m_connections[m_activeConnectionIdx].Host() + p_client->ActiveEndPoint();
		cwarn << EthRed "**Rejected  " EthReset << (stale ? "(stale)" : "") << ss.str();
		m_farm.rejectedSolution();
	});

	m_farm.onSolutionFound([&](const Solution& sol)
	{
        // Solution should passthrough only if client is
        // properly connected. Otherwise we'll have the bad behavior
        // to log nonce submission but receive no response
        if (p_client->isConnected()) {
            p_client->submitSolution(sol);
        } else {
            cnote << std::string(EthRed "Nonce ") + std::to_string(sol.getWork().getNonce()) << " wasted. Waiting for connection ...";
        }
    return false;
	});
	m_farm.onMinerRestart([&]() {
        setThreadName("main");
		cnote << "Restart miners...";
		if (m_farm.isMining()) {
			cnote << "Shutting down miners...";
			m_farm.stop();
		}
        auto vEngineModes = getEngineModes(m_minerType);
        m_farm.start(vEngineModes);
	});
}

void PoolManager::stop()
{
    if (m_running.load(std::memory_order_relaxed)) {
        cnote << "Shutting down...";
        m_running.store(false, std::memory_order_relaxed);
        m_failovertimer.cancel();

        if (p_client->isConnected()) {
            p_client->disconnect();
        }
        if (m_farm.isMining()) {
            cnote << "Shutting down miners...";
            m_farm.stop();
        }
    }
}

void PoolManager::trun()
{
    setThreadName("main");
    while (m_running.load(std::memory_order_relaxed)) {
        // Take action only if not pending state (connecting/disconnecting)
        // Otherwise do nothing and wait until connection state is NOT pending
        if (!p_client->isPendingState()) {
            if (!p_client->isConnected()) {
                // If this connection is marked Unrecoverable then discard it
                if (m_connections[m_activeConnectionIdx].IsUnrecoverable()) {
                    m_connections.erase(m_connections.begin() + m_activeConnectionIdx);
                    if (m_activeConnectionIdx >= m_connections.size()) {
                        m_activeConnectionIdx = 0;
                    }
                    m_connectionAttempt = 0;
                }
                // Rotate connections if above max attempts threshold
                if (m_connectionAttempt >= m_maxConnectionAttempts) {
                    m_connectionAttempt = 0;
                    m_activeConnectionIdx++;
                    if (m_activeConnectionIdx == m_connections.size()) {
                        m_activeConnectionIdx = 0;
                    }

                    // Suspend mining if applicable as we're switching
                    if (m_farm.isMining()) {
                        cnote << "Suspend mining due connection change...";
                        m_farm.resetWork();//
                    }
                }
                if (m_connections[m_activeConnectionIdx].Host() != "exit"  && m_connections.size() > 0) {
                    // Count connectionAttempts
                    m_connectionAttempt++;

                    // Invoke connections
                    p_client->setConnection(m_connections[m_activeConnectionIdx]);
                    m_farm.set_pool_addresses(m_connections[m_activeConnectionIdx].Host(), m_connections[m_activeConnectionIdx].Port());
                    cnote << "Selected pool " << (m_connections[m_activeConnectionIdx].Host() + ":" + toString(m_connections[m_activeConnectionIdx].Port()));
                    p_client->connect();

                } else {
                    cnote << "No more connections to try. Exiting ...";
                    // Stop mining if applicable
                    if (m_farm.isMining()) {
                        cnote << "Shutting down miners...";
                        m_farm.stop();
                    }

                    m_running.store(false, std::memory_order_relaxed);
                    continue;
                }
            }

        }

        // Hashrate reporting
        m_hashrateReportingTimePassed++;

        if (m_hashrateReportingTimePassed > m_hashrateReportingTime) {
            //auto mp = m_farm.miningProgress();
            //std::string h = toHex(toCompactBigEndian(uint64_t(mp.hashRate), 1));
            //std::string res = h[0] != '0' ? h : h.substr(1);

            // Should be 32 bytes
            // https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_submithashrate
            //std::ostringstream ss;
            //ss << std::setw(64) << std::setfill('0') << res;
            //cnote << res.str();
            //!TODO p_client->submitHashrate();
            m_hashrateReportingTimePassed = 0;
        }
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
}

void PoolManager::addConnection(URI &conn)
{
	m_connections.push_back(conn);
}

void PoolManager::clearConnections()
{
    m_connections.clear();
    m_farm.set_pool_addresses("", 0);
    if (p_client && p_client->isConnected()) {
        p_client->disconnect();
    }
}

bool PoolManager::start()
{
    if (m_connections.size() > 0) {
        m_running.store (true, std::memory_order_relaxed);
        m_workThread = std::thread{ boost::bind(&PoolManager::trun, this) };
        // Try to connect to pool
        return true;
    } else {
        cwarn << "Manager has no connections defined!";
        return false;
    }
    return true;
}

void PoolManager::check_failover_timeout(const boost::system::error_code& ec)
{

    if (!ec) {
        if (m_running.load(std::memory_order_relaxed)) {
            if (m_activeConnectionIdx != 0) {
                p_client->disconnect();
                m_activeConnectionIdx = 0;
                m_connectionAttempt = 0;
            }
        }
    }
}

max_stars_repo_name: MaynardMiner/energiminer

max_issues_repo_name: MaynardMiner/energiminer

max_forks_repo_name: MaynardMiner/energiminer


text:
#include "Triangle.h"
#include "Ray.h"
#include <Eigen/Geometry>
#include <iostream>

bool Triangle::intersect(
  const Ray & ray, const double min_t, double & t, Eigen::Vector3d & n) const
{
  ////////////////////////////////////////////////////////////////////////////
  /**
   * NOTE: The following solution is found on page 79 in the textbook.
   */
  bool hit = false;

  // Set up some variables
  Eigen::Vector3d P = std::get<0>(Triangle::corners);       // Point P
  Eigen::Vector3d Q = std::get<1>(Triangle::corners);       // Point Q
  Eigen::Vector3d R = std::get<2>(Triangle::corners);       // Point R
  Eigen::Vector3d PQ = Q - P;                               // direction vector
  Eigen::Vector3d PR = R - P;                               // direction vector
  Eigen::Vector3d v = ray.direction;
  Eigen::Vector3d O = ray.origin;

  // Get the normal of the two vectors in the plane of the triangle
  Eigen::Vector3d normal = PQ.cross(PR);

  // Check if the ray intersects with the plane made by the triangle
  if (v.dot(normal) == 0) {
    return false;
  }

  // If we make it here, then we know that the ray intersects the plane at some
  // point t
  t = (normal.dot(P - O)) / (normal.dot(v));
  if (t < min_t) {
    return false;
  }

  /**
   * Now we need to check if the intersection point is in the triangle
   */
  // Eigen::Matrix3d A;
  // A << -PQ, -PR, v;
  // Eigen::Vector3d y = P - O;           // Ax = y, where x = <beta, gamma, t>

  // Set up the columns of matrix A
  // Column vector (P - Q)
  double a = -PQ[0];
  double b = -PQ[1];
  double c = -PQ[2];
  // Column vector (P - R)
  double d = -PR[0];
  double e = -PR[1];
  double f = -PR[2];
  // Column vector d (direction vector of ray)
  double g = v[0];
  double h = v[1];
  double i = v[2];

  // Column vector y                      Ax = y
  double j = P[0] - O[0];
  double k = P[1] - O[1];
  double l = P[2] - O[2];

  /**
   * Rather than use A.determinant(), we can reduce the number of operations
   * by reusing numbers.
   * double M = A.determinant();
   */
  double ei_minus_hf = e * i - h * f;
  double gf_minus_di = g * f - d * i;
  double dh_minus_eg = d * h - e * g;

  double ak_minus_jb = a * k - j * b;
  double jc_minus_al = j * c - a * l;
  double bl_minus_kc = b * l - k * c;

  // Get the determinant of A
  double M = a * ei_minus_hf + b * gf_minus_di + c * dh_minus_eg;

  // Solve for the values of x = <beta, gamma, t> in the system Ax = y
  double beta = (j * ei_minus_hf + k * gf_minus_di + l * dh_minus_eg) / M;
  double gamma = (i * ak_minus_jb + h * jc_minus_al + g * bl_minus_kc) / M;
  // double t_prime = -((f * ak_minus_jb + e * jc_minus_al + d * bl_minus_kc) / M);
  // assert(t == t_prime);                  // works properly

  if (beta >= 0 && gamma >= 0 && (beta + gamma) <= 1) {
    n = normal.normalized();
    hit = true;
  }

  return hit;
  ////////////////////////////////////////////////////////////////////////////
}

max_stars_repo_name: ericpko/computer-graphics-ray-tracing

max_issues_repo_name: ericpko/computer-graphics-ray-tracing

max_forks_repo_name: ericpko/computer-graphics-ray-tracing


text:
/*
 * Copyright 2015 Klemens Morgenstern
 * Copyright 2016 Jorge Lodos
 * Copyright 2016 Andrey Semashev
 *
 * Distributed under the Boost Software License, Version 1.0.
 * See http://www.boost.org/LICENSE_1_0.txt
 */

#ifndef BOOST_WINAPI_DBGHELP_HPP_INCLUDED_
#define BOOST_WINAPI_DBGHELP_HPP_INCLUDED_

#include <boost/winapi/basic_types.hpp>

#if defined( BOOST_USE_WINDOWS_H )
#if !defined( BOOST_WINAPI_IS_MINGW )
#include <dbghelp.h>
#else
// In MinGW there is no dbghelp.h but an older imagehlp.h header defines some of the symbols from it.
// Note that the user has to link with libimagehlp.a instead of libdbghelp.a for it to work.
#include <imagehlp.h>
#endif
#endif

#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif

#if BOOST_WINAPI_PARTITION_DESKTOP

#include <boost/winapi/detail/header.hpp>

// Some symbols declared below are not present in all versions of Windows SDK, MinGW and MinGW-w64.
// dbghelp.h/imagehlp.h define the API_VERSION_NUMBER macro which we use to detect its version.
// When the macro is not available we can only guess based on the compiler version or SDK type.
#if defined(API_VERSION_NUMBER)
#if API_VERSION_NUMBER >= 11
// UnDecorateSymbolNameW available since Windows SDK 6.0A and MinGW-w64 (as of 2016-02-14)
#define BOOST_WINAPI_DETAIL_HAS_UNDECORATESYMBOLNAMEW
#endif
#elif defined(_MSC_VER) && _MSC_VER >= 1500
// Until MSVC 9.0 Windows SDK was bundled in Visual Studio and didn't have UnDecorateSymbolNameW.
// Supposedly, Windows SDK 6.0A was the first standalone one and it is used with MSVC 9.0.
#define BOOST_WINAPI_DETAIL_HAS_UNDECORATESYMBOLNAMEW
#elif !defined(BOOST_WINAPI_IS_MINGW)
// MinGW does not provide UnDecorateSymbolNameW (as of 2016-02-14)
#define BOOST_WINAPI_DETAIL_HAS_UNDECORATESYMBOLNAMEW
#endif

#if !defined( BOOST_USE_WINDOWS_H )
extern "C" {

struct API_VERSION;

BOOST_WINAPI_IMPORT boost::winapi::DWORD_ BOOST_WINAPI_WINAPI_CC
UnDecorateSymbolName(
    boost::winapi::LPCSTR_ DecoratedName,
    boost::winapi::LPSTR_ UnDecoratedName,
    boost::winapi::DWORD_ UndecoratedLength,
    boost::winapi::DWORD_ Flags);

#if defined( BOOST_WINAPI_DETAIL_HAS_UNDECORATESYMBOLNAMEW )
BOOST_WINAPI_IMPORT boost::winapi::DWORD_ BOOST_WINAPI_WINAPI_CC
UnDecorateSymbolNameW(
    boost::winapi::LPCWSTR_ DecoratedName,
    boost::winapi::LPWSTR_ UnDecoratedName,
    boost::winapi::DWORD_ UndecoratedLength,
    boost::winapi::DWORD_ Flags);
#endif

BOOST_WINAPI_IMPORT API_VERSION* BOOST_WINAPI_WINAPI_CC
ImagehlpApiVersion(BOOST_WINAPI_DETAIL_VOID);

} // extern "C"
#endif

namespace boost {
namespace winapi {

#if defined( BOOST_USE_WINDOWS_H )

BOOST_CONSTEXPR_OR_CONST DWORD_ UNDNAME_COMPLETE_ = UNDNAME_COMPLETE;
BOOST_CONSTEXPR_OR_CONST DWORD_ UNDNAME_NO_LEADING_UNDERSCORES_ = UNDNAME_NO_LEADING_UNDERSCORES;
BOOST_CONSTEXPR_OR_CONST DWORD_ UNDNAME_NO_MS_KEYWORDS_ = UNDNAME_NO_MS_KEYWORDS;
BOOST_CONSTEXPR_OR_CONST DWORD_ UNDNAME_NO_FUNCTION_RETURNS_ = UNDNAME_NO_FUNCTION_RETURNS;
BOOST_CONSTEXPR_OR_CONST DWORD_ UNDNAME_NO_ALLOCATION_MODEL_ = UNDNAME_NO_ALLOCATION_MODEL;
BOOST_CONSTEXPR_OR_CONST DWORD_ UNDNAME_NO_ALLOCATION_LANGUAGE_ = UNDNAME_NO_ALLOCATION_LANGUAGE;
BOOST_CONSTEXPR_OR_CONST DWORD_ UNDNAME_NO_MS_THISTYPE_ = UNDNAME_NO_MS_THISTYPE;
BOOST_CONSTEXPR_OR_CONST DWORD_ UNDNAME_NO_CV_THISTYPE_ = UNDNAME_NO_CV_THISTYPE;
BOOST_CONSTEXPR_OR_CONST DWORD_ UNDNAME_NO_THISTYPE_ = UNDNAME_NO_THISTYPE;
BOOST_CONSTEXPR_OR_CONST DWORD_ UNDNAME_NO_ACCESS_SPECIFIERS_ = UNDNAME_NO_ACCESS_SPECIFIERS;
BOOST_CONSTEXPR_OR_CONST DWORD_ UNDNAME_NO_THROW_SIGNATURES_ = UNDNAME_NO_THROW_SIGNATURES;
BOOST_CONSTEXPR_OR_CONST DWORD_ UNDNAME_NO_MEMBER_TYPE_ = UNDNAME_NO_MEMBER_TYPE;
BOOST_CONSTEXPR_OR_CONST DWORD_ UNDNAME_NO_RETURN_UDT_MODEL_ = UNDNAME_NO_RETURN_UDT_MODEL;
BOOST_CONSTEXPR_OR_CONST DWORD_ UNDNAME_32_BIT_DECODE_ = UNDNAME_32_BIT_DECODE;
BOOST_CONSTEXPR_OR_CONST DWORD_ UNDNAME_NAME_ONLY_ = UNDNAME_NAME_ONLY;
BOOST_CONSTEXPR_OR_CONST DWORD_ UNDNAME_NO_ARGUMENTS_ = UNDNAME_NO_ARGUMENTS;
BOOST_CONSTEXPR_OR_CONST DWORD_ UNDNAME_NO_SPECIAL_SYMS_ = UNDNAME_NO_SPECIAL_SYMS;

#else // defined( BOOST_USE_WINDOWS_H )

BOOST_CONSTEXPR_OR_CONST DWORD_ UNDNAME_COMPLETE_ = 0x00000000;
BOOST_CONSTEXPR_OR_CONST DWORD_ UNDNAME_NO_LEADING_UNDERSCORES_ = 0x00000001;
BOOST_CONSTEXPR_OR_CONST DWORD_ UNDNAME_NO_MS_KEYWORDS_ = 0x00000002;
BOOST_CONSTEXPR_OR_CONST DWORD_ UNDNAME_NO_FUNCTION_RETURNS_ = 0x00000004;
BOOST_CONSTEXPR_OR_CONST DWORD_ UNDNAME_NO_ALLOCATION_MODEL_ = 0x00000008;
BOOST_CONSTEXPR_OR_CONST DWORD_ UNDNAME_NO_ALLOCATION_LANGUAGE_ = 0x00000010;
BOOST_CONSTEXPR_OR_CONST DWORD_ UNDNAME_NO_MS_THISTYPE_ = 0x00000020;
BOOST_CONSTEXPR_OR_CONST DWORD_ UNDNAME_NO_CV_THISTYPE_ = 0x00000040;
BOOST_CONSTEXPR_OR_CONST DWORD_ UNDNAME_NO_THISTYPE_ = 0x00000060;
BOOST_CONSTEXPR_OR_CONST DWORD_ UNDNAME_NO_ACCESS_SPECIFIERS_ = 0x00000080;
BOOST_CONSTEXPR_OR_CONST DWORD_ UNDNAME_NO_THROW_SIGNATURES_ = 0x00000100;
BOOST_CONSTEXPR_OR_CONST DWORD_ UNDNAME_NO_MEMBER_TYPE_ = 0x00000200;
BOOST_CONSTEXPR_OR_CONST DWORD_ UNDNAME_NO_RETURN_UDT_MODEL_ = 0x00000400;
BOOST_CONSTEXPR_OR_CONST DWORD_ UNDNAME_32_BIT_DECODE_ = 0x00000800;
BOOST_CONSTEXPR_OR_CONST DWORD_ UNDNAME_NAME_ONLY_ = 0x00001000;
BOOST_CONSTEXPR_OR_CONST DWORD_ UNDNAME_NO_ARGUMENTS_ = 0x00002000;
BOOST_CONSTEXPR_OR_CONST DWORD_ UNDNAME_NO_SPECIAL_SYMS_ = 0x00004000;

#endif // defined( BOOST_USE_WINDOWS_H )

using ::UnDecorateSymbolName;
#if defined( BOOST_WINAPI_DETAIL_HAS_UNDECORATESYMBOLNAMEW )
using ::UnDecorateSymbolNameW;
#endif

typedef struct BOOST_MAY_ALIAS API_VERSION {
    USHORT_  MajorVersion;
    USHORT_  MinorVersion;
    USHORT_  Revision;
    USHORT_  Reserved;
} API_VERSION_, *LPAPI_VERSION_;

BOOST_FORCEINLINE LPAPI_VERSION_ ImagehlpApiVersion()
{
    return reinterpret_cast<LPAPI_VERSION_>(::ImagehlpApiVersion());
}

BOOST_FORCEINLINE DWORD_ undecorate_symbol_name(
    LPCSTR_ DecoratedName,
    LPSTR_ UnDecoratedName,
    DWORD_ UndecoratedLength,
    DWORD_ Flags)
{
    return ::UnDecorateSymbolName(
        DecoratedName,
        UnDecoratedName,
        UndecoratedLength,
        Flags);
}

#if defined( BOOST_WINAPI_DETAIL_HAS_UNDECORATESYMBOLNAMEW )

BOOST_FORCEINLINE DWORD_ undecorate_symbol_name(
    LPCWSTR_ DecoratedName,
    LPWSTR_ UnDecoratedName,
    DWORD_ UndecoratedLength,
    DWORD_ Flags)
{
    return ::UnDecorateSymbolNameW(
        DecoratedName,
        UnDecoratedName,
        UndecoratedLength,
        Flags);
}

#endif

}
}

#include <boost/winapi/detail/footer.hpp>

#endif // BOOST_WINAPI_PARTITION_DESKTOP
#endif // BOOST_WINAPI_DBGHELP_HPP_INCLUDED_


text:
/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2011 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_FEATURE_TYPE_STYLE_HPP
#define MAPNIK_FEATURE_TYPE_STYLE_HPP

// mapnik
#include <mapnik/config.hpp>
#include <mapnik/rule.hpp>
#include <mapnik/enumeration.hpp>
#include <mapnik/image_filter_types.hpp>
#include <mapnik/image_compositing.hpp>

// boost
#include <boost/optional.hpp>

// stl
#include <vector>

namespace mapnik
{

class rule;

enum filter_mode_enum {
    FILTER_ALL,
    FILTER_FIRST,
    filter_mode_enum_MAX
};

DEFINE_ENUM( filter_mode_e, filter_mode_enum );

typedef std::vector<rule> rules;

class MAPNIK_DECL feature_type_style
{
private:
    rules rules_;
    filter_mode_e filter_mode_;
    // image_filters
    std::vector<filter::filter_type> filters_;
    std::vector<filter::filter_type> direct_filters_;
    // comp-op
    boost::optional<composite_mode_e> comp_op_;
    float opacity_;
public:
    feature_type_style();

    feature_type_style(feature_type_style const& rhs, bool deep_copy = false);

    feature_type_style& operator=(feature_type_style const& rhs);

    void add_rule(rule const& rule);
    rules const& get_rules() const;
    rules& get_rules_nonconst();

    bool active(double scale_denom) const;

    void set_filter_mode(filter_mode_e mode);
    filter_mode_e get_filter_mode() const;

    // filters
    std::vector<filter::filter_type> const& image_filters() const;
    std::vector<filter::filter_type> & image_filters();
    std::vector<filter::filter_type> const& direct_image_filters() const;
    std::vector<filter::filter_type> & direct_image_filters();
    // compositing
    void set_comp_op(composite_mode_e comp_op);
    boost::optional<composite_mode_e> comp_op() const;
    void set_opacity(float opacity);
    float get_opacity() const;

    ~feature_type_style() {}

};
}

#endif // MAPNIK_FEATURE_TYPE_STYLE_HPP

max_stars_repo_name: Wujingli/OpenWebGlobeDataProcessing

max_issues_repo_name: Wujingli/OpenWebGlobeDataProcessing

max_forks_repo_name: Wujingli/OpenWebGlobeDataProcessing