text:
//
// Copyright Jesse Manning 2007
//
// 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_NUMERIC_BINDINGS_LAPACK_GELS_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_GELS_HPP

#include <algorithm>

#include <boost/numeric/bindings/traits/type.hpp>
#include <boost/numeric/bindings/traits/traits.hpp>
#include <boost/numeric/bindings/traits/type_traits.hpp>
#include <boost/numeric/bindings/lapack/lapack.h>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/traits/detail/array.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>

#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
#  include <boost/static_assert.hpp>
#  include <boost/type_traits.hpp>
#endif

namespace boost { namespace numeric { namespace bindings {

    namespace lapack {

        ////////////////////////////////////////////////////////////////////////
        //
        // Linear Least Squares of an underdetermined or overdetermined matrix
        //
        ///////////////////////////////////////////////////////////////////////

        /*  gels - uses the LQ or QR factorization to solve an overdetermined
         *         or underdetermined linear system.  A full rank matrix is
         *         assumed.
         *
         *  The linear least squares system is defined by A*x=b.  A is the m-by-n
         *  coefficients matrix and b is the m-by-nrhs matrix.  Several
         *  right hand side vectors b and solution vectors x can be handled in
         *  a single call; they are stored as the columns of the m-by-nrhs right
         *  hand side matrix B and the n-by-nrh solution matrix x.
         *
         *  If trans = 'N' and m >= n:  find least squares solution of overdetermined system
         *      minimizes || b - A x ||2
         *
         *  if trans = 'N' and m < n: find minimum norm solution of underdetermined system
         *      A*X = B
         *
         *  if trans = 'T' or 'C' and m >= n: find minimum norm soltion of underdetermined system
         *      A^H*X = B
         *
         *  if trans = 'T' or 'C' and m < n: find least squares solution of overdetermined system
         *      minimize || b - A^H x ||2
         *
         *  Workspace is organized following the arguments in the calling sequence.
         *  optimal_workspace() : for optimizing use of blas 3 kernels
         *  minimal_workspace() : minimum size of work arrays, but does not allow for optimization
         *                        of blas 3 kernels
         *  workspace( work )   : where work size must be at least min(m, n) + max(1, m, n, nrhs)
         *
         *
         *  Each solution vector x (length n) is returned column-wise in the rhs matrix B.
         */

        namespace detail {

            inline void gels(char const trans, const integer_t m, const integer_t n,
                             const integer_t nrhs, float *a, const integer_t lda,
                             float *b, const integer_t ldb, float *work,
                             const integer_t lwork, integer_t *info)
            {
                LAPACK_SGELS(&trans, &m, &n, &nrhs, a, &lda, b, &ldb, work, &lwork, info);
            }

            inline void gels(char const trans, const integer_t m, const integer_t n,
                             const integer_t nrhs, double *a, const integer_t lda,
                             double *b, const integer_t ldb, double *work,
                             const integer_t lwork, integer_t *info)
            {
                LAPACK_DGELS(&trans, &m, &n, &nrhs, a, &lda, b, &ldb, work, &lwork, info);
            }

            inline void gels(char const trans, const integer_t m, const integer_t n,
                             const integer_t nrhs, traits::complex_f *a, const integer_t lda,
                             traits::complex_f *b, const integer_t ldb, traits::complex_f *work,
                             const integer_t lwork, integer_t *info)
            {
                LAPACK_CGELS(&trans, &m, &n, &nrhs,
                             traits::complex_ptr(a), &lda,
                             traits::complex_ptr(b), &ldb,
                             traits::complex_ptr(work), &lwork, info);
            }

            inline void gels(char const trans, const integer_t m, const integer_t n,
                             const integer_t nrhs, traits::complex_d *a, const integer_t lda,
                             traits::complex_d *b, const integer_t ldb, traits::complex_d *work,
                             const integer_t lwork, integer_t *info)
            {
                LAPACK_ZGELS(&trans, &m, &n, &nrhs,
                             traits::complex_ptr(a), &lda,
                             traits::complex_ptr(b), &ldb,
                             traits::complex_ptr(work), &lwork, info);
            }

            // generic function that calls more detailed lapack function
            template <typename MatrA, typename VecB, typename Work>
            int gels(const char trans, MatrA& A, VecB& b, Work& work)
            {
#ifndef NDEBUG
                const std::ptrdiff_t m = traits::matrix_size1(A);
                const std::ptrdiff_t n = traits::matrix_size2(A);
                const std::ptrdiff_t mrhs = traits::matrix_size1(b);
                const std::ptrdiff_t nrhs = traits::matrix_size2(b);
#endif

                // sanity checks
                assert(trans == 'N' || trans == 'T' || trans == 'C');
                assert(m >= 0 && n >= 0);
                assert(mrhs >= 0 && nrhs >= 0);
                assert(traits::leading_dimension(A) >= 1 && traits::leading_dimension(b) >= 1);
                assert(mrhs == std::max(m, n));

                integer_t info;
                detail::gels(trans,
                             traits::matrix_size1(A),
                             traits::matrix_size2(A),
                             traits::matrix_size2(b),
                             traits::matrix_storage(A),
                             traits::leading_dimension(A),
                             traits::matrix_storage(b),
                             traits::leading_dimension(b),
                             traits::vector_storage(work),
                             traits::vector_size(work),
                             &info);

                return info;
            }

            // query for recommended workspace
            template <typename MatrA, typename VecB>
            integer_t gels_optimal_work(const char trans, MatrA& A, VecB& b)
            {
                typename MatrA::value_type work;
                integer_t info;
                detail::gels(trans,
                    traits::matrix_size1(A),
                    traits::matrix_size2(A),
                    traits::matrix_size2(b),
                    traits::matrix_storage(A),
                    traits::leading_dimension(A),
                    traits::matrix_storage(b),
                    traits::leading_dimension(b),
                    &work, //traits::vector_storage(work),
                    -1, // traits::vector_size(work),
                    &info);

                assert(info == 0);

                integer_t lwork = traits::detail::to_int(work);

                return lwork;
            }
        } // namespace detail

        template <typename MatrA, typename VecB>
        int gels(const char trans, MatrA& A, VecB& b, optimal_workspace)
        {
            // query optimal workspace size
            integer_t work_size = detail::gels_optimal_work(trans, A, b);
            traits::detail::array<typename MatrA::value_type> work(work_size);

            return detail::gels(trans, A, b, work);
        }

        template <typename MatrA, typename VecB>
        int gels(const char trans, MatrA& A, VecB& b, minimal_workspace)
        {
            const std::ptrdiff_t m = traits::matrix_size1(A);
            const std::ptrdiff_t n = traits::matrix_size2(A);
            const std::ptrdiff_t r = traits::matrix_size2(b);

            const std::ptrdiff_t minmn = std::min(m, n);       //m < n ? m : n;
            const std::ptrdiff_t maxmn = std::max(m, n);       // m > n ? m : n;
            const std::ptrdiff_t maxdim = std::max(maxmn, r);  // maxmn > r ? maxmn : r;

            traits::detail::array<typename MatrA::value_type> work(minmn + std::max<std::ptrdiff_t>(1, maxdim));

            return detail::gels(trans, A, b, work);
        }

        template <typename MatrA, typename VecB, typename Work>
        int gels(const char trans, MatrA& A, VecB& b, detail::workspace1<Work> workspace)
        {
            return detail::gels(trans, A, b, workspace.select(typename traits::vector_traits<VecB>::value_type()));
        }

    } // namespace lapack

}}}

#endif

max_stars_repo_name: diku-dk/PROX

max_issues_repo_name: diku-dk/PROX

max_forks_repo_name: diku-dk/PROX


text:
#include <string>
#include <Eigen/Sparse>

#include "SparseMatrix.hpp"

swSim::SparseMatrix::SparseMatrix(){};
swSim::SparseMatrix::SparseMatrix(std::string nm, int rw, int col){
    name = nm;
    mat.resize(rw,col);
};
swSim::SparseMatrix::~SparseMatrix(){};

void swSim::SparseMatrix::setName(std::string nm){name=nm;return;};
void swSim::SparseMatrix::setSize(int rw, int col){mat.resize(rw,col);return;};

