<commit_before>// FieldMap
// Author: Matthew Raso-Barnett  13/12/2010
#include <list>
#include <cmath>

#include "FieldMap.h"
#include "FileParser.h"
#include "FieldVertex.h"
#include "VertexStack.h"
#include "Particle.h"
#include "Run.h"

//#define VERBOSE

using namespace std;

//______________________________________________________________________________
// FieldMap -
//
//______________________________________________________________________________

ClassImp(FieldMap)

//_____________________________________________________________________________
FieldMap::FieldMap()
{
// Default constructor.
   Info("FieldMap", "Default Constructor");
}

//_____________________________________________________________________________
FieldMap::FieldMap(const FieldMap& /*other*/)
{
// Copy constructor.
}

//______________________________________________________________________________
FieldMap::~FieldMap()
{
// Destructor.
   Info("FieldMap", "Destructor");
}

//______________________________________________________________________________
// MagFieldMap -
//
//______________________________________________________________________________

ClassImp(MagFieldMap)

//_____________________________________________________________________________
MagFieldMap::MagFieldMap()
            :FieldMap(),
             fTree(NULL)
{
// Default constructor.
   Info("MagFieldMap", "Default Constructor");
}

//_____________________________________________________________________________
MagFieldMap::MagFieldMap(const string& name, const TGeoShape* shape, const TGeoMatrix* matrix)
            :FieldMap(),
             MagField(name, shape, matrix),
             fTree(NULL)
{
// Default constructor.
   Info("MagFieldMap", "Constructor");
}

//_____________________________________________________________________________
MagFieldMap::MagFieldMap(const MagFieldMap& other)
            :FieldMap(other),
             MagField(other),
             fTree(NULL)
{
// Copy constructor.
   Info("MagFieldMap", "Copy Constructor");
}

//______________________________________________________________________________
MagFieldMap::~MagFieldMap()
{
// Destructor.
   Info("MagFieldMap", "Destructor");
   if (fTree) delete fTree;
}

//______________________________________________________________________________
const TVector3 MagFieldMap::GetField(const TVector3& position) const
{
   // Perform interpolation to get current field
   Int_t numInterpolatePoints = 6;
   return this->Interpolate(position, numInterpolatePoints);
}

//______________________________________________________________________________
Bool_t MagFieldMap::BuildMap(const std::string& filename)
{
   // -- Take input file and initialise a KDTree object data structure to hold the field points.
   cout << "Building MagFieldMap from file: " << filename << endl;
   FileParser parser;
   // Get flat list of Field vertices from provided file using the parser
   vector<FieldVertex*> vertices;
   if (parser.ExtractFieldVertices(filename, vertices) == false) {
      Error("BuildMap","Failed to extract field vertices from: %s", filename.c_str());
      return false;
   }
   // For each vertex, convert coordinates to the global coordinate system
   vector<const FieldVertex*> global_vertices;
   vector<FieldVertex*>::const_iterator iter;
   for (iter = vertices.begin(); iter != vertices.end(); iter++) {
      FieldVertex global = this->ConvertToGlobalFrame((**iter));
      global_vertices.push_back(new FieldVertex(global));
   }
   // Build Tree structure of FieldVertices
   fTree = new KDTree(global_vertices);
   // Delete original local points
   for (iter = vertices.begin(); iter != vertices.end(); iter++) {if (*iter) delete *iter;}
   cout << "Successfully created MagFieldMap from " << global_vertices.size() << " points." << endl;
   return true;
}

//______________________________________________________________________________
TVector3 MagFieldMap::Interpolate(const TVector3& position, const Int_t numInterpolatePoints) const
{
   // -- For given position, find the n-nearest-neighbouring vertices (n being numInterpolatePoints)
   // -- and perform IDW interpolation using Modified Shepard's Method,
   // -- http://en.wikipedia.org/wiki/Inverse_distance_weighting
   FieldVertex vertex(position.X(), position.Y(), position.Z(), 0.,0.,0.,0.);
   const VertexStack* neighbours = fTree->NearestNeighbours(vertex, numInterpolatePoints);
   list<StackElement>::const_iterator stackIter;
   double radius = (neighbours->back()).second;
   double sumWeights = 0.;
   TVector3 avgField;
   for (stackIter = neighbours->begin(); stackIter != neighbours->end(); stackIter++) {
      double distance = stackIter->second;
      const FieldVertex* vertex = stackIter->first;
      double weight = pow((radius - distance)/(radius*distance),2.0);
      #ifdef VERBOSE
         cout << "Vertex: " << vertex->ToString() << "\t";
         cout << "Distance: " << distance << "\t";
         cout << "Weight: " << weight << endl;
      #endif
      sumWeights += weight;
      avgField += weight*(vertex->FieldVector());
   }
   avgField = avgField*(1.0/sumWeights);
   return avgField;
}

<commit_msg>Fix memory leak in FieldMap::Interpolate<commit_after>// FieldMap
// Author: Matthew Raso-Barnett  13/12/2010
#include <list>
#include <cmath>

#include "FieldMap.h"
#include "FileParser.h"
#include "FieldVertex.h"
#include "VertexStack.h"
#include "Particle.h"
#include "Run.h"

//#define VERBOSE

using namespace std;

//______________________________________________________________________________
// FieldMap -
//
//______________________________________________________________________________

ClassImp(FieldMap)

//_____________________________________________________________________________
FieldMap::FieldMap()
{
// Default constructor.
   Info("FieldMap", "Default Constructor");
}

//_____________________________________________________________________________
FieldMap::FieldMap(const FieldMap& /*other*/)
{
// Copy constructor.
}

//______________________________________________________________________________
FieldMap::~FieldMap()
{
// Destructor.
   Info("FieldMap", "Destructor");
}

//______________________________________________________________________________
// MagFieldMap -
//
//______________________________________________________________________________

ClassImp(MagFieldMap)

//_____________________________________________________________________________
MagFieldMap::MagFieldMap()
            :FieldMap(),
             fTree(NULL)
{
// Default constructor.
   Info("MagFieldMap", "Default Constructor");
}

//_____________________________________________________________________________
MagFieldMap::MagFieldMap(const string& name, const TGeoShape* shape, const TGeoMatrix* matrix)
            :FieldMap(),
             MagField(name, shape, matrix),
             fTree(NULL)
{
// Default constructor.
   Info("MagFieldMap", "Constructor");
}

//_____________________________________________________________________________
MagFieldMap::MagFieldMap(const MagFieldMap& other)
            :FieldMap(other),
             MagField(other),
             fTree(NULL)
{
// Copy constructor.
   Info("MagFieldMap", "Copy Constructor");
}

//______________________________________________________________________________
MagFieldMap::~MagFieldMap()
{
// Destructor.
   Info("MagFieldMap", "Destructor");
   if (fTree) delete fTree;
}

//______________________________________________________________________________
const TVector3 MagFieldMap::GetField(const TVector3& position) const
{
   // Perform interpolation to get current field
   Int_t numInterpolatePoints = 6;
   return this->Interpolate(position, numInterpolatePoints);
}

//______________________________________________________________________________
Bool_t MagFieldMap::BuildMap(const std::string& filename)
{
   // -- Take input file and initialise a KDTree object data structure to hold the field points.
   cout << "Building MagFieldMap from file: " << filename << endl;
   FileParser parser;
   // Get flat list of Field vertices from provided file using the parser
   vector<FieldVertex*> vertices;
   if (parser.ExtractFieldVertices(filename, vertices) == false) {
      Error("BuildMap","Failed to extract field vertices from: %s", filename.c_str());
      return false;
   }
   // For each vertex, convert coordinates to the global coordinate system
   vector<const FieldVertex*> global_vertices;
   vector<FieldVertex*>::const_iterator iter;
   for (iter = vertices.begin(); iter != vertices.end(); iter++) {
      FieldVertex global = this->ConvertToGlobalFrame((**iter));
      global_vertices.push_back(new FieldVertex(global));
   }
   // Build Tree structure of FieldVertices
   fTree = new KDTree(global_vertices);
   // Delete original local points
   for (iter = vertices.begin(); iter != vertices.end(); iter++) {if (*iter) delete *iter;}
   cout << "Successfully created MagFieldMap from " << global_vertices.size() << " points." << endl;
   return true;
}

//______________________________________________________________________________
TVector3 MagFieldMap::Interpolate(const TVector3& position, const Int_t numInterpolatePoints) const
{
   // -- For given position, find the n-nearest-neighbouring vertices (n being numInterpolatePoints)
   // -- and perform IDW interpolation using Modified Shepard's Method,
   // -- http://en.wikipedia.org/wiki/Inverse_distance_weighting
   FieldVertex vertex(position.X(), position.Y(), position.Z(), 0.,0.,0.,0.);
   const VertexStack* neighbours = fTree->NearestNeighbours(vertex, numInterpolatePoints);
   list<StackElement>::const_iterator stackIter;
   double radius = (neighbours->back()).second;
   double sumWeights = 0.;
   TVector3 avgField;
   for (stackIter = neighbours->begin(); stackIter != neighbours->end(); stackIter++) {
      double distance = stackIter->second;
      const FieldVertex* vertex = stackIter->first;
      double weight = pow((radius - distance)/(radius*distance),2.0);
      #ifdef VERBOSE
         cout << "Vertex: " << vertex->ToString() << "\t";
         cout << "Distance: " << distance << "\t";
         cout << "Weight: " << weight << endl;
      #endif
      sumWeights += weight;
      avgField += weight*(vertex->FieldVector());
   }
   avgField = avgField*(1.0/sumWeights);
   // Delete nearest neighbours now that we are finished with it
   delete neighbours;
   return avgField;
}

<|endoftext|>


<commit_before>#include "../common/std_headers.h"
#include "../common/jsonio.h"
#include "./jswrapbase.h"

using namespace arma;

void ThrowInvalidArgs(Isolate *isolate) {
  isolate->ThrowException(Exception::TypeError(String::NewFromUtf8(isolate, "Invalid arguments")));
}

void ThrowInvalidThis(Isolate *isolate) {
  isolate->ThrowException(Exception::TypeError(String::NewFromUtf8(isolate, "Invalid this, did you forget to call new?")));
}

void ThrowTypeError(Isolate *isolate, char const *s) {
  isolate->ThrowException(Exception::TypeError(String::NewFromUtf8(isolate, s)));
}

void ThrowRuntimeError(Isolate *isolate, char const *s) {
  isolate->ThrowException(Exception::Error(String::NewFromUtf8(isolate, s)));
}

/* ----------------------------------------------------------------------
  string I/O
*/

bool canConvJsToString(Isolate *isolate, Local<Value> it) {
  return it->IsString() || node::Buffer::HasInstance(it);
}
string convJsToString(Isolate *isolate, Local<Value> it) {
  if (it->IsString()) {
    String::Utf8Value v8str(it);
    return string((char *) *v8str, v8str.length());
  }
  else if (node::Buffer::HasInstance(it)) {
    char *data = node::Buffer::Data(it);
    size_t len = node::Buffer::Length(it);
    return string(data, data+len);
  }
  else {
    throw runtime_error("Can't convert to string");
  }
}
Local<Value> convStringToJs(Isolate *isolate, string const &it) {
  return String::NewFromUtf8(isolate, it.data(), String::kNormalString, it.size());
}
Local<Value> convStringToJsBuffer(Isolate *isolate, string const &it) {
  Local<Value> nb = node::Buffer::New(isolate, it.size()).ToLocalChecked();
  memcpy(node::Buffer::Data(nb), it.data(), it.size());
  return nb;
}