std::string swSim::SparseMatrix::getName() const {return name;};
size_t swSim::SparseMatrix::getNonZeroLength() const {return mat.nonZeros();};
double* swSim::SparseMatrix::getValueArray() {return mat.valuePtr();};
int* swSim::SparseMatrix::getColumnIndexArray() {return mat.innerIndexPtr();};
int* swSim::SparseMatrix::getRowpointerArray() {return mat.outerIndexPtr();};
size_t swSim::SparseMatrix::getRowpointerLength() const {return mat.outerSize()+1;};
int swSim::SparseMatrix::getRowCount() const {return mat.rows();};
int swSim::SparseMatrix::getColumnCount() const {return mat.cols();};

void swSim::SparseMatrix::SetValue(int i, int j, double val)
{
    mat.coeffRef(i, j) = val;
    return;
}

double swSim::SparseMatrix::GetValue(int i, int j){ return mat.coeffRef(i, j);};

void swSim::SparseMatrix::AddValue(int i, int j, double val)
{
    mat.coeffRef(i, j) += val;
    return;
}
void swSim::SparseMatrix::Prune()
{
    mat.prune(0.0);
    return;
}

ext: cpp

max_stars_repo_name: nasa/swSim


text:
#include <boost/serialization/export.hpp>
#include "Convolution1D.hpp"
#include "LayerModel.hpp"

using namespace std;
using namespace snn;
using namespace internal;

BOOST_CLASS_EXPORT(Convolution1D)

Convolution1D::Convolution1D(LayerModel& model, shared_ptr<NeuralNetworkOptimizer> optimizer)
    : FilterLayer(model, optimizer)
{
    this->shapeOfOutput = {
        this->shapeOfInput[0] - (this->sizeOfFilterMatrix - 1),
        this->numberOfFilters
    };
}

inline
unique_ptr<BaseLayer> Convolution1D::clone(std::shared_ptr<NeuralNetworkOptimizer> optimizer) const
{
    auto layer = make_unique<Convolution1D>(*this);
    for (int n = 0; n < layer->getNumberOfNeurons(); ++n)
    {
        layer->neurons[n].setOptimizer(optimizer);
    }
    return layer;
}

int Convolution1D::isValid() const
{
    for (auto& neuron : neurons)
    {
        if (neuron.getNumberOfInputs() != this->sizeOfFilterMatrix * this->shapeOfInput[1])
            return 203;
    }
    return this->FilterLayer::isValid();
}

inline
vector<float> Convolution1D::createInputsForNeuron(const int neuronIndex, const vector<float>& inputs)
{
    const int beginIndex = neuronIndex * this->shapeOfInput[1];
    const int endIndex = (neuronIndex + this->sizeOfFilterMatrix) * this->shapeOfInput[1];
    return vector<float>(inputs.begin() + beginIndex, inputs.begin() + endIndex);
}

inline
void Convolution1D::insertBackOutputForNeuron(const int neuronIndex, const std::vector<float>& error,
                                              std::vector<float>& errors)
{
    const int beginIndex = neuronIndex * this->shapeOfInput[1];
    for (int e = 0; e < (int)error.size(); ++e)
    {
        const int i = beginIndex + e;
        errors[i] += error[e];
    }
}

bool Convolution1D::operator==(const BaseLayer& layer) const
{
    return this->FilterLayer::operator==(layer);
}

bool Convolution1D::operator!=(const BaseLayer& layer) const
{
    return !(*this == layer);
}


text:
/* ----------------------------------------------------------------------------

 * GTSAM Copyright 2010, Georgia Tech Research Corporation,
 * Atlanta, Georgia 30332-0415
 * All Rights Reserved
 * Authors: Frank Dellaert, et al. (see THANKS for the full author list)

 * See LICENSE for the license information

 * -------------------------------------------------------------------------- */

/**
 *  @file  lago.h
 *  @author Luca Carlone
 *  @author Frank Dellaert
 *  @date   May 14, 2014
 */

#include <gtsam/slam/lago.h>

#include <gtsam/slam/InitializePose.h>
#include <gtsam/nonlinear/PriorFactor.h>
#include <gtsam/slam/BetweenFactor.h>
#include <gtsam/inference/Symbol.h>
#include <gtsam/geometry/Pose2.h>
#include <gtsam/base/timing.h>

#include <boost/math/special_functions.hpp>

using namespace std;

namespace gtsam {
namespace lago {

static const Matrix I = I_1x1;
static const Matrix I3 = I_3x3;

static const noiseModel::Diagonal::shared_ptr priorOrientationNoise =
    noiseModel::Diagonal::Sigmas((Vector(1) << 0).finished());
static const noiseModel::Diagonal::shared_ptr priorPose2Noise =
    noiseModel::Diagonal::Variances(Vector3(1e-6, 1e-6, 1e-8));

/* ************************************************************************* */
/**
 * Compute the cumulative orientation (without wrapping) wrt the root of a
 * spanning tree (tree) for a node (nodeKey). The function starts at the nodes and
 * moves towards the root summing up the (directed) rotation measurements.
 * Relative measurements are encoded in "deltaThetaMap".
 * The root is assumed to have orientation zero.
 */
static double computeThetaToRoot(const Key nodeKey,
    const PredecessorMap<Key>& tree, const key2doubleMap& deltaThetaMap,
    const key2doubleMap& thetaFromRootMap) {

  double nodeTheta = 0;
  Key key_child = nodeKey; // the node
  Key key_parent = 0; // the initialization does not matter
  while (1) {
    // We check if we reached the root
    if (tree.at(key_child) == key_child) // if we reached the root
      break;
    // we sum the delta theta corresponding to the edge parent->child
    nodeTheta += deltaThetaMap.at(key_child);
    // we get the parent
    key_parent = tree.at(key_child); // the parent
    // we check if we connected to some part of the tree we know
    if (thetaFromRootMap.find(key_parent) != thetaFromRootMap.end()) {
      nodeTheta += thetaFromRootMap.at(key_parent);
      break;
    }
    key_child = key_parent; // we move upwards in the tree
  }
  return nodeTheta;
}

/* ************************************************************************* */
key2doubleMap computeThetasToRoot(const key2doubleMap& deltaThetaMap,
    const PredecessorMap<Key>& tree) {

  key2doubleMap thetaToRootMap;

  // Orientation of the roo
  thetaToRootMap.insert(pair<Key, double>(initialize::kAnchorKey, 0.0));

  // for all nodes in the tree
  for(const key2doubleMap::value_type& it: deltaThetaMap) {
    // compute the orientation wrt root
    Key nodeKey = it.first;
    double nodeTheta = computeThetaToRoot(nodeKey, tree, deltaThetaMap,
        thetaToRootMap);
    thetaToRootMap.insert(pair<Key, double>(nodeKey, nodeTheta));
  }
  return thetaToRootMap;
}

/* ************************************************************************* */
void getSymbolicGraph(
/*OUTPUTS*/vector<size_t>& spanningTreeIds, vector<size_t>& chordsIds,
    key2doubleMap& deltaThetaMap,
    /*INPUTS*/const PredecessorMap<Key>& tree, const NonlinearFactorGraph& g) {

  // Get keys for which you want the orientation
  size_t id = 0;
  // Loop over the factors
  for(const boost::shared_ptr<NonlinearFactor>& factor: g) {
    if (factor->keys().size() == 2) {
      Key key1 = factor->keys()[0];
      Key key2 = factor->keys()[1];
      // recast to a between
      boost::shared_ptr<BetweenFactor<Pose2> > pose2Between =
          boost::dynamic_pointer_cast<BetweenFactor<Pose2> >(factor);
      if (!pose2Between)
        continue;
      // get the orientation - measured().theta();
      double deltaTheta = pose2Between->measured().theta();
      // insert (directed) orientations in the map "deltaThetaMap"
      bool inTree = false;
      if (tree.at(key1) == key2) { // key2 -> key1
        deltaThetaMap.insert(pair<Key, double>(key1, -deltaTheta));
        inTree = true;
      } else if (tree.at(key2) == key1) { // key1 -> key2
        deltaThetaMap.insert(pair<Key, double>(key2, deltaTheta));
        inTree = true;
      }
      // store factor slot, distinguishing spanning tree edges from chordsIds
      if (inTree == true)
        spanningTreeIds.push_back(id);
      else
        // it's a chord!
        chordsIds.push_back(id);
    }
    id++;
  }
}

/* ************************************************************************* */
// Retrieve the deltaTheta and the corresponding noise model from a BetweenFactor<Pose2>
static void getDeltaThetaAndNoise(NonlinearFactor::shared_ptr factor,
    Vector& deltaTheta, noiseModel::Diagonal::shared_ptr& model_deltaTheta) {

  // Get the relative rotation measurement from the between factor
  boost::shared_ptr<BetweenFactor<Pose2> > pose2Between =
      boost::dynamic_pointer_cast<BetweenFactor<Pose2> >(factor);
  if (!pose2Between)
    throw invalid_argument(
        "buildLinearOrientationGraph: invalid between factor!");
  deltaTheta = (Vector(1) << pose2Between->measured().theta()).finished();

  // Retrieve the noise model for the relative rotation
  SharedNoiseModel model = pose2Between->noiseModel();
  boost::shared_ptr<noiseModel::Diagonal> diagonalModel =
      boost::dynamic_pointer_cast<noiseModel::Diagonal>(model);
  if (!diagonalModel)
    throw invalid_argument("buildLinearOrientationGraph: invalid noise model "
        "(current version assumes diagonal noise model)!");
  Vector std_deltaTheta = (Vector(1) << diagonalModel->sigma(2)).finished(); // std on the angular measurement
  model_deltaTheta = noiseModel::Diagonal::Sigmas(std_deltaTheta);
}

/* ************************************************************************* */
GaussianFactorGraph buildLinearOrientationGraph(
    const vector<size_t>& spanningTreeIds, const vector<size_t>& chordsIds,
    const NonlinearFactorGraph& g, const key2doubleMap& orientationsToRoot,
    const PredecessorMap<Key>& tree) {

  GaussianFactorGraph lagoGraph;
  Vector deltaTheta;
  noiseModel::Diagonal::shared_ptr model_deltaTheta;

  // put original measurements in the spanning tree
  for(const size_t& factorId: spanningTreeIds) {
    const KeyVector& keys = g[factorId]->keys();
    Key key1 = keys[0], key2 = keys[1];
    getDeltaThetaAndNoise(g[factorId], deltaTheta, model_deltaTheta);
    lagoGraph.add(key1, -I, key2, I, deltaTheta, model_deltaTheta);
  }
  // put regularized measurements in the chordsIds
  for(const size_t& factorId: chordsIds) {
    const KeyVector& keys = g[factorId]->keys();
    Key key1 = keys[0], key2 = keys[1];
    getDeltaThetaAndNoise(g[factorId], deltaTheta, model_deltaTheta);
    double key1_DeltaTheta_key2 = deltaTheta(0);
    ///cout << "REG: key1= " << DefaultKeyFormatter(key1) << " key2= " << DefaultKeyFormatter(key2) << endl;
    double k2pi_noise = key1_DeltaTheta_key2 + orientationsToRoot.at(key1)
        - orientationsToRoot.at(key2); // this coincides to summing up measurements along the cycle induced by the chord
    double k = boost::math::round(k2pi_noise / (2 * M_PI));
    //if (k2pi_noise - 2*k*M_PI > 1e-5) cout << k2pi_noise - 2*k*M_PI << endl; // for debug
    Vector deltaThetaRegularized = (Vector(1)
        << key1_DeltaTheta_key2 - 2 * k * M_PI).finished();
    lagoGraph.add(key1, -I, key2, I, deltaThetaRegularized, model_deltaTheta);
  }
  // prior on the anchor orientation
  lagoGraph.add(initialize::kAnchorKey, I, (Vector(1) << 0.0).finished(), priorOrientationNoise);
  return lagoGraph;
}

/* ************************************************************************* */
static PredecessorMap<Key> findOdometricPath(
    const NonlinearFactorGraph& pose2Graph) {

  PredecessorMap<Key> tree;
  Key minKey = initialize::kAnchorKey; // this initialization does not matter
  bool minUnassigned = true;

  for(const boost::shared_ptr<NonlinearFactor>& factor: pose2Graph) {

    Key key1 = std::min(factor->keys()[0], factor->keys()[1]);
    Key key2 = std::max(factor->keys()[0], factor->keys()[1]);
    if (minUnassigned) {
      minKey = key1;
      minUnassigned = false;
    }
    if (key2 - key1 == 1) { // consecutive keys
      tree.insert(key2, key1);
      if (key1 < minKey)
        minKey = key1;
    }
  }
  tree.insert(minKey, initialize::kAnchorKey);
  tree.insert(initialize::kAnchorKey, initialize::kAnchorKey); // root
  return tree;
}

/* ************************************************************************* */
// Return the orientations of a graph including only BetweenFactors<Pose2>
static VectorValues computeOrientations(const NonlinearFactorGraph& pose2Graph,
    bool useOdometricPath) {
  gttic(lago_computeOrientations);

  // Find a minimum spanning tree
  PredecessorMap<Key> tree;
  if (useOdometricPath)
    tree = findOdometricPath(pose2Graph);
  else
    tree = findMinimumSpanningTree<NonlinearFactorGraph, Key,
        BetweenFactor<Pose2> >(pose2Graph);

  // Create a linear factor graph (LFG) of scalars
  key2doubleMap deltaThetaMap;
  vector<size_t> spanningTreeIds; // ids of between factors forming the spanning tree T
  vector<size_t> chordsIds; // ids of between factors corresponding to chordsIds wrt T
  getSymbolicGraph(spanningTreeIds, chordsIds, deltaThetaMap, tree, pose2Graph);

  // temporary structure to correct wraparounds along loops
  key2doubleMap orientationsToRoot = computeThetasToRoot(deltaThetaMap, tree);

  // regularize measurements and plug everything in a factor graph
  GaussianFactorGraph lagoGraph = buildLinearOrientationGraph(spanningTreeIds,
      chordsIds, pose2Graph, orientationsToRoot, tree);

  // Solve the LFG
  VectorValues orientationsLago = lagoGraph.optimize();

  return orientationsLago;
}

/* ************************************************************************* */
VectorValues initializeOrientations(const NonlinearFactorGraph& graph,
    bool useOdometricPath) {

  // We "extract" the Pose2 subgraph of the original graph: this
  // is done to properly model priors and avoiding operating on a larger graph
  NonlinearFactorGraph pose2Graph = initialize::buildPoseGraph<Pose2>(graph);

  // Get orientations from relative orientation measurements
  return computeOrientations(pose2Graph, useOdometricPath);
}

/* ************************************************************************* */
Values computePoses(const NonlinearFactorGraph& pose2graph,
    VectorValues& orientationsLago) {
  gttic(lago_computePoses);

  // Linearized graph on full poses
  GaussianFactorGraph linearPose2graph;

  // We include the linear version of each between factor
  for(const boost::shared_ptr<NonlinearFactor>& factor: pose2graph) {

    boost::shared_ptr<BetweenFactor<Pose2> > pose2Between =
        boost::dynamic_pointer_cast<BetweenFactor<Pose2> >(factor);

    if (pose2Between) {
      Key key1 = pose2Between->keys()[0];
      double theta1 = orientationsLago.at(key1)(0);
      double s1 = sin(theta1);
      double c1 = cos(theta1);

      Key key2 = pose2Between->keys()[1];
      double theta2 = orientationsLago.at(key2)(0);

      double linearDeltaRot = theta2 - theta1
          - pose2Between->measured().theta();
      linearDeltaRot = Rot2(linearDeltaRot).theta(); // to normalize

      double dx = pose2Between->measured().x();
      double dy = pose2Between->measured().y();

      Vector globalDeltaCart = //
          (Vector(2) << c1 * dx - s1 * dy, s1 * dx + c1 * dy).finished();
      Vector b = (Vector(3) << globalDeltaCart, linearDeltaRot).finished(); // rhs
      Matrix J1 = -I3;
      J1(0, 2) = s1 * dx + c1 * dy;
      J1(1, 2) = -c1 * dx + s1 * dy;
      // Retrieve the noise model for the relative rotation
      boost::shared_ptr<noiseModel::Diagonal> diagonalModel =
          boost::dynamic_pointer_cast<noiseModel::Diagonal>(
              pose2Between->noiseModel());

      linearPose2graph.add(key1, J1, key2, I3, b, diagonalModel);
    } else {
      throw invalid_argument(
          "computeLagoPoses: cannot manage non between factor here!");
    }
  }
  // add prior
  linearPose2graph.add(initialize::kAnchorKey, I3, Vector3(0.0, 0.0, 0.0),
      priorPose2Noise);

  // optimize
  VectorValues posesLago = linearPose2graph.optimize();

  // put into Values structure
  Values initialGuessLago;
  for(const VectorValues::value_type& it: posesLago) {
    Key key = it.first;
    if (key != initialize::kAnchorKey) {
      const Vector& poseVector = it.second;
      Pose2 poseLago = Pose2(poseVector(0), poseVector(1),
          orientationsLago.at(key)(0) + poseVector(2));
      initialGuessLago.insert(key, poseLago);
    }
  }
  return initialGuessLago;
}

/* ************************************************************************* */
Values initialize(const NonlinearFactorGraph& graph, bool useOdometricPath) {
  gttic(lago_initialize);

  // We "extract" the Pose2 subgraph of the original graph: this
  // is done to properly model priors and avoiding operating on a larger graph
  NonlinearFactorGraph pose2Graph = initialize::buildPoseGraph<Pose2>(graph);

  // Get orientations from relative orientation measurements
  VectorValues orientationsLago = computeOrientations(pose2Graph,
      useOdometricPath);

  // Compute the full poses
  return computePoses(pose2Graph, orientationsLago);
}

/* ************************************************************************* */
Values initialize(const NonlinearFactorGraph& graph,
    const Values& initialGuess) {
  Values initialGuessLago;

  // get the orientation estimates from LAGO
  VectorValues orientations = initializeOrientations(graph);

  // for all nodes in the tree
  for(const VectorValues::value_type& it: orientations) {
    Key key = it.first;
    if (key != initialize::kAnchorKey) {
      const Pose2& pose = initialGuess.at<Pose2>(key);
      const Vector& orientation = it.second;
      Pose2 poseLago = Pose2(pose.x(), pose.y(), orientation(0));
      initialGuessLago.insert(key, poseLago);
    }
  }
  return initialGuessLago;
}

} // end of namespace lago
} // end of namespace gtsam