/* ----------------------------------------------------------------------
  arma::cx_double I/O

  arma::cx_double, the same as std::complex<double> is reflected into a simple {real:,imag:} object in JS. There's no binary wrapped type
  See also jsonio.cc: wrJson(..., arma::cx_double)
*/
bool canConvJsToCxDouble(Isolate *isolate, Local<Value> itv)
{
  if (itv->IsObject()) {
    Local<Object> it = itv->ToObject();
    Local<Value> realv = it->Get(String::NewFromUtf8(isolate, "real"));
    Local<Value> imagv = it->Get(String::NewFromUtf8(isolate, "imag"));
    if (realv->IsNumber() && imagv->IsNumber()) {
      return true;
    }
  }
  return false;
}
arma::cx_double convJsToCxDouble(Isolate *isolate, Local<Value> itv)
{
  if (itv->IsObject()) {
    Local<Object> it = itv->ToObject();
    Local<Value> realv = it->Get(String::NewFromUtf8(isolate, "real"));
    Local<Value> imagv = it->Get(String::NewFromUtf8(isolate, "imag"));
    if (realv->IsNumber() && imagv->IsNumber()) {
      return arma::cx_double(realv->NumberValue(), imagv->NumberValue());
    }
  }
  throw runtime_error("convJsToCxDouble: conversion failed");
}
Local<Object> convCxDoubleToJs(Isolate *isolate, arma::cx_double const &it)
{
  Local<Object> ret = Object::New(isolate);
  ret->Set(String::NewFromUtf8(isolate, "real"), Number::New(isolate, it.real()));
  ret->Set(String::NewFromUtf8(isolate, "imag"), Number::New(isolate, it.imag()));
  return ret;
}

/* ----------------------------------------------------------------------
  Enhancements to the JSON module
*/

/* ----------------------------------------------------------------------
  jsonstr I/O
*/
bool canConvJsToJsonstr(Isolate *isolate, Local<Value> value) {
  return true;
}

jsonstr convJsToJsonstr(Isolate *isolate, Local<Value> value)
{
  if (value->IsObject()) {
    Local<Value> toJsonString = value->ToObject()->Get(String::NewFromUtf8(isolate, "toJsonString")); // defined on all generated stubs
    if (!toJsonString.IsEmpty() && toJsonString->IsFunction()) {
      Local<Value> ret = toJsonString.As<Function>()->Call(value->ToObject(), 0, NULL);
      return jsonstr(convJsToString(isolate, ret->ToString()));
    }
  }

  Local<Object> global = isolate->GetCurrentContext()->Global();
  Local<Value> gJSON = global->Get(String::NewFromUtf8(isolate, "JSON"));
  assert(gJSON->IsObject());

  Local<Value> gStringify = gJSON->ToObject()->Get(String::NewFromUtf8(isolate, "stringify"));
  assert(!gStringify.IsEmpty() && "function not found: JSON.stringify");
  assert(gStringify->IsFunction() && "not a function: JSON.stringify");
  Local<Function> gJSON_stringify = gStringify.As<Function>();

  return jsonstr(convJsToString(isolate, gJSON_stringify->Call(gJSON, 1, &value)->ToString()));
}

Local<Value> convJsonstrToJs(Isolate *isolate, jsonstr const &it)
{
  Local<Object> global = isolate->GetCurrentContext()->Global();
  Local<Value> gJSON = global->Get(String::NewFromUtf8(isolate, "JSON"));
  assert(gJSON->IsObject());

  Local<Value> gParse = gJSON->ToObject()->Get(String::NewFromUtf8(isolate, "parse"));
  assert(!gParse.IsEmpty() && "function not found: JSON.parse");
  assert(gParse->IsFunction() && "not a function: JSON.parse");
  Local<Function> gJSON_parse = gParse.As<Function>();

  Local<Value> itJs = convStringToJs(isolate, it.it);
  Local<Value> ret = gJSON_parse->Call(gJSON, 1, &itJs);
  // WRITEME someday: This would be the place to handle ndarrays, if the jsonstr has blobs
  return ret;
}

/* ----------------------------------------------------------------------
  map<string, jsonstr> I/O
*/

bool canConvJsToMapStringJsonstr(Isolate *isolate, Local<Value> itv) {
  if (itv->IsObject()) return true;
  return false;
}

map<string, jsonstr> convJsToMapStringJsonstr(Isolate *isolate, Local<Value> itv) {

  if (itv->IsObject()) {
    map < string, jsonstr > ret;

    Local<Object> it = itv->ToObject();
    Local<Array> itKeys = it->GetOwnPropertyNames();

    size_t itKeysLen = itKeys->Length();
    for (size_t i=0; i<itKeysLen; i++) {
      Local<Value> itKey = itKeys->Get(i);
      Local<Value> itVal = it->Get(itKey);

      string cKey = convJsToString(isolate, itKey->ToString());
      jsonstr cVal = convJsToJsonstr(isolate, itVal);

      ret[cKey] = cVal;
    }
    return ret;
  }
  throw runtime_error("convJsToMapStringJsonstr: not an object");
}

// ----------------------------------------------------------------------

template<typename T>
bool canConvJsToArmaCol(Isolate *isolate, Local<Value> itv) {
  if (itv->IsObject()) {
    Local<Object> it = itv->ToObject();
    if (it->IsFloat32Array()) return true;
    if (it->IsFloat64Array()) return true;
    if (it->IsArray()) return true;
  }
  return false;
}
template<typename T>
bool canConvJsToArmaRow(Isolate *isolate, Local<Value> itv) {
  if (itv->IsObject()) {
    Local<Object> it = itv->ToObject();
    if (it->IsFloat32Array()) return true;
    if (it->IsFloat64Array()) return true;
    if (it->IsArray()) return true;
  }
  return false;
}

template<typename T>
arma::Col<T> convJsToArmaCol(Isolate *isolate, Local<Value> itv) {
  if (itv->IsObject()) {
    Local<Object> it = itv->ToObject();

    // Sort of wrong for T = cx_double. I believe it only sets the real part.
    if (it->IsFloat64Array()) {
      Float64Array *ita = Float64Array::Cast(*it);
      size_t itLen = ita->Length();
      double* itData = new double[itLen];
      ita->CopyContents(itData, itLen * sizeof(double));

      arma::Col<T> ret(itLen);
      for (size_t i=0; i<itLen; i++) ret(i) = itData[i];
      delete [] itData;
      return ret;
    }

    if (it->IsFloat32Array()) {
      Float32Array *ita = Float32Array::Cast(*it);
      size_t itLen = ita->Length();
      float* itData = new float[itLen];
      ita->CopyContents(itData, itLen * sizeof(float));

      arma::Col<T> ret(itLen);
      for (size_t i=0; i<itLen; i++) ret(i) = itData[i];
      delete [] itData;
      return ret;
    }

    // Also handle regular JS arrays
    if (it->IsArray()) {
      Local<Array> itArr = Local<Array>::Cast(it);
      size_t itArrLen = itArr->Length();
      arma::Col<T> ret(itArrLen);
      for (size_t i=0; i<itArrLen; i++) {
        ret(i) = itArr->Get(i)->NumberValue();
      }
      return ret;
    }
  }
  throw runtime_error("convJsToArmaCol: not an array");
}
template<typename T>
arma::Row<T> convJsToArmaRow(Isolate *isolate, Local<Value> itv) {
  if (itv->IsObject()) {
    Local<Object> it = itv->ToObject();

    // Sort of wrong for T = cx_double. I believe it only sets the real part.
    if (it->IsFloat64Array()) {
      Float64Array *ita = Float64Array::Cast(*it);
      size_t itLen = ita->Length();
      double* itData = new double[itLen];
      ita->CopyContents(itData, itLen * sizeof(double));

      arma::Row<T> ret(itLen);
      for (size_t i=0; i<itLen; i++) ret(i) = itData[i];
      delete [] itData;
      return ret;
    }

    if (it->IsFloat32Array()) {
      Float32Array *ita = Float32Array::Cast(*it);
      size_t itLen = ita->Length();
      float* itData = new float[itLen];
      ita->CopyContents(itData, itLen * sizeof(float));

      arma::Row<T> ret(itLen);
      for (size_t i=0; i<itLen; i++) ret(i) = itData[i];
      delete [] itData;
      return ret;
    }

    // Also handle regular JS arrays
    if (it->IsArray()) {
      Local<Array> itArr = Local<Array>::Cast(it);
      size_t itArrLen = itArr->Length();
      arma::Row<T> ret(itArrLen);
      for (size_t i=0; i<itArrLen; i++) {
        ret(i) = itArr->Get(i)->NumberValue();
      }
      return ret;
    }
  }
  throw runtime_error("convJsToArmaRow: not an array");
}

static double * mkFloat64Array(Isolate *isolate, size_t size, Local<Object> &ret)
{
  if (size > 100000000) throw runtime_error("mkFloat64Array: unreasonable size");

  Local<ArrayBuffer> ab = ArrayBuffer::New(isolate, size*sizeof(double));
  double *retData = (double *)ab->GetContents().Data();

  ret = Float64Array::New(ab, 0, size);

#if 0
  Local<Object> global = isolate->GetCurrentContext()->Global();
  Local<Value> float64Array = global->Get(String::NewFromUtf8(isolate, "Float64Array"));
  if (float64Array.IsEmpty()) throw runtime_error("Type not found: Float64Array");
  if (!float64Array->IsFunction()) throw runtime_error("Not a constructor: Float64Array");
  Local<Function> float64ArrayConstructor = float64Array.As<Function>();

  Local<Value> jsSize = Integer::NewFromUnsigned(isolate, (u_int)size);
  ret = float64ArrayConstructor->NewInstance(1, &jsSize);

  if (ret->GetIndexedPropertiesExternalArrayDataType() != kExternalDoubleArray) throw runtime_error("Failed to get Float64Array");
  if ((size_t)ret->GetIndexedPropertiesExternalArrayDataLength() != size) throw runtime_error("Got Float64Array of wrong size");

  double* retData = static_cast<double*>(ret->GetIndexedPropertiesExternalArrayData());
#endif

  return retData;
}

template<typename T>
Local<Object> convArmaColToJs(Isolate *isolate, arma::Col<T> const &it) {
  Local<Object> ret;
  double *retData = mkFloat64Array(isolate, it.n_elem, ret);
  for (size_t i=0; i<it.n_elem; i++) {
    retData[i] = it(i);
  }

  return ret;
}

template<typename T>
Local<Object> convArmaRowToJs(Isolate *isolate, arma::Row<T> const &it) {
  Local<Object> ret;
  double *retData = mkFloat64Array(isolate, it.n_elem, ret);
  for (size_t i=0; i<it.n_elem; i++) {
    retData[i] = it(i);
  }

  return ret;
}

/* arma::Mat conversion.
   arma::Mats are in column-major order. That means the elements are
   0  4  8  12
   1  5  9  13
   2  6  10 14
   3  7  11 15
 */

template<typename T>
bool canConvJsToArmaMat(Isolate *isolate, Local<Value> it)
{
  if (it->IsArray()) return true;
  return false;
}

template<typename T>
arma::Mat<T> convJsToArmaMat(Isolate *isolate, Local<Value> it, size_t nRows, size_t nCols)
{
  if (it->IsArray()) {

    Local<Array> itArr = Local<Array>::Cast(it);
    size_t itArrLen = itArr->Length();

    if (nRows == 0 && nCols == 0) {
      switch (itArrLen) {
      case 16: nRows = 4; nCols = 4; break;
      case 9:  nRows = 3; nCols = 3; break;
      case 4:  nRows = 2; nCols = 2; break;
      default: throw runtime_error(stringprintf("convJsToArmaMat: unknown size %d", int(itArrLen)));
      }
    } else {
      if (nRows * nCols != itArrLen) {
        throw runtime_error(stringprintf("convJsToArmaMat: wrong size: %d != %dx%d", int(itArrLen), int(nRows), int(nCols)));
      }
    }

    arma::Mat<T> ret(nRows, nCols);

    for (size_t i=0; i<itArrLen; i++) {
      ret(i) = itArr->Get(i)->NumberValue();
    }
    return ret;
  }
  throw runtime_error("convJsToArmaMat: not an array");
}

template<typename T>
Local<Object> convArmaMatToJs(Isolate *isolate, arma::Mat<T> const &it)
{
  Local<Object> ret;
  double *retData = mkFloat64Array(isolate, it.n_elem, ret);
  for (size_t ei = 0; ei < it.n_elem; ei++) {
    retData[ei] = it(ei);
  }
  return ret;
}