text:
// This file is part of snark, a generic and flexible library for robotics research
// Copyright (c) 2011 The University of Sydney
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// 1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
// 3. Neither the name of the University of Sydney nor the
//    names of its contributors may be used to endorse or promote products
//    derived from this software without specific prior written permission.
//
// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
// GRANTED BY THIS LICENSE.  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
// HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include <sstream>
#include <boost/lexical_cast.hpp>
#include <QHBoxLayout>
#include "IdEdit.h"
#include "Tools.h"
#include "Viewer.h"

namespace snark { namespace graphics { namespace View {

IdEdit::IdEdit( Viewer* viewer )
    : m_viewer( viewer )
    , m_edit( new QLineEdit )
    , m_size( new QLabel )
{
    QPalette p = palette();
    p.setColor( QPalette::Normal, QPalette::Text, QColor( 255, 255, 255 ) );
    p.setColor( QPalette::Normal, QPalette::Base, QColor( 0, 0, 0 ) );
    m_edit->setMaxLength( 10 );
    m_edit->setPalette( p );
    QSizePolicy policy;
    policy.setHorizontalPolicy( QSizePolicy::Minimum );
    m_edit->setSizePolicy( policy );
    connect( m_edit, SIGNAL( returnPressed() ), this, SLOT( handleReturnPressed() ) );
    connect( this, SIGNAL( valueChanged( comma::uint32 ) ), this, SLOT( setValue( comma::uint32 ) ) );
    QLabel* label = new QLabel( "id:" );
    label->setMargin( 5 );
    m_size->setMargin( 5 );
    QHBoxLayout* layout = new QHBoxLayout;
    layout->addWidget( label );
    layout->addWidget( m_edit );
    layout->addWidget( m_size );
    setLayout( layout );
    setToolTip( "numeric id, e.g. 123
\"min\" for min id
\"max\" for max id
\"new\" (Ctrl-N) for max id + 1" );
}

void IdEdit::handleReturnPressed()
{
    comma::uint32 id = 0;
    std::string s = m_edit->text().toStdString();
    if( s == "" ) { return; }
    if( s == "new" || s == "min" || s == "max" )
    {
        boost::optional< comma::uint32 > minId; // quick and dirty, max is a macro on windows
        boost::optional< comma::uint32 > maxId;
        for( std::size_t i = 0; i < m_viewer->datasets().size(); ++i )
        {
            if( !m_viewer->datasets()[i]->visible() || m_viewer->datasets()[i]->partitions().empty() ) { continue; }
            if( !minId || m_viewer->datasets()[i]->partitions().begin()->first < *minId ) { minId = m_viewer->datasets()[i]->partitions().begin()->first; }
            if( !maxId || m_viewer->datasets()[i]->partitions().rbegin()->first > *maxId ) { maxId = m_viewer->datasets()[i]->partitions().rbegin()->first; }
        }
        if( s == "new" ) { id = maxId ? *maxId + 1 : 0; }
        else if( s == "min" ) { id = minId ? *minId : 0; }
        else if( s == "max" ) { id = maxId ? *maxId : 0; }
    }
    else
    {
        try { id = boost::lexical_cast< comma::uint32 >( m_edit->text().toStdString() ); }
        catch( ... ) { m_edit->setText( m_id ? boost::lexical_cast< std::string >( *m_id ).c_str() : "" ); return; }
    }
    //if( m_id && *m_id == id ) { return; }
    emit valueChanged( id );
}

void IdEdit::setValue( comma::uint32 id )
{
    m_id = id;
    QPalette p = palette();
    QColor4ub color = Tools::colorFromId( id );
    QColor background;
    QColor foreground = color.red() + color.green() + color.blue() > 640 ? QColor( 0, 0, 0 ) : QColor( 255, 255, 255 );
    background.setRgb( color.red(), color.green(), color.blue() );
    p.setColor( QPalette::Normal, QPalette::Text, foreground );
    p.setColor( QPalette::Normal, QPalette::Base, background );
    m_edit->setText( boost::lexical_cast< std::string >( id ).c_str() );
    m_edit->setPalette( p );
    comma::uint32 size = 0;
    std::size_t num = 0;
    for( std::size_t i = 0; i < m_viewer->datasets().size(); ++i )
    {
        if( !m_viewer->datasets()[i]->visible() ) { continue; }
        Dataset::Partitions::const_iterator it = m_viewer->datasets()[i]->partitions().find( id );
        if( it != m_viewer->datasets()[i]->partitions().end() )
        {
            std::cerr << "label-points: id " << id << ": " << it->second.size() << ( it->second.size() == 1 ? " point" : " points" ) << " in " << m_viewer->datasets()[i]->filename() << std::endl;
            size += it->second.size();
        }
        ++num;
    }
    std::ostringstream oss;
    oss << size << ( size == 1 ? " point" : " points" );
    if( size > 0 && m_viewer->datasets().size() > 1 ) { oss << " in " << num << " visible file" << ( num == 1 ? "" : "s" ); }
    m_size->setText( oss.str().c_str() );
}

} } } // namespace snark { namespace graphics { namespace View {

max_stars_repo_name: jackiecx/snark

max_issues_repo_name: jackiecx/snark

max_forks_repo_name: jackiecx/snark


text:
//
// FILE NAME:       $HeadURL: svn+ssh://svn.cm.aol.com/advertising/adlearn/gen1/trunk/lib/cpp/DataProxy/private/GroupingAggregateStreamTransformer.cpp $
//
// REVISION:        $Revision: 287491 $
//
// COPYRIGHT:       (c) 2008 Advertising.com All Rights Reserved.
//
// LAST UPDATED:    $Date: 2013-09-11 20:45:11 -0400 (Wed, 11 Sep 2013) $
// UPDATED BY:      $Author: sstrick $

// This class is responsible for performing runtime aggregations based on configuration.
// It dynamically generates unix commands ('awk') based on the configuration
// and executes the command on the incoming stream.  The basic algorithm is:
// 1. Pre-Process (i.e. turn hourperiods into dayperiods, add 10, etc.) to the requested fields
// 2. Order the columns so that keys are aligned into columns 1 through n, where n is the # of
//    fields that represent the entire key. Step 1 is combined into this step with the
//    generation of an awk command that follows the form:
//      {printf("%i,%i,%i,%i", $7,$3/5,$1,$5+1);}
//    In the above case, we're interested in 4 columns... those in positions 7, 3, 1, and 5.
//     input-column 3 (output-column 2) will be divided by 5,
//     and input-column 5 (output-column 4) will be incremented by 1
// 3. Generate an awk command to perform aggregation. See AggregateFields for the general pattern

#include "GroupingAggregateStreamTransformer.hpp"
#include "LargeStringStream.hpp"
#include "ShellExecutor.hpp"
#include "MVLogger.hpp"
#include "Nullable.hpp"
#include "AggregatorField.hpp"
#include "AwkUtilities.hpp"
#include "TransformerUtilities.hpp"
#include <algorithm>
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <boost/regex.hpp>
#include <set>

namespace
{
	const std::string KEY( "key" );
	const std::string FIELDS( "fields" );
	const std::string TIMEOUT( "timeout" );
	const std::string SKIP_GROUP( "skipGroup" );
	const std::string SKIP_DEFAULT( "false" );
	const std::string TEMP_DIRECTORY( "tempDir" );
	const std::string TEMP_DEFAULT( "/tmp" );
	const std::string SKIP_GROUP_KEY( "1" );

	const std::string COMMA( "," );
	const std::string COLON( ":" );

	const std::string NEW_VALUE_FORMATTER( "%v" );
	const std::string AGGREGATE_VALUE_FORMATTER( "%a" );
	const std::string KEY_VALUE_FORMATTER( "%k" );

	const boost::regex INIT_REGEX( "init\\((.+)\\)" );
	const boost::regex TYPE_REGEX( "type\\((.+)\\)" );
	const boost::regex OP_REGEX( "op\\((.*)\\)" );
	const boost::regex RENAME_REGEX( "rename\\((.+)\\)" );
	const boost::regex MODIFY_REGEX( "modify\\((.+)\\)" );
	const boost::regex OUTPUT_REGEX( "output\\((.*)\\)" );

	// function responsible for parsing fields and keys, and setting the configuration based on the input parameters.
	// returns null for non-key fields
	Nullable< bool > ParseFields( const std::map< std::string, std::string >& i_rParameters, std::vector< AggregatorField >& o_rFields, bool i_IsKey )
	{
		std::vector< std::string > fields;
		std::string fieldString;
		Nullable< bool > keyExists = null;

		if( i_IsKey )
		{
			Nullable< std::string > keyValue = TransformerUtilities::GetNullableValue( KEY, i_rParameters );
			if( !keyValue.IsNull() )
			{
				fieldString = keyValue;
				keyExists = true;
			}
			else
			{
				return false;
			}
		}
		else
		{
			fieldString = TransformerUtilities::GetValue( FIELDS, i_rParameters );
			if( boost::trim_copy( fieldString ).empty() )
			{
				MV_THROW( GroupingAggregateStreamTransformerException, "No fields have been specified" );
			}
		}

		// first split the fields by comma
		AwkUtilities::SplitByMatchingParentheses( fields, fieldString, ',', false );
		std::vector< std::string >::const_iterator fieldIter = fields.begin();
		for( ; fieldIter != fields.end(); ++fieldIter )
		{
			AggregatorField dataField;
			std::vector< std::string > params;
			std::string::size_type nameEnd = fieldIter->find( COLON );

			// set name and defaults
			dataField.SetValue< Name >( fieldIter->substr(0, nameEnd) );
			boost::trim( dataField.GetReference< Name >() );
			dataField.SetValue< VarName >( dataField.GetValue< Name >() );
			dataField.SetValue< ColumnName >( dataField.GetValue< Name >() );
			dataField.SetValue< AwkType >( "%i" );
			dataField.SetValue< IsKey >( i_IsKey );
			if( !i_IsKey )
			{
				dataField.SetValue< InitValue >( "0" );
				dataField.SetValue< Output >( "%a" );
			}

			// clean up the variable name
			AwkUtilities::CleanVariableName( dataField.GetReference< VarName >() );

			// if there is additional configuration for this field, parse it
			if( nameEnd != std::string::npos )
			{
				bool foundType( false );
				bool foundRename( false );
				bool foundPreModification( false );
				bool foundInit( false );
				bool foundOp( false );
				bool foundOutput( false );

				// parameters begin after the name/parameter separator
				std::string paramString = fieldIter->substr(nameEnd+COLON.size());

				// split the parameter string by ending parentheses
				AwkUtilities::SplitByMatchingParentheses( params, paramString, ')', true );
				std::vector< std::string >::const_iterator paramIter = params.begin();
				for( ; paramIter != params.end(); ++paramIter )
				{
					boost::smatch matches;
					if( boost::regex_match( *paramIter, matches, TYPE_REGEX ) )
					{
						AwkUtilities::SetParameter< AggregatorField, AwkType, Name >( dataField, matches[1], foundType, "type" );
						AwkUtilities::ValidateType( dataField.GetValue< AwkType >(), dataField.GetValue< Name >() );
					}
					else if( boost::regex_match( *paramIter, matches, RENAME_REGEX ) )
					{
						AwkUtilities::SetParameter< AggregatorField, ColumnName, Name >( dataField, matches[1], foundRename, "rename" );
					}
					else if( boost::regex_match( *paramIter, matches, MODIFY_REGEX ) )
					{
						AwkUtilities::SetParameter< AggregatorField, PreModification, Name >( dataField, matches[1], foundPreModification, "modify" );
					}
					else if( !i_IsKey && boost::regex_match( *paramIter, matches, INIT_REGEX ) )
					{
						AwkUtilities::SetParameter< AggregatorField, InitValue, Name >( dataField, matches[1], foundInit, "init" );
					}
					else if( !i_IsKey && boost::regex_match( *paramIter, matches, OP_REGEX ) )
					{
						AwkUtilities::SetParameter< AggregatorField, Operation, Name >( dataField, matches[1], foundOp, "op" );
					}
					else if( !i_IsKey && boost::regex_match( *paramIter, matches, OUTPUT_REGEX ) )
					{
						AwkUtilities::SetParameter< AggregatorField, Output, Name >( dataField, matches[1], foundOutput, "output" );
					}
					else
					{
						std::stringstream message;
						message << "Unrecognized parameter or parameter format: '" << *paramIter << "' for " << (i_IsKey ? "key" : "field" ) << " name: '"
								<< dataField.GetValue< Name >() << "'. Format for each comma-separated " << (i_IsKey ? "key" : "field" ) << " is: "
								<< "column:param1(value1) param2(value2) ... paramN(valueN) where each param is one of: type, rename, modify"
								<< ( i_IsKey ? "" : ", init, op, output" );
						MV_THROW( GroupingAggregateStreamTransformerException, message.str() );
					}
				}

				// if this is a data field (non-key), ensure that it has at least an operation or an output defined
				if( !i_IsKey && !foundOp && !foundOutput )
				{
					MV_THROW( GroupingAggregateStreamTransformerException, "No operation or output defined for field: '" << dataField.GetValue< Name >() << "'" );
				}
			}

			// this data field is required if it is a key, or if the operation accesses a positional value in the stream (identified by %v)
			dataField.SetValue< IsRequired >( i_IsKey || dataField.GetValue< Operation >().find( NEW_VALUE_FORMATTER ) != std::string::npos );
			o_rFields.push_back( dataField );

			// logging the details of the parsed field configuration
			std::stringstream message;
			message << (i_IsKey ? "Key" : "Field") << ": '" << dataField.GetValue< Name >() << "'"
					<< " format type: '" << dataField.GetValue< AwkType >() << "' ";
			if( !dataField.GetValue< PreModification >().empty() )
			{
				message << " modification: '" << dataField.GetValue< PreModification >() << "'";
			}
			if( !dataField.GetValue< Operation >().empty() )
			{
				message << " init value: '" << dataField.GetValue< InitValue >() << "'"
						<< " grouped operation: '" << dataField.GetValue< Operation >() << "'";
			}
			if( !dataField.GetValue< Output >().empty() )
			{
				message << " output: '" << dataField.GetValue< Output >() << "'";
			}
			MVLOGGER( "root.lib.DataProxy.DataProxyClient.StreamTransformers.GroupingAggregator.AggregateFields.FieldDetails", message.str() );
		}

		return keyExists;
	}