template bool canConvJsToArmaCol<double>(Isolate *isolate, Local<Value> itv);
template arma::Col<double> convJsToArmaCol<double>(Isolate *isolate, Local<Value> itv);
template Local<Object> convArmaColToJs<double>(Isolate *isolate, arma::Col<double> const &it);
template bool canConvJsToArmaRow<double>(Isolate *isolate, Local<Value> itv);
template arma::Row<double> convJsToArmaRow<double>(Isolate *isolate, Local<Value> itv);
template Local<Object> convArmaRowToJs<double>(Isolate *isolate, arma::Row<double> const &it);
template bool canConvJsToArmaMat<double>(Isolate *isolate, Local<Value> it);
template arma::Mat<double> convJsToArmaMat<double>(Isolate *isolate, Local<Value> it, size_t nRows, size_t nCols);
template Local<Object> convArmaMatToJs<double>(Isolate *isolate, arma::Mat<double> const &it);

template bool canConvJsToArmaCol<float>(Isolate *isolate, Local<Value> itv);
template arma::Col<float> convJsToArmaCol<float>(Isolate *isolate, Local<Value> itv);
template Local<Object> convArmaColToJs<float>(Isolate *isolate, arma::Col<float> const &it);
template bool canConvJsToArmaRow<float>(Isolate *isolate, Local<Value> itv);
template arma::Row<float> convJsToArmaRow<float>(Isolate *isolate, Local<Value> itv);
template Local<Object> convArmaRowToJs<float>(Isolate *isolate, arma::Row<float> const &it);
template bool canConvJsToArmaMat<float>(Isolate *isolate, Local<Value> it);
template arma::Mat<float> convJsToArmaMat<float>(Isolate *isolate, Local<Value> it, size_t nRows, size_t nCols);
template Local<Object> convArmaMatToJs<float>(Isolate *isolate, arma::Mat<float> const &it);

template bool canConvJsToArmaCol<S64>(Isolate *isolate, Local<Value> itv);
template arma::Col<S64> convJsToArmaCol<S64>(Isolate *isolate, Local<Value> itv);
template Local<Object> convArmaColToJs<S64>(Isolate *isolate, arma::Col<S64> const &it);
template bool canConvJsToArmaRow<S64>(Isolate *isolate, Local<Value> itv);
template arma::Row<S64> convJsToArmaRow<S64>(Isolate *isolate, Local<Value> itv);
template Local<Object> convArmaRowToJs<S64>(Isolate *isolate, arma::Row<S64> const &it);
template bool canConvJsToArmaMat<S64>(Isolate *isolate, Local<Value> it);
template arma::Mat<S64> convJsToArmaMat<S64>(Isolate *isolate, Local<Value> it, size_t nRows, size_t nCols);
template Local<Object> convArmaMatToJs<S64>(Isolate *isolate, arma::Mat<S64> const &it);

template bool canConvJsToArmaCol<U64>(Isolate *isolate, Local<Value> itv);
template arma::Col<U64> convJsToArmaCol<U64>(Isolate *isolate, Local<Value> itv);
template Local<Object> convArmaColToJs<U64>(Isolate *isolate, arma::Col<U64> const &it);
template bool canConvJsToArmaRow<U64>(Isolate *isolate, Local<Value> itv);
template arma::Row<U64> convJsToArmaRow<U64>(Isolate *isolate, Local<Value> itv);
template Local<Object> convArmaRowToJs<U64>(Isolate *isolate, arma::Row<U64> const &it);
template bool canConvJsToArmaMat<U64>(Isolate *isolate, Local<Value> it);
template arma::Mat<U64> convJsToArmaMat<U64>(Isolate *isolate, Local<Value> it, size_t nRows, size_t nCols);
template Local<Object> convArmaMatToJs<U64>(Isolate *isolate, arma::Mat<U64> const &it);

template bool canConvJsToArmaCol<arma::cx_double>(Isolate *isolate, Local<Value> itv);
//template arma::Col<arma::cx_double> convJsToArmaCol<arma::cx_double>(Isolate *isolate, Local<Value> itv);
//template Local<Object> convArmaColToJs<arma::cx_double>(Isolate *isolate, arma::Col<arma::cx_double> const &it);
template bool canConvJsToArmaRow<arma::cx_double>(Isolate *isolate, Local<Value> itv);
//template arma::Row<arma::cx_double> convJsToArmaRow<arma::cx_double>(Isolate *isolate, Local<Value> itv);
//template Local<Object> convArmaRowToJs<arma::cx_double>(Isolate *isolate, arma::Row<arma::cx_double> const &it);
template bool canConvJsToArmaMat<arma::cx_double>(Isolate *isolate, Local<Value> it);
//template arma::Mat<arma::cx_double> convJsToArmaMat<arma::cx_double>(Isolate *isolate, Local<Value> it, size_t nRows, size_t nCols);
//template Local<Object> convArmaMatToJs<arma::cx_double>(Isolate *isolate, arma::Mat<arma::cx_double> const &it);
<commit_msg>Delete jswrapbase.cc<commit_after><|endoftext|>


<commit_before>// InputXML.cpp
// Implements XML input handling class
#include <iostream>
#include <string.h>
#include <sys/stat.h>

#include "InputXML.h"

#include "Timer.h"
#include "GenException.h"
#include "Logician.h"
#include "Model.h"

InputXML* InputXML::_instance = 0;

/// implement a searchpath paradigm
string searchPathForFile(string filename, string inputPath, string envPath, string builtinPath)
{
  struct stat stat_info;
  int stat_result = -1;
  string::size_type begin = 0;
  string::size_type end = 0;
  string searchFilename;

  string searchPath = "./";  // initialize search path with this directory

  if (inputPath.size() > 0)
    searchPath += ":" + inputPath;
  if (envPath.size() > 0)
    searchPath += ":" + envPath;
  if (builtinPath.size() > 0)
    searchPath += ":" + builtinPath + ":";

  while (stat_result != 0 && begin < searchPath.length())
  {
    end = searchPath.find(":",begin);
    string thisDir = searchPath.substr(begin,end-begin);
    if (thisDir[thisDir.length()-1] != '/')
  thisDir += "/";
    searchFilename = thisDir +  filename;

    stat_result = stat(searchFilename.c_str(),&stat_info);
    begin = end + 1;
  }

  return strdup(searchFilename.c_str());

}

string InputXML::main_schema = searchPathForFile("cyclus.rng", "../../src", getenv("CYCLUS_SRC_DIR"), getenv("PATH"));

InputXML::InputXML()
{

  cur_ns = "";

}

InputXML* InputXML::Instance() {

  if (0 == _instance)
  _instance = new InputXML();

  return _instance;

}

xmlDocPtr InputXML::validate_file(xmlFileInfo *fileInfo)
{
  xmlRelaxNGParserCtxtPtr ctxt = xmlRelaxNGNewParserCtxt(fileInfo->schema->c_str());
  if (NULL == ctxt)
  throw GenException("Failed to generate parser from schema: " + *(fileInfo->schema));

  xmlRelaxNGPtr schema = xmlRelaxNGParse(ctxt);

  xmlRelaxNGValidCtxtPtr vctxt = xmlRelaxNGNewValidCtxt(schema);

  xmlDocPtr doc = xmlReadFile(fileInfo->filename.c_str(), NULL,0);
  if (NULL == doc) {
    throw GenException("Failed to parse: " + fileInfo->filename);
  }

  if (xmlRelaxNGValidateDoc(vctxt,doc))
    throw GenException("Invalid XML file; file: "
      + fileInfo->filename
      + " does not validate against schema "
      + *(fileInfo->schema));
  else
    cerr << "File " << fileInfo->filename << " is valid against schema "
    << *(fileInfo->schema) << endl;

  /// free up some data

  return doc;

}

void InputXML::stripCurNS()
{

  if ("" == cur_ns)
  throw GenException("Unable to strip tokens from an empty namespace.");

  string::iterator pos = cur_ns.end();
  cur_ns.erase(--pos);

  size_t delimeter_pos = cur_ns.rfind(':');

  if (string::npos != delimeter_pos)
  cur_ns.erase(delimeter_pos);
  else
  cur_ns.erase();

}

void InputXML::load_file(string filename)
{
  curFilePtr = new xmlFileInfo;

  xmlFileInfo &inputFile = *curFilePtr;

  inputFile.filename = filename;
  inputFile.schema = &main_schema;
  inputFile.doc = validate_file(&inputFile);

  /* Create xpath evaluation context */
  inputFile.xpathCtxt = xmlXPathNewContext(inputFile.doc);
  if(inputFile.xpathCtxt == NULL) {
    fprintf(stderr,"Error: unable to create new xpath context \n");
  }

  Commodity::load_commodities();

  Material::load_recipes();

  Model::load_converters();
  Model::load_markets();
  Model::load_facilities();
  Model::load_regions();
  Model::load_institutions();

  TI->load_simulation();

  // delete/free mem

}

void InputXML::load_recipebook(string filename)
{
  /// store parent file info
  fileStack.push(curFilePtr);

  curFilePtr = new xmlFileInfo;
  xmlFileInfo &recipebook = *curFilePtr;

  recipebook.filename = filename;
  recipebook.schema = &main_schema;
  recipebook.doc = validate_file(&recipebook);
  recipebook.xpathCtxt = xmlXPathNewContext(recipebook.doc);

  Material::load_recipes();

  // get rid of recipebook, freeing memory
  delete curFilePtr;

  /// restore parent file info
  curFilePtr = fileStack.top();
  fileStack.pop();

}

void InputXML::load_facilitycatalog(string filename)
{
  /// store parent file info
  fileStack.push(curFilePtr);

  curFilePtr = new xmlFileInfo;
  xmlFileInfo &facilitycatalog = *curFilePtr;

  facilitycatalog.filename = filename;
  facilitycatalog.schema = &main_schema;
  facilitycatalog.doc = validate_file(&facilitycatalog);
  facilitycatalog.xpathCtxt = xmlXPathNewContext(facilitycatalog.doc);

  /// load here???
  Model::load_facilities();

  // get rid of facilitycatalog, freeing memory
  delete curFilePtr;

  /// restore parent file info
  curFilePtr = fileStack.top();
  fileStack.pop();

}

/*xmlNodeSetPtr InputXML::get_xpath_axes(xmlNodePtr cur,const char* expression)
{

  xmlXPathContextPtr xpathCtxt = curFilePtr->xpathCtxt;
  xpathCtxt->node = cur;

  xmlXPathObjectPtr xpathAx = xmlXPathEvalExpression((const xmlChar*)expression, xpathCtxt);
  if(xpathAx == NULL) {
    fprintf(stderr,"Error: unable to evaluate xpath expression \"%s\"\n", expression);
    xmlXPathFreeContext(xpathCtxt);
  }

  return xpathAx->nodeaxes;
}
*/
xmlNodeSetPtr InputXML::get_xpath_elements(xmlNodePtr cur,const char* expression)
{

  xmlXPathContextPtr xpathCtxt = curFilePtr->xpathCtxt;
  xpathCtxt->node = cur;

  /* Evaluate xpath expression */
  xmlXPathObjectPtr xpathObj = xmlXPathEvalExpression((const xmlChar*)expression, xpathCtxt);
  if(xpathObj == NULL) {
    fprintf(stderr,"Error: unable to evaluate xpath expression \"%s\"\n", expression);
    xmlXPathFreeContext(xpathCtxt);
  }

  return xpathObj->nodesetval;

  // when and how to cleanup memory allocation?

}

xmlNodePtr InputXML::get_xpath_element(xmlNodePtr cur,const char* expression)
{

  xmlXPathContextPtr xpathCtxt = curFilePtr->xpathCtxt;
  xpathCtxt->node = cur;

  /* Evaluate xpath expression */
  xmlXPathObjectPtr xpathObj = xmlXPathEvalExpression((const xmlChar*)expression, xpathCtxt);
  if(xpathObj == NULL) {
    fprintf(stderr,"Error: unable to evaluate xpath expression \"%s\"\n", expression);
    xmlXPathFreeContext(xpathCtxt);
  }

  return xpathObj->nodesetval->nodeTab[0];

  // when and how to cleanup memory allocation?

}