	// function to determine whether columns will have to be re-ordered.  This will return true if one of the following is true:
	// 1. a key or field needs to be modified
	// 2. keys are not contiguous columns in the stream
	bool NeedColumnManipulation( std::vector< AggregatorField >& i_rKeys, std::vector< AggregatorField >& i_rFields )
	{
		bool result = false;

		std::stringstream names;
		std::stringstream indices;

		std::set< size_t > keyIndices;
		std::vector< AggregatorField >::const_iterator fieldIter = i_rKeys.begin();
		for( ; fieldIter != i_rKeys.end(); ++fieldIter )
		{
			if( !fieldIter->GetValue< PreModification >().empty() )
			{
				MVLOGGER( "root.lib.DataProxy.DataProxyClient.StreamTransformers.GroupingAggregator.AggregateFields.NeedColumnManipulation.KeyModification",
					"Key column: " << fieldIter->GetValue< Name >() << " has a modification configured. Column manipulation will have to take place" );
				result = true;
			}
			size_t awkIndex = boost::lexical_cast< size_t >( fieldIter->GetValue< AwkIndex >().substr(1) );
			// if inserting a value does not increase the size (i.e. if it's not unique)
			if( !keyIndices.insert( awkIndex ).second )
			{
				// this should NEVER happen!
				MV_THROW( GroupingAggregateStreamTransformerException, "Multiple keys have the same awk-index: " << fieldIter->GetValue< AwkIndex >() );
			}

			if( fieldIter != i_rKeys.begin() )
			{
				names << ',';
				indices << ',';
			}
			names << fieldIter->GetValue< Name >();
			indices << awkIndex;
		}

		if( i_rKeys.size() > 0 )
		{
			size_t minKeyIndex = *keyIndices.begin();
			size_t maxKeyIndex = *keyIndices.rbegin();
			if( minKeyIndex + keyIndices.size()-1 != maxKeyIndex )
			{
				MVLOGGER( "root.lib.DataProxy.DataProxyClient.StreamTransformers.GroupingAggregator.AggregateFields.NeedColumnManipulation.KeyOrdering",
					"Key columns (" << names.str() << ") are not contiguous (indices: " << indices.str() << "). Column manipulation will have to take place" );
				result = true;
			}
		}

		fieldIter = i_rFields.begin();
		for( ; fieldIter != i_rFields.end(); ++fieldIter )
		{
			if( !fieldIter->GetValue< PreModification >().empty() )
			{
				MVLOGGER( "root.lib.DataProxy.DataProxyClient.StreamTransformers.GroupingAggregator.AggregateFields.NeedColumnManipulation.FieldModication",
					"Field column: " << fieldIter->GetValue< Name >() << " has a modification configured. Column manipulation will have to take place" );
				result = true;
			}
		}

		if( result == false )
		{
			MVLOGGER( "root.lib.DataProxy.DataProxyClient.StreamTransformers.GroupingAggregator.AggregateFields.SkipColumnManipulation",
				"Key columns are contiguous and no modifications are configured. Column manipulation will be skipped." );
		}
		return result;
	}

	// the first step is to modify columns as requested (i.e. turn hourperiods->dayperiods)
	// and ensure that key fields make up the first n columns so they can be sorted.
	// this function returns the awk command to do both of these things
	std::string GetPreprocessAndOrderCommand( std::vector< AggregatorField >& i_rKeys, std::vector< AggregatorField >& i_rFields )
	{
		std::stringstream result;
		std::stringstream fields;
		result << "awk -F, '{printf(\"";
		std::vector< AggregatorField >::iterator iter = i_rKeys.begin();
		for( int count=1; iter != i_rFields.end(); ++iter )
		{
			// if we're finished with keys, move on to fields
			if( iter == i_rKeys.end() )
			{
				iter = i_rFields.begin();
			}

			// if this field is not required, then we don't need to output it
			if( !iter->GetValue< IsRequired >() )
			{
				continue;
			}
			if( iter != i_rKeys.begin() )
			{
				result << ',';
				fields << ',';
			}

			// if there's no modification function, then we simply use the index.
			// if there is a modification function, apply it here
			std::string colFunc = ( iter->GetValue< PreModification >().empty() ? iter->GetValue< AwkIndex >() : iter->GetValue< PreModification >() );

			// replace the new value formatter (%v) with the awk index (e.g. $3)
			boost::replace_all( colFunc, NEW_VALUE_FORMATTER, iter->GetValue< AwkIndex >() );

			// add the awk format type to the result
			result << iter->GetValue< AwkType >();

			// and the parallel column function (we will append this stringstream later)
			fields << colFunc;

			// now reset the index to what it will be after the re-ordering
			iter->SetValue< AwkIndex >( AwkUtilities::AwkIndexFormat( count ) );
			++count;
		}
		result << "\\n\", " << fields.str() << ");}' | ";
		return result.str();
	}

	// this function forms the keyFields string & the preprocess/order command, and
	// returns the number of columns that represent the key (so an appropriate call to sort can be made)
	void ParseFieldOrder( std::vector< AggregatorField >& i_rKeys,
						  std::vector< AggregatorField >& i_rFieldOperations,
						  const std::vector< std::string >& i_rHeaderFields,
						  bool i_SkipSort,
						  const std::string& i_rTempDirectory,
						  std::string& o_rKeyFields,
						  std::string& o_rOrderCommand )
	{
		std::stringstream keyFields;
		std::vector< AggregatorField >::iterator fieldIter = i_rKeys.begin();
		// iterate over the keys & set the AwkIndex
		for( ; fieldIter != i_rKeys.end(); ++fieldIter )
		{
			std::string index = AwkUtilities::IndexOf( i_rHeaderFields, fieldIter->GetValue< Name >() );
			fieldIter->SetValue< AwkIndex >( index );
		}

		// iterate over the fields & set the AwkIndex
		for( fieldIter = i_rFieldOperations.begin() ; fieldIter != i_rFieldOperations.end(); ++fieldIter )
		{
			if( !fieldIter->GetValue< IsRequired >() )
			{
				continue;
			}
			std::string index = AwkUtilities::IndexOf( i_rHeaderFields, fieldIter->GetValue< Name >() );
			fieldIter->SetValue< AwkIndex >( index );
		}

		// if we have to perform column manipulation, form the command
		if( NeedColumnManipulation( i_rKeys, i_rFieldOperations ) )
		{
			o_rOrderCommand = GetPreprocessAndOrderCommand( i_rKeys, i_rFieldOperations );
		}

		// finally, after all the re-ordering, form the keyFields
		if( i_rKeys.size() > 0 )
		{
			for( fieldIter = i_rKeys.begin() ; fieldIter != i_rKeys.end(); ++fieldIter )
			{
				if( fieldIter != i_rKeys.begin() )
				{
					keyFields << " \",\" ";
				}
				keyFields << fieldIter->GetValue< AwkIndex >();
			}
		}

		o_rKeyFields = keyFields.str();
	}

	// the print command dictates how every fully-aggregated line will be formatted once it is ready
	std::string GetPrintCommand( const std::vector< AggregatorField >& i_rFields, const std::string& i_rKeyContainer, const std::string& i_rIndexName )
	{
		std::stringstream result;
		std::stringstream fields;
		result << "printf(\"%s";

		std::vector< AggregatorField >::const_iterator iter = i_rFields.begin();
		for( ; iter != i_rFields.end(); ++iter )
		{
			std::string outputColumn = iter->GetValue< Output >();
			if( outputColumn.empty() )
			{
				continue;
			}
			boost::replace_all( outputColumn, AGGREGATE_VALUE_FORMATTER, iter->GetValue< VarName >() + "[" + i_rIndexName + "]" );
			boost::replace_all( outputColumn, KEY_VALUE_FORMATTER, i_rIndexName );
			result << "," << iter->GetValue< AwkType >();
			fields << "," << outputColumn;
		}
		result << "\\n\", " << i_rKeyContainer << "[" << i_rIndexName << "]" << fields.str() << ");";

		return result.str();
	}

	std::string GetPrintCommandNoKeys( const std::vector< AggregatorField >& i_rFields )
	{
		std::stringstream result;
		std::stringstream fields;
		result << "printf(\"";

		for( std::vector< AggregatorField >::const_iterator iter = i_rFields.begin(); iter != i_rFields.end(); ++iter )
		{
			std::string outputColumn = iter->GetValue< Output >();
			if( outputColumn.empty() )
			{
				continue;
			}
			boost::replace_all( outputColumn, AGGREGATE_VALUE_FORMATTER, iter->GetValue< VarName >() );
			result << iter->GetValue< AwkType >();
			if( std::distance(iter, i_rFields.end()) > 1 )
			{
				result << ",";
			}
			fields << "," << outputColumn;
		}
		result << "\\n\" " << fields.str() << ");";

		return result.str();
	}

	// we will have to call the init assignment at the beginning of the function,
	// as well as whenever we move onto the next key, so our aggregations start
	// from the requested value every time
	std::string GetInitAssignment( const std::vector< AggregatorField >& i_rFields )
	{
		std::stringstream result;
		std::vector< AggregatorField >::const_iterator iter = i_rFields.begin();
		for( ; iter != i_rFields.end(); ++iter )
		{
			result << iter->GetValue< VarName >() << " = " << iter->GetValue< InitValue >() << "; ";
		}
		return result.str();
	}

	// we will have to call the init assignment whenever we find a new key, so our aggregations start
	// from the requested value every time
	std::string GetInitAssignment( const std::vector< AggregatorField >& i_rFields, const std::string& i_rIndexName )
	{
		std::stringstream result;
		std::vector< AggregatorField >::const_iterator iter = i_rFields.begin();
		for( ; iter != i_rFields.end(); ++iter )
		{
			result << iter->GetValue< VarName >() << "[" << i_rIndexName << "] = " << iter->GetValue< InitValue >() << "; ";
		}
		return result.str();
	}

	// every time we process a row, we have to perform operations on the
	// appropriate aggregations.
	std::string GetIncrementAssignment( const std::vector< AggregatorField >& i_rFields )
	{
		std::stringstream result;
		std::vector< AggregatorField >::const_iterator iter = i_rFields.begin();
		for( ; iter != i_rFields.end(); ++iter )
		{
			std::string operation = iter->GetValue< Operation >();
			if( operation.empty() )
			{
				continue;
			}
			boost::replace_all( operation, NEW_VALUE_FORMATTER, iter->GetValue< AwkIndex >() );
			boost::replace_all( operation, AGGREGATE_VALUE_FORMATTER, iter->GetValue< VarName >() );
			result << operation << "; ";
		}
		return result.str();
	}

	// every time we process a row, we have to perform operations on the appropriate aggregations
	// at the appropriate index.
	std::string GetIncrementAssignment( const std::vector< AggregatorField >& i_rFields, const std::string& i_rIndexName )
	{
		std::stringstream result;
		std::vector< AggregatorField >::const_iterator iter = i_rFields.begin();
		for( ; iter != i_rFields.end(); ++iter )
		{
			std::string operation = iter->GetValue< Operation >();
			if( operation.empty() )
			{
				continue;
			}
			boost::replace_all( operation, NEW_VALUE_FORMATTER, iter->GetValue< AwkIndex >() );
			boost::replace_all( operation, AGGREGATE_VALUE_FORMATTER, iter->GetValue< VarName >() + "[" + i_rIndexName + "]");
			result << operation << "; ";
		}
		return result.str();
	}

	// helper function to get the count of a given item in a vector
	int CountOf( const std::vector< std::string >& i_rHeaders, const std::string& i_rKey )
	{
		int count = 0;
		std::vector< std::string >::const_iterator iter = i_rHeaders.begin();
		for( ; iter != i_rHeaders.end(); ++iter )
		{
			if( boost::trim_copy( *iter ) == i_rKey )
			{
				++count;
			}
		}
		return count;
	}

	void ValidateUniquePresence( const std::vector< std::string >& i_rHeaders, const std::vector< AggregatorField >& i_rKeys, const std::vector< AggregatorField >& i_rFields )
	{
		std::vector< AggregatorField >::const_iterator iter = i_rKeys.begin();
		for( ; iter != i_rFields.end(); ++iter )
		{
			// if we're done with keys, move on to fields
			if( iter == i_rKeys.end() )
			{
				iter = i_rFields.begin();
			}

			int count = CountOf( i_rHeaders, iter->GetValue< Name >() );
			if( iter->GetValue< IsRequired >() && count == 0 )
			{
				MV_THROW( GroupingAggregateStreamTransformerException, "Input stream is missing required column: '" << iter->GetValue< Name >() << "'" );
			}
			if( count > 1 )
			{
				MV_THROW( GroupingAggregateStreamTransformerException, "Input stream has ambiguous required column: '" << iter->GetValue< Name >() << "'" );
			}
		}
	}
}

GroupingAggregateStreamTransformer::GroupingAggregateStreamTransformer()
 :	ITransformFunction()
{
}

GroupingAggregateStreamTransformer::~GroupingAggregateStreamTransformer()
{
}

boost::shared_ptr< std::istream > GroupingAggregateStreamTransformer::TransformInput( boost::shared_ptr< std::istream > i_pInputStream, const std::map< std::string, std::string >& i_rParameters )
{
	std::large_stringstream* pResult( new std::large_stringstream() );
	std::stringstream command;
	bool keysExist;

	// parse out configuration values
	double timeout = TransformerUtilities::GetValueAs< double >( TIMEOUT, i_rParameters );
	bool skipGroup = TransformerUtilities::GetValueAsBool( SKIP_GROUP, i_rParameters, SKIP_DEFAULT );
	std::string tempDirectory = TransformerUtilities::GetValue( TEMP_DIRECTORY, i_rParameters, TEMP_DEFAULT );

	// parse out required key columns (and see if the key exists)
	std::vector< AggregatorField > keys;
	keysExist = ParseFields( i_rParameters, keys, true );

	// parse out fields & their operations
	std::vector< AggregatorField > fields;
	ParseFields( i_rParameters, fields, false );

	// form the output header
	std::vector< AggregatorField > outputFields;
	for( std::vector< AggregatorField >::const_iterator iter = keys.begin(); iter != fields.end(); ++iter )
	{
		if( iter == keys.end() )
		{
			iter = fields.begin();
		}
		// if this is a non-key, and is set to empty output, skip it
		if( !iter->GetValue< IsKey >() && iter->GetValue< Output >().empty() )
		{
			continue;
		}
		outputFields.push_back( *iter );
	}
	std::string outputHeader = AwkUtilities::GetOutputHeader< AggregatorField, ColumnName >( outputFields );
	MVLOGGER( "root.lib.DataProxy.DataProxyClient.GroupingAggregateStreamTransformer.TransformInput.OutputHeader", "Output format will be: '" << outputHeader << "'" );

	// read a line from the input to get the input header
	std::string inputHeader;
	std::getline( *i_pInputStream, inputHeader );
	std::vector< std::string > headerFields;
	boost::iter_split( headerFields, inputHeader, boost::first_finder(COMMA) );
	ValidateUniquePresence( headerFields, keys, fields );

	// short circuit if we're done
	if( i_pInputStream->peek() == EOF )
	{
		*pResult << outputHeader << std::endl;
		return boost::shared_ptr< std::istream >( pResult );
	}

	// get the string that will represent our key & the initial command that will order key-columns first
	std::string keyFields;
	std::string orderCommand;
	ParseFieldOrder( keys, fields, headerFields, skipGroup, tempDirectory, keyFields, orderCommand );
	command << orderCommand;

	// form the awk command
	// skipGroup == false means full aggregation of data (memory-intensive)
	// skipGroup == true  means that we skip grouping to save awk memory

	if ( !skipGroup && keysExist ) // Normal case
	{
		command << "awk -F, '"
				<< "BEGIN	{ 	print \"" << outputHeader << "\"; } "
				<< "		{ 	__currentKey = " << keyFields << "; "
				<< "			if (__currentKey in __foundKey) "
				<< "			{ "
				<<					GetIncrementAssignment( fields, "__currentKey" ) << "; "
				<< "			} "
				<< "			else "
				<< "			{ "
				<< "				__foundKey[__currentKey] = __currentKey; "
				<< 					GetInitAssignment( fields, "__currentKey" ) << "; "
				<< 					GetIncrementAssignment( fields, "__currentKey" ) << "; "
				<< "			} "
				<< "		} "
				<< "END 	{	for (__var in __foundKey) " << GetPrintCommand( fields, "__foundKey", "__var") << "; }'";
	}
	else if (!keysExist)
	{
		command << "awk -F, '"
				<< "BEGIN 	{	print \"" << outputHeader << "\"; } "
				<< "NR == 1	{"	<< GetInitAssignment( fields ) << "; }"
				<< "		{ "	<< GetIncrementAssignment( fields ) << "; }"
				<< "END		{ " << GetPrintCommandNoKeys( fields ) << "; }"
				<< "'";
	}
	else
	{
		command << "awk -F, '"
				<< "BEGIN 	{	print \"" << outputHeader << "\"; } "
				<< "NR == 1	{	__prevKey = " << keyFields << ";  "
				<< "			__foundKey[" << SKIP_GROUP_KEY << "] = __prevKey; "
				<< 				GetInitAssignment( fields, SKIP_GROUP_KEY) << "; "
				<< "		}"
				<< "		{	__currentKey = " << keyFields << "; "
				<< "			if (__prevKey != __currentKey) "
				<< "			{ "
				<< 					GetPrintCommand( fields, "__foundKey", SKIP_GROUP_KEY ) << "; "
				<< 					GetInitAssignment( fields, SKIP_GROUP_KEY ) << "; "
				<< "				__prevKey = __currentKey; "
				<< "				__foundKey[" << SKIP_GROUP_KEY << "] = __currentKey; "
				<< "			} "
				<< 				GetIncrementAssignment( fields, SKIP_GROUP_KEY ) << "; "
				<< "		} "
				<< "END		{ " << GetPrintCommand( fields, "__foundKey", SKIP_GROUP_KEY ) << "; }"
				<< "'";
	}

	// execute!
	std::large_stringstream standardError;
	ShellExecutor executor( command.str() );
	MVLOGGER( "root.lib.DataProxy.DataProxyClient.StreamTransformers.GroupingAggregator.AggregateFields.ExecutingCommand", "Executing command: '" << command.str() << "'" );
	int status = executor.Run( timeout, *i_pInputStream, *pResult, standardError );
	standardError.flush();
	if( status != 0 )
	{
		MV_THROW( GroupingAggregateStreamTransformerException, "Aggregator returned non-zero status: " << status << ". Standard error: " << standardError.rdbuf() );
	}
	if( !standardError.str().empty() )
	{
		MVLOGGER( "root.lib.DataProxy.DataProxyClient.StreamTransformers.GroupingAggregator.AggregateFields.StandardError",
			"Aggregator generated standard error output: " << standardError.rdbuf() );
	}
	pResult->flush();
	return boost::shared_ptr< std::istream >( pResult );
}