const char* InputXML::get_xpath_content(xmlNodePtr cur,const char* expression)
{

  xmlXPathContextPtr xpathCtxt = curFilePtr->xpathCtxt;
  xpathCtxt->node = cur;

  /* Evaluate xpath expression */
  xmlXPathObjectPtr xpathObj = xmlXPathEvalExpression((const xmlChar*)expression, xpathCtxt);
  if(xpathObj == NULL) {
    fprintf(stderr,"Error: unable to evaluate xpath expression \"%s\"\n", expression);
    xmlXPathFreeContext(xpathCtxt);
  }

  return (const char*)(xpathObj->nodesetval->nodeTab[0]->children->content);

  // when and how to cleanup memory allocation?

}

const char* InputXML::get_xpath_name(xmlNodePtr cur,const char* expression)
{

  xmlXPathContextPtr xpathCtxt = curFilePtr->xpathCtxt;
  xpathCtxt->node = cur;

  /* Evaluate xpath expression */
  xmlXPathObjectPtr xpathObj = xmlXPathEvalExpression((const xmlChar*)expression, xpathCtxt);
  if(xpathObj == NULL) {
    fprintf(stderr,"Error: unable to evaluate xpath expression \"%s\"\n", expression);
    xmlXPathFreeContext(xpathCtxt);
  }

  return (const char*)(xpathObj->nodesetval->nodeTab[0]->name);

  // when and how to cleanup memory allocation?

}

<commit_msg>More InputXML editing<commit_after>// InputXML.cpp
// Implements XML input handling class
#include <iostream>
#include <string.h>
#include <sys/stat.h>

#include "InputXML.h"

#include "Timer.h"
#include "GenException.h"
#include "Logician.h"
#include "Model.h"

InputXML* InputXML::_instance = 0;

/// implement a searchpath paradigm
string searchPathForFile(string filename, string inputPath, string envPath, string builtinPath)
{
  struct stat stat_info;
  int stat_result = -1;
  string::size_type begin = 0;
  string::size_type end = 0;
  string searchFilename;

  string searchPath = "./";  // initialize search path with this directory

  if (inputPath.size() > 0)
    searchPath += ":" + inputPath;
  if (envPath.size() > 0)
    searchPath += ":" + envPath;
  if (builtinPath.size() > 0)
    searchPath += ":" + builtinPath + ":";

  while (stat_result != 0 && begin < searchPath.length())
  {
    end = searchPath.find(":",begin);
    string thisDir = searchPath.substr(begin,end-begin);
    if (thisDir[thisDir.length()-1] != '/')
  thisDir += "/";
    searchFilename = thisDir +  filename;

    stat_result = stat(searchFilename.c_str(),&stat_info);
    begin = end + 1;
  }

  return strdup(searchFilename.c_str());

}

string InputXML::main_schema = searchPathForFile("cyclus.rng","", getenv("CYCLUS_SRC_DIR"), getenv("PATH"));

InputXML::InputXML()
{

  cur_ns = "";

}

InputXML* InputXML::Instance() {

  if (0 == _instance)
  _instance = new InputXML();

  return _instance;

}

xmlDocPtr InputXML::validate_file(xmlFileInfo *fileInfo)
{
  xmlRelaxNGParserCtxtPtr ctxt = xmlRelaxNGNewParserCtxt(fileInfo->schema->c_str());
  if (NULL == ctxt)
  throw GenException("Failed to generate parser from schema: " + *(fileInfo->schema));

  xmlRelaxNGPtr schema = xmlRelaxNGParse(ctxt);

  xmlRelaxNGValidCtxtPtr vctxt = xmlRelaxNGNewValidCtxt(schema);

  xmlDocPtr doc = xmlReadFile(fileInfo->filename.c_str(), NULL,0);
  if (NULL == doc) {
    throw GenException("Failed to parse: " + fileInfo->filename);
  }

  if (xmlRelaxNGValidateDoc(vctxt,doc))
    throw GenException("Invalid XML file; file: "
      + fileInfo->filename
      + " does not validate against schema "
      + *(fileInfo->schema));
  else
    cerr << "File " << fileInfo->filename << " is valid against schema "
    << *(fileInfo->schema) << endl;

  /// free up some data

  return doc;

}

void InputXML::stripCurNS()
{

  if ("" == cur_ns)
  throw GenException("Unable to strip tokens from an empty namespace.");

  string::iterator pos = cur_ns.end();
  cur_ns.erase(--pos);

  size_t delimeter_pos = cur_ns.rfind(':');

  if (string::npos != delimeter_pos)
  cur_ns.erase(delimeter_pos);
  else
  cur_ns.erase();

}

void InputXML::load_file(string filename)
{
  curFilePtr = new xmlFileInfo;

  xmlFileInfo &inputFile = *curFilePtr;

  inputFile.filename = filename;
  inputFile.schema = &main_schema;
  inputFile.doc = validate_file(&inputFile);

  /* Create xpath evaluation context */
  inputFile.xpathCtxt = xmlXPathNewContext(inputFile.doc);
  if(inputFile.xpathCtxt == NULL) {
    fprintf(stderr,"Error: unable to create new xpath context \n");
  }

  Commodity::load_commodities();

  Material::load_recipes();

  Model::load_converters();
  Model::load_markets();
  Model::load_facilities();
  Model::load_regions();
  Model::load_institutions();

  TI->load_simulation();

  // delete/free mem

}

void InputXML::load_recipebook(string filename)
{
  /// store parent file info
  fileStack.push(curFilePtr);

  curFilePtr = new xmlFileInfo;
  xmlFileInfo &recipebook = *curFilePtr;

  recipebook.filename = filename;
  recipebook.schema = &main_schema;
  recipebook.doc = validate_file(&recipebook);
  recipebook.xpathCtxt = xmlXPathNewContext(recipebook.doc);

  Material::load_recipes();

  // get rid of recipebook, freeing memory
  delete curFilePtr;

  /// restore parent file info
  curFilePtr = fileStack.top();
  fileStack.pop();

}

void InputXML::load_facilitycatalog(string filename)
{
  /// store parent file info
  fileStack.push(curFilePtr);

  curFilePtr = new xmlFileInfo;
  xmlFileInfo &facilitycatalog = *curFilePtr;

  facilitycatalog.filename = filename;
  facilitycatalog.schema = &main_schema;
  facilitycatalog.doc = validate_file(&facilitycatalog);
  facilitycatalog.xpathCtxt = xmlXPathNewContext(facilitycatalog.doc);

  /// load here???
  Model::load_facilities();

  // get rid of facilitycatalog, freeing memory
  delete curFilePtr;

  /// restore parent file info
  curFilePtr = fileStack.top();
  fileStack.pop();

}

/*xmlNodeSetPtr InputXML::get_xpath_axes(xmlNodePtr cur,const char* expression)
{

  xmlXPathContextPtr xpathCtxt = curFilePtr->xpathCtxt;
  xpathCtxt->node = cur;

  xmlXPathObjectPtr xpathAx = xmlXPathEvalExpression((const xmlChar*)expression, xpathCtxt);
  if(xpathAx == NULL) {
    fprintf(stderr,"Error: unable to evaluate xpath expression \"%s\"\n", expression);
    xmlXPathFreeContext(xpathCtxt);
  }

  return xpathAx->nodeaxes;
}
*/
xmlNodeSetPtr InputXML::get_xpath_elements(xmlNodePtr cur,const char* expression)
{

  xmlXPathContextPtr xpathCtxt = curFilePtr->xpathCtxt;
  xpathCtxt->node = cur;

  /* Evaluate xpath expression */
  xmlXPathObjectPtr xpathObj = xmlXPathEvalExpression((const xmlChar*)expression, xpathCtxt);
  if(xpathObj == NULL) {
    fprintf(stderr,"Error: unable to evaluate xpath expression \"%s\"\n", expression);
    xmlXPathFreeContext(xpathCtxt);
  }

  return xpathObj->nodesetval;

  // when and how to cleanup memory allocation?

}

xmlNodePtr InputXML::get_xpath_element(xmlNodePtr cur,const char* expression)
{

  xmlXPathContextPtr xpathCtxt = curFilePtr->xpathCtxt;
  xpathCtxt->node = cur;

  /* Evaluate xpath expression */
  xmlXPathObjectPtr xpathObj = xmlXPathEvalExpression((const xmlChar*)expression, xpathCtxt);
  if(xpathObj == NULL) {
    fprintf(stderr,"Error: unable to evaluate xpath expression \"%s\"\n", expression);
    xmlXPathFreeContext(xpathCtxt);
  }

  return xpathObj->nodesetval->nodeTab[0];

  // when and how to cleanup memory allocation?

}

const char* InputXML::get_xpath_content(xmlNodePtr cur,const char* expression)
{

  xmlXPathContextPtr xpathCtxt = curFilePtr->xpathCtxt;
  xpathCtxt->node = cur;

  /* Evaluate xpath expression */
  xmlXPathObjectPtr xpathObj = xmlXPathEvalExpression((const xmlChar*)expression, xpathCtxt);
  if(xpathObj == NULL) {
    fprintf(stderr,"Error: unable to evaluate xpath expression \"%s\"\n", expression);
    xmlXPathFreeContext(xpathCtxt);
  }

  return (const char*)(xpathObj->nodesetval->nodeTab[0]->children->content);

  // when and how to cleanup memory allocation?

}

const char* InputXML::get_xpath_name(xmlNodePtr cur,const char* expression)
{

  xmlXPathContextPtr xpathCtxt = curFilePtr->xpathCtxt;
  xpathCtxt->node = cur;

  /* Evaluate xpath expression */
  xmlXPathObjectPtr xpathObj = xmlXPathEvalExpression((const xmlChar*)expression, xpathCtxt);
  if(xpathObj == NULL) {
    fprintf(stderr,"Error: unable to evaluate xpath expression \"%s\"\n", expression);
    xmlXPathFreeContext(xpathCtxt);
  }

  return (const char*)(xpathObj->nodesetval->nodeTab[0]->name);

  // when and how to cleanup memory allocation?

}

<|endoftext|>


<commit_before>#include <ortools/sat/cp_model.h>

#include <rice/Array.hpp>
#include <rice/Constructor.hpp>
#include <rice/Module.hpp>

using operations_research::sat::BoolVar;
using operations_research::sat::Constraint;
using operations_research::sat::CpModelBuilder;
using operations_research::sat::CpSolverResponse;
using operations_research::sat::CpSolverStatus;
using operations_research::sat::LinearExpr;
using operations_research::sat::IntVar;
using operations_research::sat::IntervalVar;
using operations_research::sat::Model;
using operations_research::sat::NewFeasibleSolutionObserver;
using operations_research::sat::SatParameters;
using operations_research::sat::SolutionBooleanValue;
using operations_research::sat::SolutionIntegerValue;

using Rice::Array;
using Rice::Object;
using Rice::String;
using Rice::Symbol;

template<>
inline
LinearExpr from_ruby<LinearExpr>(Object x)
{
  LinearExpr expr;

  if (x.respond_to("to_i")) {
    expr = from_ruby<int64>(x.call("to_i"));
  } else if (x.respond_to("vars")) {
    Array vars = x.call("vars");
    for(auto const& var: vars) {
      auto cvar = (Array) var;
      // TODO clean up
      Object o = cvar[0];
      std::string type = ((String) o.call("class").call("name")).str();
      if (type == "ORTools::BoolVar") {
        expr.AddTerm(from_ruby<BoolVar>(cvar[0]), from_ruby<int64>(cvar[1]));
      } else if (type == "Integer") {
        expr.AddConstant(from_ruby<int64>(cvar[0]) * from_ruby<int64>(cvar[1]));
      } else {
        expr.AddTerm(from_ruby<IntVar>(cvar[0]), from_ruby<int64>(cvar[1]));
      }
    }
  } else {
    std::string type = ((String) x.call("class").call("name")).str();
    if (type == "ORTools::BoolVar") {
      expr = from_ruby<BoolVar>(x);
    } else {
      expr = from_ruby<IntVar>(x);
    }
  }

  return expr;
}

// need a wrapper class since absl::Span doesn't own
class IntVarSpan {
  std::vector<IntVar> vec;
  public:
    IntVarSpan(Object x) {
      Array a = Array(x);
      vec.reserve(a.size());
      for (std::size_t i = 0; i < a.size(); ++i) {
        vec.push_back(from_ruby<IntVar>(a[i]));
      }
    }
    operator absl::Span<const IntVar>() {
      return absl::Span<const IntVar>(vec);
    }
};