max_stars_repo_name: aol/DataProxyLibrary

max_issues_repo_name: aol/DataProxyLibrary

max_forks_repo_name: aol/DataProxyLibrary


text:
#pragma once

#include <boost/asio/io_service.hpp>
#include <boost/asio/serial_port.hpp>
#include <boost/asio/deadline_timer.hpp>

class SerialPort
{
public:
  using tResponseCallback = std::function<void(std::string const&, bool error)>;
  using eParity = boost::asio::serial_port_base::parity::type;
  using eStopBits = boost::asio::serial_port_base::stop_bits::type;

public:
  SerialPort(std::string const& portPath,
             uint32_t baudrate,
             eParity parity = eParity::none,
             eStopBits = eStopBits::one,
             uint8_t characterSize = 8);

  SerialPort(SerialPort&&) = default;
  SerialPort& operator=(SerialPort&&) = default;

  void SendCommand(std::string const& data,
                   tResponseCallback && response = [](std::string const&, bool error){},
                   size_t timeoutResponseMs = 0);

private:
  boost::asio::io_service _io;
  boost::asio::serial_port _port;
  boost::asio::deadline_timer _timer;
};

ext: hpp


text:
/**
 * @file multicast_sender_example.cpp
 *
 * @author Lucas Haug <lucas.haug@thuneratz.org>
 * @author Lucas Schneider <lucas.schneider@thuneratz.org>
 *
 * @brief Example on how to use the MulticastSender
 *
 * @date 04/2021
 *
 * @copyright MIT License - Copyright (c) 2021 ThundeRatz
 */

#include <boost/asio.hpp>
#include <iostream>
#include <string>

#include "travesim_adapters/udp/multicast_sender.hpp"

/*****************************************
 * Main Function
 *****************************************/

int main() {
    const std::string multicast_address_str = "224.0.0.1";
    const short multicast_port = 10002;
    const int max_message_count = 10;

    try {
        boost::asio::io_context io_context;
        boost::asio::steady_timer my_timer(io_context);
        travesim::udp::MulticastSender my_sender(multicast_address_str, multicast_port);

        for (int i = 0; i < max_message_count; i++) {
            std::string msg = "Menssagem " + std::to_string(i);
            size_t bytes_sent = my_sender.send(msg.c_str(), msg.length());

            std::cout << msg << "\nBytes sent: " << bytes_sent << "\n\n";

            my_timer.expires_after(std::chrono::milliseconds(200));
            my_timer.wait();
        }
    } catch (std::exception& e) {
        std::cerr << "Exception: " << e.what() << "\n";
    }

    return 0;
}


text:
// Copyright 2006-2009 Daniel James.
// 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)

//[intro_example1_1
#include <boost/unordered_map.hpp>
#include <boost/foreach.hpp>
#include <cassert>
#include <iostream>
//]

int main() {
//[intro_example1_2
    typedef boost::unordered_map<std::string, int> map;
    map x;
    x["one"] = 1;
    x["two"] = 2;
    x["three"] = 3;

    assert(x.at("one") == 1);
    assert(x.find("missing") == x.end());
//]

//[intro_example1_3
    BOOST_FOREACH(map::value_type i, x) {
        std::cout<<i.first<<","<<i.second<<"\n";
    }
//]
}

max_stars_repo_name: randolphwong/mcsema

max_issues_repo_name: randolphwong/mcsema

max_forks_repo_name: randolphwong/mcsema


text:
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.

#ifndef BOOST_PYTHON_SOURCE
# define BOOST_PYTHON_SOURCE
#endif

#include <boost/python/errors.hpp>
#include <boost/cast.hpp>
#include <boost/python/detail/exception_handler.hpp>

namespace boost { namespace python {

// IMPORTANT: this function may only be called from within a catch block!
BOOST_PYTHON_DECL bool handle_exception_impl(function0<void> f)
{
    try
    {
        if (detail::exception_handler::chain)
            return detail::exception_handler::chain->handle(f);
        f();
        return false;
    }
    catch(const boost::python::error_already_set&)
    {
        // The python error reporting has already been handled.
    }
    catch(const std::bad_alloc&)
    {
        PyErr_NoMemory();
    }
    catch(const bad_numeric_cast& x)
    {
        PyErr_SetString(PyExc_OverflowError, x.what());
    }
    catch(const std::exception& x)
    {
        PyErr_SetString(PyExc_RuntimeError, x.what());
    }
    catch(...)
    {
        PyErr_SetString(PyExc_RuntimeError, "unidentifiable C++ exception");
    }
    return true;
}

void BOOST_PYTHON_DECL throw_argument_error()
{
    throw argument_error();
}

void BOOST_PYTHON_DECL throw_error_already_set()
{
    throw error_already_set();
}

namespace detail {

  BOOST_PYTHON_DECL void expect_complex(PyObject* p)
  {
      if (!PyComplex_Check(p))
      {
          PyErr_SetString(PyExc_TypeError, "expected a complex number");
          boost::python::throw_argument_error();
      }
  }

// needed by void_adaptor (see void_adaptor.hpp)
BOOST_PYTHON_DECL PyObject arbitrary_object = { 0 };

bool exception_handler::operator()(function0<void> const& f) const
{
    if (m_next)
    {
        return m_next->handle(f);
    }
    else
    {
        f();
        return false;
    }
}

exception_handler::exception_handler(handler_function const& impl)
    : m_impl(impl)
    , m_next(0)
{
    if (chain != 0)
        tail->m_next = this;
    else
        chain = this;
    tail = this;
}

exception_handler* exception_handler::chain;
exception_handler* exception_handler::tail;

BOOST_PYTHON_DECL void register_exception_handler(handler_function const& f)
{
    // the constructor links the new object into a handler chain, so
    // this object isn't actaully leaked (until, of course, the
    // interpreter exits).
    new exception_handler(f);
}

} // namespace boost::python::detail

}} // namespace boost::python