template<>
inline
IntVarSpan from_ruby<IntVarSpan>(Object x)
{
  return IntVarSpan(x);
}

// need a wrapper class since absl::Span doesn't own
class IntervalVarSpan {
  std::vector<IntervalVar> vec;
  public:
    IntervalVarSpan(Object x) {
      Array a = Array(x);
      vec.reserve(a.size());
      for (std::size_t i = 0; i < a.size(); ++i) {
        vec.push_back(from_ruby<IntervalVar>(a[i]));
      }
    }
    operator absl::Span<const IntervalVar>() {
      return absl::Span<const IntervalVar>(vec);
    }
};

template<>
inline
IntervalVarSpan from_ruby<IntervalVarSpan>(Object x)
{
  return IntervalVarSpan(x);
}

// need a wrapper class since absl::Span doesn't own
class LinearExprSpan {
  std::vector<LinearExpr> vec;
  public:
    LinearExprSpan(Object x) {
      Array a = Array(x);
      vec.reserve(a.size());
      for (std::size_t i = 0; i < a.size(); ++i) {
        vec.push_back(from_ruby<LinearExpr>(a[i]));
      }
    }
    operator absl::Span<const LinearExpr>() {
      return absl::Span<const LinearExpr>(vec);
    }
};

template<>
inline
LinearExprSpan from_ruby<LinearExprSpan>(Object x)
{
  return LinearExprSpan(x);
}

// need a wrapper class since absl::Span doesn't own
class BoolVarSpan {
  std::vector<BoolVar> vec;
  public:
    BoolVarSpan(Object x) {
      Array a = Array(x);
      vec.reserve(a.size());
      for (std::size_t i = 0; i < a.size(); ++i) {
        vec.push_back(from_ruby<BoolVar>(a[i]));
      }
    }
    operator absl::Span<const BoolVar>() {
      return absl::Span<const BoolVar>(vec);
    }
};

template<>
inline
BoolVarSpan from_ruby<BoolVarSpan>(Object x)
{
  return BoolVarSpan(x);
}

void init_constraint(Rice::Module& m) {
  Rice::define_class_under<IntVar>(m, "SatIntVar")
    .define_method("name", &IntVar::Name);

  Rice::define_class_under<IntervalVar>(m, "SatIntervalVar")
    .define_method("name", &IntervalVar::Name);

  Rice::define_class_under<Constraint>(m, "SatConstraint");

  Rice::define_class_under<BoolVar>(m, "BoolVar")
    .define_method("name", &BoolVar::Name)
    .define_method("index", &BoolVar::index)
    .define_method("not", &BoolVar::Not)
    .define_method(
      "inspect",
      *[](BoolVar& self) {
        String name(self.Name());
        return "#<ORTools::BoolVar @name=" + name.inspect().str() + ">";
      });

  Rice::define_class_under<SatParameters>(m, "SatParameters")
    .define_constructor(Rice::Constructor<SatParameters>())
    .define_method("max_time_in_seconds=",
    *[](SatParameters& self, double value) {
      self.set_max_time_in_seconds(value);
    });

  Rice::define_class_under<CpModelBuilder>(m, "CpModel")
    .define_constructor(Rice::Constructor<CpModelBuilder>())
    .define_method(
      "new_int_var",
      *[](CpModelBuilder& self, int64 start, int64 end, std::string name) {
        const operations_research::Domain domain(start, end);
        return self.NewIntVar(domain).WithName(name);
      })
    .define_method(
      "new_bool_var",
      *[](CpModelBuilder& self, std::string name) {
        return self.NewBoolVar().WithName(name);
      })
    .define_method(
      "new_interval_var",
      *[](CpModelBuilder& self, IntVar start, IntVar size, IntVar end, std::string name) {
        return self.NewIntervalVar(start, size, end).WithName(name);
      })
    .define_method(
      "new_constant",
      *[](CpModelBuilder& self, int64 value) {
        return self.NewConstant(value);
      })
    .define_method(
      "true_var",
      *[](CpModelBuilder& self) {
        return self.TrueVar();
      })
    .define_method(
      "false_var",
      *[](CpModelBuilder& self) {
        return self.FalseVar();
      })
    .define_method(
      "add_equality",
      *[](CpModelBuilder& self, LinearExpr x, LinearExpr y) {
        self.AddEquality(x, y);
      })
    .define_method(
      "add_not_equal",
      *[](CpModelBuilder& self, LinearExpr x, LinearExpr y) {
        self.AddNotEqual(x, y);
      })
    .define_method(
      "add_greater_than",
      *[](CpModelBuilder& self, LinearExpr x, LinearExpr y) {
        self.AddGreaterThan(x, y);
      })
    .define_method(
      "add_greater_or_equal",
      *[](CpModelBuilder& self, LinearExpr x, LinearExpr y) {
        self.AddGreaterOrEqual(x, y);
      })
    .define_method(
      "add_less_than",
      *[](CpModelBuilder& self, LinearExpr x, LinearExpr y) {
        self.AddLessThan(x, y);
      })
    .define_method(
      "add_less_or_equal",
      *[](CpModelBuilder& self, LinearExpr x, LinearExpr y) {
        self.AddLessOrEqual(x, y);
      })
    .define_method(
      "add_all_different",
      *[](CpModelBuilder& self, IntVarSpan vars) {
        self.AddAllDifferent(vars);
      })
    .define_method(
      "add_min_equality",
      *[](CpModelBuilder& self, IntVar target, IntVarSpan vars) {
        self.AddMinEquality(target, vars);
      })
    .define_method(
      "add_lin_min_equality",
      *[](CpModelBuilder& self, LinearExpr target, LinearExprSpan exprs) {
        self.AddLinMinEquality(target, exprs);
      })
    .define_method(
      "add_max_equality",
      *[](CpModelBuilder& self, IntVar target, IntVarSpan vars) {
        self.AddMaxEquality(target, vars);
      })
    .define_method(
      "add_lin_max_equality",
      *[](CpModelBuilder& self, LinearExpr target, LinearExprSpan exprs) {
        self.AddLinMaxEquality(target, exprs);
      })
    .define_method(
      "add_division_equality",
      *[](CpModelBuilder& self, IntVar target, IntVar numerator, IntVar denominator) {
        self.AddDivisionEquality(target, numerator, denominator);
      })
    .define_method(
      "add_abs_equality",
      *[](CpModelBuilder& self, IntVar target, IntVar var) {
        self.AddAbsEquality(target, var);
      })
    .define_method(
      "add_modulo_equality",
      *[](CpModelBuilder& self, IntVar target, IntVar var, IntVar mod) {
        self.AddModuloEquality(target, var, mod);
      })
    .define_method(
      "add_product_equality",
      *[](CpModelBuilder& self, IntVar target, IntVarSpan vars) {
        self.AddProductEquality(target, vars);
      })
    .define_method(
      "add_no_overlap",
      *[](CpModelBuilder& self, IntervalVarSpan vars) {
        self.AddNoOverlap(vars);
      })
    .define_method(
      "add_bool_or",
      *[](CpModelBuilder& self, BoolVarSpan literals) {
        self.AddBoolOr(literals);
      })
    .define_method("add_implication", &CpModelBuilder::AddImplication)
    .define_method(
      "maximize",
      *[](CpModelBuilder& self, LinearExpr expr) {
        self.Maximize(expr);
      })
    .define_method(
      "minimize",
      *[](CpModelBuilder& self, LinearExpr expr) {
        self.Minimize(expr);
      })
    .define_method(
      "scale_objective_by",
      *[](CpModelBuilder& self, double scaling) {
        self.ScaleObjectiveBy(scaling);
      });

  Rice::define_class_under(m, "CpSolver")
    .define_method(
      "_solve_with_observer",
      *[](Object self, CpModelBuilder& model, SatParameters& parameters, Object callback, bool all_solutions) {
        Model m;

        if (all_solutions) {
          // set parameters for SearchForAllSolutions
          parameters.set_enumerate_all_solutions(true);
        }
        m.Add(NewSatParameters(parameters));

        m.Add(NewFeasibleSolutionObserver(
          [callback](const CpSolverResponse& r) {
            // TODO find a better way to do this
            callback.call("response=", r);
            callback.call("on_solution_callback");
          })
        );
        return SolveCpModel(model.Build(), &m);
      })
    .define_method(
      "_solve",
      *[](Object self, CpModelBuilder& model, SatParameters& parameters) {
        Model m;
        m.Add(NewSatParameters(parameters));
        return SolveCpModel(model.Build(), &m);
      })
    .define_method(
      "_solution_integer_value",
      *[](Object self, CpSolverResponse& response, IntVar& x) {
        return SolutionIntegerValue(response, x);
      })
    .define_method(
      "_solution_boolean_value",
      *[](Object self, CpSolverResponse& response, BoolVar& x) {
        return SolutionBooleanValue(response, x);
      });

  Rice::define_class_under<CpSolverResponse>(m, "CpSolverResponse")
    .define_method("objective_value", &CpSolverResponse::objective_value)
    .define_method("num_conflicts", &CpSolverResponse::num_conflicts)
    .define_method("num_branches", &CpSolverResponse::num_branches)
    .define_method("wall_time", &CpSolverResponse::wall_time)
    .define_method(
      "solution_integer_value",
      *[](CpSolverResponse& self, IntVar& x) {
        LinearExpr expr(x);
        return SolutionIntegerValue(self, expr);
      })
    .define_method("solution_boolean_value", &SolutionBooleanValue)
    .define_method(
      "status",
      *[](CpSolverResponse& self) {
        auto status = self.status();

        if (status == CpSolverStatus::OPTIMAL) {
          return Symbol("optimal");
        } else if (status == CpSolverStatus::FEASIBLE) {
          return Symbol("feasible");
        } else if (status == CpSolverStatus::INFEASIBLE) {
          return Symbol("infeasible");
        } else if (status == CpSolverStatus::MODEL_INVALID) {
          return Symbol("model_invalid");
        } else if (status == CpSolverStatus::UNKNOWN) {
          return Symbol("unknown");
        } else {
          throw std::runtime_error("Unknown solver status");
        }
      });
}
<commit_msg>Added more constraint builder methods<commit_after>#include <ortools/sat/cp_model.h>

#include <rice/Array.hpp>
#include <rice/Constructor.hpp>
#include <rice/Module.hpp>

using operations_research::sat::BoolVar;
using operations_research::sat::Constraint;
using operations_research::sat::CpModelBuilder;
using operations_research::sat::CpSolverResponse;
using operations_research::sat::CpSolverStatus;
using operations_research::sat::LinearExpr;
using operations_research::sat::IntVar;
using operations_research::sat::IntervalVar;
using operations_research::sat::Model;
using operations_research::sat::NewFeasibleSolutionObserver;
using operations_research::sat::SatParameters;
using operations_research::sat::SolutionBooleanValue;
using operations_research::sat::SolutionIntegerValue;

using Rice::Array;
using Rice::Object;
using Rice::String;
using Rice::Symbol;

template<>
inline
LinearExpr from_ruby<LinearExpr>(Object x)
{
  LinearExpr expr;

  if (x.respond_to("to_i")) {
    expr = from_ruby<int64>(x.call("to_i"));
  } else if (x.respond_to("vars")) {
    Array vars = x.call("vars");
    for(auto const& var: vars) {
      auto cvar = (Array) var;
      // TODO clean up
      Object o = cvar[0];
      std::string type = ((String) o.call("class").call("name")).str();
      if (type == "ORTools::BoolVar") {
        expr.AddTerm(from_ruby<BoolVar>(cvar[0]), from_ruby<int64>(cvar[1]));
      } else if (type == "Integer") {
        expr.AddConstant(from_ruby<int64>(cvar[0]) * from_ruby<int64>(cvar[1]));
      } else {
        expr.AddTerm(from_ruby<IntVar>(cvar[0]), from_ruby<int64>(cvar[1]));
      }
    }
  } else {
    std::string type = ((String) x.call("class").call("name")).str();
    if (type == "ORTools::BoolVar") {
      expr = from_ruby<BoolVar>(x);
    } else {
      expr = from_ruby<IntVar>(x);
    }
  }

  return expr;
}

// need a wrapper class since absl::Span doesn't own
class IntVarSpan {
  std::vector<IntVar> vec;
  public:
    IntVarSpan(Object x) {
      Array a = Array(x);
      vec.reserve(a.size());
      for (std::size_t i = 0; i < a.size(); ++i) {
        vec.push_back(from_ruby<IntVar>(a[i]));
      }
    }
    operator absl::Span<const IntVar>() {
      return absl::Span<const IntVar>(vec);
    }
};

template<>
inline
IntVarSpan from_ruby<IntVarSpan>(Object x)
{
  return IntVarSpan(x);
}

// need a wrapper class since absl::Span doesn't own
class IntervalVarSpan {
  std::vector<IntervalVar> vec;
  public:
    IntervalVarSpan(Object x) {
      Array a = Array(x);
      vec.reserve(a.size());
      for (std::size_t i = 0; i < a.size(); ++i) {
        vec.push_back(from_ruby<IntervalVar>(a[i]));
      }
    }
    operator absl::Span<const IntervalVar>() {
      return absl::Span<const IntervalVar>(vec);
    }
};

template<>
inline
IntervalVarSpan from_ruby<IntervalVarSpan>(Object x)
{
  return IntervalVarSpan(x);
}

// need a wrapper class since absl::Span doesn't own
class LinearExprSpan {
  std::vector<LinearExpr> vec;
  public:
    LinearExprSpan(Object x) {
      Array a = Array(x);
      vec.reserve(a.size());
      for (std::size_t i = 0; i < a.size(); ++i) {
        vec.push_back(from_ruby<LinearExpr>(a[i]));
      }
    }
    operator absl::Span<const LinearExpr>() {
      return absl::Span<const LinearExpr>(vec);
    }
};

template<>
inline
LinearExprSpan from_ruby<LinearExprSpan>(Object x)
{
  return LinearExprSpan(x);
}

// need a wrapper class since absl::Span doesn't own
class BoolVarSpan {
  std::vector<BoolVar> vec;
  public:
    BoolVarSpan(Object x) {
      Array a = Array(x);
      vec.reserve(a.size());
      for (std::size_t i = 0; i < a.size(); ++i) {
        vec.push_back(from_ruby<BoolVar>(a[i]));
      }
    }
    operator absl::Span<const BoolVar>() {
      return absl::Span<const BoolVar>(vec);
    }
};

template<>
inline
BoolVarSpan from_ruby<BoolVarSpan>(Object x)
{
  return BoolVarSpan(x);
}

void init_constraint(Rice::Module& m) {
  Rice::define_class_under<IntVar>(m, "SatIntVar")
    .define_method("name", &IntVar::Name);

  Rice::define_class_under<IntervalVar>(m, "SatIntervalVar")
    .define_method("name", &IntervalVar::Name);

  Rice::define_class_under<Constraint>(m, "SatConstraint");

  Rice::define_class_under<BoolVar>(m, "BoolVar")
    .define_method("name", &BoolVar::Name)
    .define_method("index", &BoolVar::index)
    .define_method("not", &BoolVar::Not)
    .define_method(
      "inspect",
      *[](BoolVar& self) {
        String name(self.Name());
        return "#<ORTools::BoolVar @name=" + name.inspect().str() + ">";
      });

  Rice::define_class_under<SatParameters>(m, "SatParameters")
    .define_constructor(Rice::Constructor<SatParameters>())
    .define_method("max_time_in_seconds=",
    *[](SatParameters& self, double value) {
      self.set_max_time_in_seconds(value);
    });

  Rice::define_class_under<CpModelBuilder>(m, "CpModel")
    .define_constructor(Rice::Constructor<CpModelBuilder>())
    .define_method(
      "new_int_var",
      *[](CpModelBuilder& self, int64 start, int64 end, std::string name) {
        const operations_research::Domain domain(start, end);
        return self.NewIntVar(domain).WithName(name);
      })
    .define_method(
      "new_bool_var",
      *[](CpModelBuilder& self, std::string name) {
        return self.NewBoolVar().WithName(name);
      })
    .define_method(
      "new_constant",
      *[](CpModelBuilder& self, int64 value) {
        return self.NewConstant(value);
      })
    .define_method(
      "true_var",
      *[](CpModelBuilder& self) {
        return self.TrueVar();
      })
    .define_method(
      "false_var",
      *[](CpModelBuilder& self) {
        return self.FalseVar();
      })
    .define_method(
      "new_interval_var",
      *[](CpModelBuilder& self, IntVar start, IntVar size, IntVar end, std::string name) {
        return self.NewIntervalVar(start, size, end).WithName(name);
      })
    .define_method(
      "new_optional_interval_var",
      *[](CpModelBuilder& self, IntVar start, IntVar size, IntVar end, BoolVar presence, std::string name) {
        return self.NewOptionalIntervalVar(start, size, end, presence).WithName(name);
      })
    .define_method(
      "add_bool_or",
      *[](CpModelBuilder& self, BoolVarSpan literals) {
        self.AddBoolOr(literals);
      })
    .define_method(
      "add_bool_and",
      *[](CpModelBuilder& self, BoolVarSpan literals) {
        self.AddBoolAnd(literals);
      })
    .define_method(
      "add_bool_xor",
      *[](CpModelBuilder& self, BoolVarSpan literals) {
        self.AddBoolXor(literals);
      })
    .define_method(
      "add_implication",
      *[](CpModelBuilder& self, BoolVar a, BoolVar b) {
        self.AddImplication(a, b);
      })
    .define_method(
      "add_equality",
      *[](CpModelBuilder& self, LinearExpr x, LinearExpr y) {
        self.AddEquality(x, y);
      })
    .define_method(
      "add_greater_or_equal",
      *[](CpModelBuilder& self, LinearExpr x, LinearExpr y) {
        self.AddGreaterOrEqual(x, y);
      })
    .define_method(
      "add_greater_than",
      *[](CpModelBuilder& self, LinearExpr x, LinearExpr y) {
        self.AddGreaterThan(x, y);
      })
    .define_method(
      "add_less_or_equal",
      *[](CpModelBuilder& self, LinearExpr x, LinearExpr y) {
        self.AddLessOrEqual(x, y);
      })
    .define_method(
      "add_less_than",
      *[](CpModelBuilder& self, LinearExpr x, LinearExpr y) {
        self.AddLessThan(x, y);
      })
    // TODO add domain
    // .define_method(
    //   "add_linear_constraint",
    //   *[](CpModelBuilder& self, LinearExpr expr, Domain domain) {
    //     self.AddLinearConstraint(expr, domain);
    //   })
    .define_method(
      "add_not_equal",
      *[](CpModelBuilder& self, LinearExpr x, LinearExpr y) {
        self.AddNotEqual(x, y);
      })
    .define_method(
      "add_all_different",
      *[](CpModelBuilder& self, IntVarSpan vars) {
        self.AddAllDifferent(vars);
      })
    .define_method(
      "add_inverse_constraint",
      *[](CpModelBuilder& self, IntVarSpan variables, IntVarSpan inverse_variables) {
        self.AddInverseConstraint(variables, inverse_variables);
      })
    .define_method(
      "add_min_equality",
      *[](CpModelBuilder& self, IntVar target, IntVarSpan vars) {
        self.AddMinEquality(target, vars);
      })
    .define_method(
      "add_lin_min_equality",
      *[](CpModelBuilder& self, LinearExpr target, LinearExprSpan exprs) {
        self.AddLinMinEquality(target, exprs);
      })
    .define_method(
      "add_max_equality",
      *[](CpModelBuilder& self, IntVar target, IntVarSpan vars) {
        self.AddMaxEquality(target, vars);
      })
    .define_method(
      "add_lin_max_equality",
      *[](CpModelBuilder& self, LinearExpr target, LinearExprSpan exprs) {
        self.AddLinMaxEquality(target, exprs);
      })
    .define_method(
      "add_division_equality",
      *[](CpModelBuilder& self, IntVar target, IntVar numerator, IntVar denominator) {
        self.AddDivisionEquality(target, numerator, denominator);
      })
    .define_method(
      "add_abs_equality",
      *[](CpModelBuilder& self, IntVar target, IntVar var) {
        self.AddAbsEquality(target, var);
      })
    .define_method(
      "add_modulo_equality",
      *[](CpModelBuilder& self, IntVar target, IntVar var, IntVar mod) {
        self.AddModuloEquality(target, var, mod);
      })
    .define_method(
      "add_product_equality",
      *[](CpModelBuilder& self, IntVar target, IntVarSpan vars) {
        self.AddProductEquality(target, vars);
      })
    .define_method(
      "add_no_overlap",
      *[](CpModelBuilder& self, IntervalVarSpan vars) {
        self.AddNoOverlap(vars);
      })
    .define_method(
      "maximize",
      *[](CpModelBuilder& self, LinearExpr expr) {
        self.Maximize(expr);
      })
    .define_method(
      "minimize",
      *[](CpModelBuilder& self, LinearExpr expr) {
        self.Minimize(expr);
      })
    .define_method(
      "scale_objective_by",
      *[](CpModelBuilder& self, double scaling) {
        self.ScaleObjectiveBy(scaling);
      });

  Rice::define_class_under(m, "CpSolver")
    .define_method(
      "_solve_with_observer",
      *[](Object self, CpModelBuilder& model, SatParameters& parameters, Object callback, bool all_solutions) {
        Model m;

        if (all_solutions) {
          // set parameters for SearchForAllSolutions
          parameters.set_enumerate_all_solutions(true);
        }
        m.Add(NewSatParameters(parameters));

        m.Add(NewFeasibleSolutionObserver(
          [callback](const CpSolverResponse& r) {
            // TODO find a better way to do this
            callback.call("response=", r);
            callback.call("on_solution_callback");
          })
        );
        return SolveCpModel(model.Build(), &m);
      })
    .define_method(
      "_solve",
      *[](Object self, CpModelBuilder& model, SatParameters& parameters) {
        Model m;
        m.Add(NewSatParameters(parameters));
        return SolveCpModel(model.Build(), &m);
      })
    .define_method(
      "_solution_integer_value",
      *[](Object self, CpSolverResponse& response, IntVar& x) {
        return SolutionIntegerValue(response, x);
      })
    .define_method(
      "_solution_boolean_value",
      *[](Object self, CpSolverResponse& response, BoolVar& x) {
        return SolutionBooleanValue(response, x);
      });

  Rice::define_class_under<CpSolverResponse>(m, "CpSolverResponse")
    .define_method("objective_value", &CpSolverResponse::objective_value)
    .define_method("num_conflicts", &CpSolverResponse::num_conflicts)
    .define_method("num_branches", &CpSolverResponse::num_branches)
    .define_method("wall_time", &CpSolverResponse::wall_time)
    .define_method(
      "solution_integer_value",
      *[](CpSolverResponse& self, IntVar& x) {
        LinearExpr expr(x);
        return SolutionIntegerValue(self, expr);
      })
    .define_method("solution_boolean_value", &SolutionBooleanValue)
    .define_method(
      "status",
      *[](CpSolverResponse& self) {
        auto status = self.status();

        if (status == CpSolverStatus::OPTIMAL) {
          return Symbol("optimal");
        } else if (status == CpSolverStatus::FEASIBLE) {
          return Symbol("feasible");
        } else if (status == CpSolverStatus::INFEASIBLE) {
          return Symbol("infeasible");
        } else if (status == CpSolverStatus::MODEL_INVALID) {
          return Symbol("model_invalid");
        } else if (status == CpSolverStatus::UNKNOWN) {
          return Symbol("unknown");
        } else {
          throw std::runtime_error("Unknown solver status");
        }
      });
}
<|endoftext|>


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

#include "assert.hpp"
#include "Platform.hpp"

//32 bits by default
eddic::Platform eddic::platform = Platform::INTEL_X86;

using namespace eddic;

struct X86Descriptor : public PlatformDescriptor {
    int sizes[BASETYPE_COUNT] = {  8, 4, 4, 4, 0 };

    unsigned int size_of(BaseType type){
        return sizes[static_cast<unsigned int>(type)];
    }

    unsigned int numberOfIntParamRegisters(){
        return 1;
    }

    unsigned int numberOfFloatParamRegisters(){
        return 1;
    }

    unsigned int number_of_registers(){
        return 6;
    }

    std::vector<unsigned short> symbolic_registers(){
        return {0, 1, 2, 3, 4, 5};
    }

    unsigned int number_of_float_registers(){
        return 8;
    }

    std::vector<unsigned short> symbolic_float_registers(){
        return {0, 1, 2, 3, 4, 5, 6, 7};
    }

    unsigned int number_of_variable_registers(){
        return 0;
    }

    unsigned int number_of_float_variable_registers(){
        return 1;
    }

    unsigned short int_variable_register(unsigned int /*position*/){
        ASSERT_PATH_NOT_TAKEN("No int variable register");

        return 0;
    }

    unsigned short float_variable_register(unsigned int position){
        assert(position == 1);

        return 6; //xmm6
    };

    unsigned short int_param_register(unsigned int position){
        assert(position == 1);

        return 2; //ecx
    }

    unsigned short float_param_register(unsigned int position){
        assert(position  == 1);

        return 7; //xmm7
    }

    unsigned short int_return_register1(){
        return 0;
    }

    unsigned short int_return_register2(){
        return 1;
    }

    unsigned short float_return_register(){
        return 0;
    }

    unsigned short a_register(){
        return 0;
    }

    unsigned short d_register(){
        return 3;
    }
};

struct X86_64Descriptor : public PlatformDescriptor {
    int sizes[BASETYPE_COUNT] = { 16, 8, 8, 8, 0 };

    unsigned int size_of(BaseType type){
        return sizes[static_cast<unsigned int>(type)];
    }

    unsigned int numberOfIntParamRegisters(){
        return 2;
    }

    unsigned int numberOfFloatParamRegisters(){
        return 1;
    }

    unsigned int number_of_registers(){
        return 14;
    }

    std::vector<unsigned short> symbolic_registers(){
        return {4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 3, 2, 1, 0};
    }

    unsigned int number_of_float_registers(){
        return 8;
    }

    std::vector<unsigned short> symbolic_float_registers(){
        return {0, 1, 2, 3, 4, 5, 6, 7};
    }

    unsigned int number_of_variable_registers(){
        return 2;
    }

    unsigned int number_of_float_variable_registers(){
        return 1;
    }

    unsigned short int_variable_register(unsigned int position){
        assert(position == 1 || position == 2);

        return position == 1 ? 10 : 11; //r12 and r13
    }

    unsigned short float_variable_register(unsigned int position){
        assert(position == 1);

        return 6; //xmm6
    };

    unsigned short int_param_register(unsigned int position){
        assert(position == 1 || position == 2);

        return position == 1 ? 12 : 13; //r14 and r15
    }

    unsigned short float_param_register(unsigned int position){
        assert(position  == 1);

        return 7;
    }

    unsigned short int_return_register1(){
        return 0;
    }

    unsigned short int_return_register2(){
        return 1;
    }

    unsigned short float_return_register(){
        return 0;
    }

    unsigned short a_register(){
        return 0;
    }

    unsigned short d_register(){
        return 3;
    }
};

PlatformDescriptor* eddic::getPlatformDescriptor(Platform platform){
    static X86Descriptor x86Descriptor;
    static X86_64Descriptor x86_64Descriptor;

    switch(platform){
        case Platform::INTEL_X86:
            return &x86Descriptor;
        case Platform::INTEL_X86_64:
            return &x86_64Descriptor;
    }

    ASSERT_PATH_NOT_TAKEN("Unhandled platform");
}
<commit_msg>Fix sizes of the base types<commit_after>//=======================================================================
// Copyright Baptiste Wicht 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include "assert.hpp"
#include "Platform.hpp"

//32 bits by default
eddic::Platform eddic::platform = Platform::INTEL_X86;

using namespace eddic;

struct X86Descriptor : public PlatformDescriptor {
    int sizes[BASETYPE_COUNT] = {  8, 4, 4, 4, 4, 0 };

    unsigned int size_of(BaseType type){
        return sizes[static_cast<unsigned int>(type)];
    }

    unsigned int numberOfIntParamRegisters(){
        return 1;
    }

    unsigned int numberOfFloatParamRegisters(){
        return 1;
    }

    unsigned int number_of_registers(){
        return 6;
    }

    std::vector<unsigned short> symbolic_registers(){
        return {0, 1, 2, 3, 4, 5};
    }

    unsigned int number_of_float_registers(){
        return 8;
    }

    std::vector<unsigned short> symbolic_float_registers(){
        return {0, 1, 2, 3, 4, 5, 6, 7};
    }

    unsigned int number_of_variable_registers(){
        return 0;
    }

    unsigned int number_of_float_variable_registers(){
        return 1;
    }

    unsigned short int_variable_register(unsigned int /*position*/){
        ASSERT_PATH_NOT_TAKEN("No int variable register");

        return 0;
    }

    unsigned short float_variable_register(unsigned int position){
        assert(position == 1);

        return 6; //xmm6
    };

    unsigned short int_param_register(unsigned int position){
        assert(position == 1);

        return 2; //ecx
    }

    unsigned short float_param_register(unsigned int position){
        assert(position  == 1);

        return 7; //xmm7
    }

    unsigned short int_return_register1(){
        return 0;
    }

    unsigned short int_return_register2(){
        return 1;
    }

    unsigned short float_return_register(){
        return 0;
    }

    unsigned short a_register(){
        return 0;
    }

    unsigned short d_register(){
        return 3;
    }
};

struct X86_64Descriptor : public PlatformDescriptor {
    int sizes[BASETYPE_COUNT] = { 16, 8, 8, 8, 8, 0 };

    unsigned int size_of(BaseType type){
        return sizes[static_cast<unsigned int>(type)];
    }

    unsigned int numberOfIntParamRegisters(){
        return 2;
    }

    unsigned int numberOfFloatParamRegisters(){
        return 1;
    }

    unsigned int number_of_registers(){
        return 14;
    }

    std::vector<unsigned short> symbolic_registers(){
        return {4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 3, 2, 1, 0};
    }

    unsigned int number_of_float_registers(){
        return 8;
    }

    std::vector<unsigned short> symbolic_float_registers(){
        return {0, 1, 2, 3, 4, 5, 6, 7};
    }

    unsigned int number_of_variable_registers(){
        return 2;
    }

    unsigned int number_of_float_variable_registers(){
        return 1;
    }

    unsigned short int_variable_register(unsigned int position){
        assert(position == 1 || position == 2);

        return position == 1 ? 10 : 11; //r12 and r13
    }

    unsigned short float_variable_register(unsigned int position){
        assert(position == 1);

        return 6; //xmm6
    };

    unsigned short int_param_register(unsigned int position){
        assert(position == 1 || position == 2);

        return position == 1 ? 12 : 13; //r14 and r15
    }

    unsigned short float_param_register(unsigned int position){
        assert(position  == 1);

        return 7;
    }

    unsigned short int_return_register1(){
        return 0;
    }

    unsigned short int_return_register2(){
        return 1;
    }

    unsigned short float_return_register(){
        return 0;
    }

    unsigned short a_register(){
        return 0;
    }

    unsigned short d_register(){
        return 3;
    }
};

PlatformDescriptor* eddic::getPlatformDescriptor(Platform platform){
    static X86Descriptor x86Descriptor;
    static X86_64Descriptor x86_64Descriptor;

    switch(platform){
        case Platform::INTEL_X86:
            return &x86Descriptor;
        case Platform::INTEL_X86_64:
            return &x86_64Descriptor;
    }

    ASSERT_PATH_NOT_TAKEN("Unhandled platform");
}
<|endoftext|>


<commit_before>/*
 * @file LoggingSystem.cpp
 * @author PJ O Halloran
 * @date 17/12/2016
 */

#include <string>

#include "LoggingSystem.h"

#define LOGURU_IMPLEMENTATION 1
#include <loguru.hpp>

#include <sol.hpp>

#include "app/EmberApp.h"
#include "app/ScriptingSystem.h"

namespace ember
{
	namespace app
	{
		using namespace ember::core;

		const char *LoggingSystem::Name = "Logging";

		bool LoggingSystem::VInitialize( int argc, char **argv )
		{
			if ( VInitialized() )
			{
				LOG_F( WARNING, "Tried to intialize %s when already running!", Name );
				return true;
			}

			loguru::init( argc, argv );

			sol::table logConfig = Application->Script()->GetConfig( Name );
			sol::table logFiles = logConfig["files"];

			logFiles.for_each( [&]( std::pair<sol::object, sol::object> pair )
			{
				sol::table logFileConfig = pair.second.as<sol::table>();

				if ( logFileConfig.valid() )
				{
					std::string name = logFileConfig["name"];
					int type = logFileConfig["type"];
					int level = logFileConfig["level"];
					loguru::add_file( name.c_str(), ( loguru::FileMode )type, ( loguru::Verbosity )level );
				}
			} );

			loguru::g_stderr_verbosity = logConfig["error_level"];

			LOG_F( INFO, "%s initialized", Name );
			_initialized = true;
			return true;
		}

		bool LoggingSystem::VShutdown()
		{
			if ( !VInitialized() )
			{
				// no logging system to log warning to in this case.
				return true;
			}

			LOG_F( INFO, "%s shutting down", Name );
			loguru::shutdown();

			_initialized = false;
			return true;
		}

		const char *LoggingSystem::VGetSystemName()
		{
			return Name;
		}
	}
}
<commit_msg>Fix include path.<commit_after>/*
 * @file LoggingSystem.cpp
 * @author PJ O Halloran
 * @date 17/12/2016
 */

#include <string>

#include "LoggingSystem.h"

#define LOGURU_IMPLEMENTATION 1
#include <loguru/loguru.hpp>

#include <sol.hpp>

#include "app/EmberApp.h"
#include "app/ScriptingSystem.h"

namespace ember
{
	namespace app
	{
		using namespace ember::core;

		const char *LoggingSystem::Name = "Logging";

		bool LoggingSystem::VInitialize( int argc, char **argv )
		{
			if ( VInitialized() )
			{
				LOG_F( WARNING, "Tried to intialize %s when already running!", Name );
				return true;
			}

			loguru::init( argc, argv );

			sol::table logConfig = Application->Script()->GetConfig( Name );
			sol::table logFiles = logConfig["files"];

			logFiles.for_each( [&]( std::pair<sol::object, sol::object> pair )
			{
				sol::table logFileConfig = pair.second.as<sol::table>();

				if ( logFileConfig.valid() )
				{
					std::string name = logFileConfig["name"];
					int type = logFileConfig["type"];
					int level = logFileConfig["level"];
					loguru::add_file( name.c_str(), ( loguru::FileMode )type, ( loguru::Verbosity )level );
				}
			} );

			loguru::g_stderr_verbosity = logConfig["error_level"];

			LOG_F( INFO, "%s initialized", Name );
			_initialized = true;
			return true;
		}

		bool LoggingSystem::VShutdown()
		{
			if ( !VInitialized() )
			{
				// no logging system to log warning to in this case.
				return true;
			}

			LOG_F( INFO, "%s shutting down", Name );
			loguru::shutdown();

			_initialized = false;
			return true;
		}

		const char *LoggingSystem::VGetSystemName()
		{
			return Name;
		}
	}
}
<|endoftext|>


<commit_before>#include "motion/move_to_posture.hpp"

MoveToPostureAction::MoveToPostureAction(ros::NodeHandle nh, std::string name) :
  nh_(nh),
  as_(nh_, name, false),
  action_name_(name) {
  //register the goal and feeback callbacks
  as_.registerGoalCallback(boost::bind(&MoveToPostureAction::goalCB, this));
  as_.registerPreemptCallback(boost::bind(&MoveToPostureAction::preemptCB, this));

  this->init();
  ROS_INFO("Starting MoveToPosture server");
  as_.start();
}

MoveToPostureAction::~MoveToPostureAction(void) {
}

void MoveToPostureAction::init() {
  distance_threshold_ = 0.03;
}

void MoveToPostureAction::goalCB() {
  target_posture_ = as_.acceptNewGoal()->posture;
  this->executeCB();
}

void MoveToPostureAction::preemptCB() {
  ROS_INFO("Preempt");
  as_.setPreempted();
}

void MoveToPostureAction::executeCB() {
  bool going = true;
  bool success = false;
  bool moveit_success = false;
  // states:
  // 0 initial
  // 1 planned
  // 2 executing
  // 3 moved
  int state = 0;

  ros::Rate r(10);
  ROS_INFO("Executing goal for %s", action_name_.c_str());
  feedback_.curr_state = 0;
  as_.publishFeedback(feedback_);
  // get move it to execute motion
  moveit::planning_interface::MoveGroup group("arm_1");

  timed_out_ = false;
  timer_ = nh_.createTimer(ros::Duration(20), &MoveToPostureAction::timerCB, this, true);

  while (going) {
    if (as_.isPreemptRequested() || !ros::ok()) {
      ROS_INFO("%s: Preempted", action_name_.c_str());
      as_.setPreempted();
      going = false;
    }

    if (state == 0) {
      group.setNamedTarget(target_posture_);
      group.setPlanningTime(20.0);
      if (!group.plan(plan_)) {
        ROS_FATAL("Unable to create motion plan.  Aborting.");
        success = false;
        going = false;
      } else {
        ROS_INFO("Planning was successful");
        // Publish Feedback that plan was success
        feedback_.curr_state = 1;
        as_.publishFeedback(feedback_);
        state = 1;
      }
    } else if (state == 1) {
      // do blocking move request
      // ATTENTION: in simulation moveit may abort but continue the motion
      moveit_success = group.execute(plan_);
      // publish feedback that it is executing motion
      feedback_.curr_state = 2;
      as_.publishFeedback(feedback_);
      state = 2;
    } else if (state == 2) {
      // TODO: fix next lines
      sleep(10.0);
      going = false;
      success = true;
    }

    if (moveit_success) {
      going = false;
      success = true;
    }

    if (timed_out_) {
      ROS_INFO("%s: Timed out", action_name_.c_str());
      // TODO: set as preempted?
      going = false;
    }

    ros::spinOnce();
    r.sleep();
  }

  feedback_.curr_state = 3;
  as_.publishFeedback(feedback_);

  if (success) {
    result_.success = true;
    ROS_INFO("%s: Succeeded!", action_name_.c_str());
    as_.setSucceeded(result_);
  } else {
    result_.success = false;
    ROS_INFO("%s: Failed!", action_name_.c_str());
    as_.setAborted(result_);
  }
}

void MoveToPostureAction::timerCB(const ros::TimerEvent& event) {
  timed_out_ = true;
}
<commit_msg>moved initialization of timer to after execution response<commit_after>#include "motion/move_to_posture.hpp"

MoveToPostureAction::MoveToPostureAction(ros::NodeHandle nh, std::string name) :
  nh_(nh),
  as_(nh_, name, false),
  action_name_(name) {
  //register the goal and feeback callbacks
  as_.registerGoalCallback(boost::bind(&MoveToPostureAction::goalCB, this));
  as_.registerPreemptCallback(boost::bind(&MoveToPostureAction::preemptCB, this));

  this->init();
  ROS_INFO("Starting MoveToPosture server");
  as_.start();
}

MoveToPostureAction::~MoveToPostureAction(void) {
}

void MoveToPostureAction::init() {
  distance_threshold_ = 0.03;
}

void MoveToPostureAction::goalCB() {
  target_posture_ = as_.acceptNewGoal()->posture;
  this->executeCB();
}

void MoveToPostureAction::preemptCB() {
  ROS_INFO("Preempt");
  as_.setPreempted();
}

void MoveToPostureAction::executeCB() {
  bool going = true;
  bool success = false;
  bool moveit_success = false;
  timed_out_ = false;
  // states:
  // 0 initial
  // 1 planned
  // 2 executing
  // 3 moved
  int state = 0;

  ros::Rate r(10);
  ROS_INFO("Executing goal for %s", action_name_.c_str());
  feedback_.curr_state = 0;
  as_.publishFeedback(feedback_);
  // get move it to execute motion
  moveit::planning_interface::MoveGroup group("arm_1");

  while (going) {
    if (as_.isPreemptRequested() || !ros::ok()) {
      ROS_INFO("%s: Preempted", action_name_.c_str());
      as_.setPreempted();
      going = false;
    }

    if (state == 0) {
      group.setNamedTarget(target_posture_);
      group.setPlanningTime(20.0);
      if (!group.plan(plan_)) {
        ROS_FATAL("Unable to create motion plan.  Aborting.");
        success = false;
        going = false;
      } else {
        ROS_INFO("Planning was successful");
        // Publish Feedback that plan was success
        feedback_.curr_state = 1;
        as_.publishFeedback(feedback_);
        state = 1;
      }
    } else if (state == 1) {
      // do blocking move request
      // ATTENTION: in simulation moveit may abort but continue the motion
      moveit_success = group.execute(plan_);
      // publish feedback that it is executing motion
      feedback_.curr_state = 2;
      as_.publishFeedback(feedback_);
      state = 2;
      timed_out_ = false;
      timer_ = nh_.createTimer(ros::Duration(30), &MoveToPostureAction::timerCB, this, true);
    } else if (state == 2) {
      // TODO: fix next lines
      success = true;
    }

    if (moveit_success) {
      going = false;
      success = true;
    }

    if (timed_out_) {
      ROS_INFO("%s: Timed out", action_name_.c_str());
      // TODO: set as preempted?
      going = false;
    }

    ros::spinOnce();
    r.sleep();
  }

  feedback_.curr_state = 3;
  as_.publishFeedback(feedback_);

  if (success) {
    result_.success = true;
    ROS_INFO("%s: Succeeded!", action_name_.c_str());
    as_.setSucceeded(result_);
  } else {
    result_.success = false;
    ROS_INFO("%s: Failed!", action_name_.c_str());
    as_.setAborted(result_);
  }
}

void MoveToPostureAction::timerCB(const ros::TimerEvent& event) {
  timed_out_ = true;
}
<|endoftext|>


<commit_before>#include <pybind11/pybind11.h>
#include <pybind11/stl.h>

#include "nifty/distributed/region_graph.hxx"
#include "nifty/python/converter.hxx"

namespace py = pybind11;

namespace nifty {
namespace distributed {

    void exportRegionGraph(py::module & module) {

        typedef nifty::array::StaticArray<int64_t, 3> CoordinateType;
        module.def("computeMergeableRegionGraph", [](
            const std::string & pathToLabels,
            const std::string & keyToLabels,
            const CoordinateType & roiBegin,
            const CoordinateType & roiEnd,
            const std::string & pathToGraph,
            const std::string & keyToGraph
        ) {

            py::gil_scoped_release allowThreads;
            computeMergeableRegionGraph(pathToLabels, keyToLabels,
                                        roiBegin, roiEnd,
                                        pathToGraph, keyToGraph);

        }, py::arg("pathToLabels"), py::arg("keyToLabels"),
           py::arg("roiBegin"), py::arg("roiEnd"),
           py::arg("pathToGraph"), py::arg("keyToGraph"));

        module.def("mergeSubgraphs", [](
            const std::string & pathToGraph,
            const std::string & blockGroup,
            const std::string & blockPrefix,
            const std::vector<size_t> & blockIds,
            const std::string & outKey,
            const int numberOfThreads
        ) {
            py::gil_scoped_release allowThreads;
            mergeSubgraphs(pathToGraph, blockGroup,
                           blockPrefix, blockIds,
                           outKey, numberOfThreads);
        }, py::arg("pathToGraph"), py::arg("blockGroup"),
           py::arg("blockPrefix"), py::arg("blockIds"),
           py::arg("outKey"), py::arg("numberOfThreads")=1);

        module.def("mapEdgeIds", [](
            const std::string & pathToGraph,
            const std::string & graphGroup,
            const std::string & blockGroup,
            const std::string & blockPrefix,
            const std::vector<size_t> & blockIds,
            const int numberOfThreads
        ) {
            py::gil_scoped_release allowThreads;
            mapEdgeIds(pathToGraph, graphGroup, blockGroup, blockPrefix, blockIds, numberOfThreads);
        }, py::arg("pathToGraph"), py::arg("graphGroup"), py::arg("blockGroup"),
           py::arg("blockPrefix"), py::arg("blockIds"), py::arg("numberOfThreads")=1);

        module.def("mapEdgeIdsForAllBlocks", [](
            const std::string & pathToGraph,
            const std::string & graphGroup,
            const std::string & blockGroup,
            const std::string & blockPrefix,
            const size_t numberOfBlocks,
            const int numberOfThreads
        ) {
            py::gil_scoped_release allowThreads;
            mapEdgeIds(pathToGraph, graphGroup, blockGroup, blockPrefix, numberOfBlocks, numberOfThreads);
        }, py::arg("pathToGraph"), py::arg("graphGroup"), py::arg("blockGroup"),
           py::arg("blockPrefix"), py::arg("blockIds"), py::arg("numberOfThreads")=1);

    }

}
}
<commit_msg>Fix kwargs for edge mapping<commit_after>#include <pybind11/pybind11.h>
#include <pybind11/stl.h>

#include "nifty/distributed/region_graph.hxx"
#include "nifty/python/converter.hxx"

namespace py = pybind11;

namespace nifty {
namespace distributed {

    void exportRegionGraph(py::module & module) {

        typedef nifty::array::StaticArray<int64_t, 3> CoordinateType;
        module.def("computeMergeableRegionGraph", [](
            const std::string & pathToLabels,
            const std::string & keyToLabels,
            const CoordinateType & roiBegin,
            const CoordinateType & roiEnd,
            const std::string & pathToGraph,
            const std::string & keyToGraph
        ) {

            py::gil_scoped_release allowThreads;
            computeMergeableRegionGraph(pathToLabels, keyToLabels,
                                        roiBegin, roiEnd,
                                        pathToGraph, keyToGraph);

        }, py::arg("pathToLabels"), py::arg("keyToLabels"),
           py::arg("roiBegin"), py::arg("roiEnd"),
           py::arg("pathToGraph"), py::arg("keyToGraph"));

        module.def("mergeSubgraphs", [](
            const std::string & pathToGraph,
            const std::string & blockGroup,
            const std::string & blockPrefix,
            const std::vector<size_t> & blockIds,
            const std::string & outKey,
            const int numberOfThreads
        ) {
            py::gil_scoped_release allowThreads;
            mergeSubgraphs(pathToGraph, blockGroup,
                           blockPrefix, blockIds,
                           outKey, numberOfThreads);
        }, py::arg("pathToGraph"), py::arg("blockGroup"),
           py::arg("blockPrefix"), py::arg("blockIds"),
           py::arg("outKey"), py::arg("numberOfThreads")=1);

        module.def("mapEdgeIds", [](
            const std::string & pathToGraph,
            const std::string & graphGroup,
            const std::string & blockGroup,
            const std::string & blockPrefix,
            const std::vector<size_t> & blockIds,
            const int numberOfThreads
        ) {
            py::gil_scoped_release allowThreads;
            mapEdgeIds(pathToGraph, graphGroup, blockGroup, blockPrefix, blockIds, numberOfThreads);
        }, py::arg("pathToGraph"), py::arg("graphGroup"), py::arg("blockGroup"),
           py::arg("blockPrefix"), py::arg("blockIds"), py::arg("numberOfThreads")=1);

        module.def("mapEdgeIdsForAllBlocks", [](
            const std::string & pathToGraph,
            const std::string & graphGroup,
            const std::string & blockGroup,
            const std::string & blockPrefix,
            const size_t numberOfBlocks,
            const int numberOfThreads
        ) {
            py::gil_scoped_release allowThreads;
            mapEdgeIds(pathToGraph, graphGroup, blockGroup, blockPrefix, numberOfBlocks, numberOfThreads);
        }, py::arg("pathToGraph"), py::arg("graphGroup"), py::arg("blockGroup"),
           py::arg("blockPrefix"), py::arg("numberOfBlocks"), py::arg("numberOfThreads")=1);

    }

}
}
<|endoftext|>