/* =========================================================================
   Copyright (c) 2010-2012, Institute for Microelectronics,
                            Institute for Analysis and Scientific Computing,
                            TU Wien.
   Portions of this software are copyright by UChicago Argonne, LLC.

                            -----------------
                  ViennaCL - The Vienna Computing Library
                            -----------------

   Project Head:    Karl Rupp                   rupp@iue.tuwien.ac.at

   (A list of authors and contributors can be found in the PDF manual)

   License:         MIT (X11), see file LICENSE in the base directory
============================================================================= */

//
// *** System
//
#include <iostream>

//
// *** Boost
//
#include <boost/numeric/ublas/io.hpp>
#include <boost/numeric/ublas/vector.hpp>
#include <boost/foreach.hpp>

//
// *** ViennaCL
//

//#define VIENNACL_DEBUG_ALL
#define VIENNACL_HAVE_UBLAS 1
//#define VIENNACL_DEBUG_BUILD
#include "viennacl/vector.hpp"
#include "viennacl/linalg/inner_prod.hpp"
#include "viennacl/linalg/norm_1.hpp"
#include "viennacl/linalg/norm_2.hpp"
#include "viennacl/linalg/norm_inf.hpp"
#include "viennacl/generator/custom_operation.hpp"
#include "viennacl/generator/elementwise_modifier.hpp"
#include "viennacl/generator/convenience_typedef.hpp"

using namespace boost::numeric;
using namespace viennacl::generator;

template <class TYPE>
bool readVectorFromFile ( const std::string & filename, boost::numeric::ublas::vector<TYPE> & vec ) {
    std::ifstream file ( filename.c_str() );

    if ( !file ) return false;

    unsigned int size;
    file >> size;

    if ( size > 20000 )  //keep execution times short
        size = 20000;
    vec.resize ( size );

    for ( unsigned int i = 0; i < size; ++i ) {
        TYPE element;
        file >> element;
        vec[i] = element;
    }

    return true;
}

template <typename ScalarType, unsigned int Alignment>
ScalarType diff ( ublas::vector<ScalarType> & v1, viennacl::vector<ScalarType,Alignment> & v2 ) {
    ublas::vector<ScalarType> v2_cpu ( v2.size() );
    viennacl::copy( v2.begin(), v2.end(), v2_cpu.begin() );
    for ( unsigned int i=0; i<v1.size(); ++i ) {
        if ( std::max ( fabs ( v2_cpu[i] ), fabs ( v1[i] ) ) > 0 )
            v2_cpu[i] = fabs ( v2_cpu[i] - v1[i] ) / std::max ( fabs ( v2_cpu[i] ), fabs ( v1[i] ) );
        else
            v2_cpu[i] = 0.0;
    }
    return norm_inf ( v2_cpu );
}

template< typename NumericT, unsigned int Alignment, typename Epsilon >
int test ( Epsilon const& epsilon, std::string vecfile) {
    int retval = EXIT_SUCCESS;

    ublas::vector<NumericT> vec;
    ublas::vector<NumericT> vec2;
    ublas::vector<NumericT> vec3;

    NumericT                    cpu_scal = static_cast<NumericT> ( 42.1415 );
    viennacl::scalar<NumericT>  gpu_scal = static_cast<NumericT> ( 42.1415 );

    viennacl::generator::symbolic_vector<0,NumericT,Alignment> symv;
    viennacl::generator::symbolic_vector<1,NumericT,Alignment> symv2;

    viennacl::generator::cpu_symbolic_scalar<1,NumericT> cpu_sym_scal2;
    viennacl::generator::gpu_symbolic_scalar<1,NumericT> gpu_sym_scal2;

    viennacl::generator::cpu_symbolic_scalar<2,NumericT> cpu_sym_scal3;
    viennacl::generator::gpu_symbolic_scalar<2,NumericT> gpu_sym_scal3;

    viennacl::generator::symbolic_vector<3, NumericT, Alignment> symv4;

    if ( !readVectorFromFile<NumericT> ( vecfile, vec ) ) {
        std::cout << "Error reading vec file" << std::endl;
        retval = EXIT_FAILURE;
    }

    std::cout << "Running tests for vector of size " << vec.size() << std::endl;
    std::cout << "----- Alignment " << Alignment << " -----" << std::endl;

    viennacl::vector<NumericT,Alignment> vcl_vec ( vec.size() );
    viennacl::vector<NumericT,Alignment> vcl_vec2( vec.size() );
    viennacl::vector<NumericT,Alignment> vcl_vec3( vec.size() );

    vec2 = vec;
    vec3 = 5.0 * vec;
    viennacl::copy ( vec.begin(), vec.end(), vcl_vec.begin() );
    viennacl::copy ( vec2.begin(), vec2.end(), vcl_vec2.begin() );
    viennacl::copy ( vec3.begin(), vec3.end(), vcl_vec3.begin() );

    unsigned int SIZE = vec.size();
    // --------------------------------------------------------------------------

    std::cout << "testing elementwise operations : vec = 1/(1+exp(-vec.*vec2))..." << std::endl;
    for(unsigned int i=0; i < SIZE; ++i){
        vec[i] = 1/(1+exp(-vec[i]*vec2[i]));
    }
    viennacl::ocl::enqueue ( viennacl::generator::custom_operation ( symv = _1_/(_1_ + math::exp(-element_prod(symv,symv2))), "vec_elementwise_test") ( vcl_vec, vcl_vec2 ) );
    if ( fabs ( diff ( vec, vcl_vec ) ) > epsilon ) {
        std::cout << "# Error at operation: addition" << std::endl;
        std::cout << "  diff: " << fabs ( diff ( vec, vcl_vec ) ) << std::endl;
        retval = EXIT_FAILURE;
    }

    std::cout << "testing addition..." << std::endl;
    vec     = ( vec - vec2 );
    viennacl::ocl::enqueue ( viennacl::generator::custom_operation ( symv = symv - symv2, "vec_add") ( vcl_vec, vcl_vec2 ) );
    if ( fabs ( diff ( vec, vcl_vec ) ) > epsilon ) {
        std::cout << "# Error at operation: addition" << std::endl;
        std::cout << "  diff: " << fabs ( diff ( vec, vcl_vec ) ) << std::endl;
        retval = EXIT_FAILURE;
    }

    std::cout << "Testing inplace addition..." << std::endl;
    vec     += vec2;
    viennacl::ocl::enqueue ( viennacl::generator::custom_operation ( symv += symv2, "vec_inplace_add" ) ( vcl_vec, vcl_vec2 ) );
    if ( fabs ( diff ( vec, vcl_vec ) ) > epsilon ) {
        std::cout << "# Error at operation: inplace addition" << std::endl;
        std::cout << "  diff: " << fabs ( diff ( vec, vcl_vec ) ) << std::endl;
        retval = EXIT_FAILURE;
    }

    std::cout << "testing substraction..." << std::endl;
    vec     = vec - vec2;
    viennacl::ocl::enqueue ( viennacl::generator::custom_operation ( symv = symv - symv2, "vec_sub" ) ( vcl_vec, vcl_vec2 ) );
    if ( fabs ( diff ( vec, vcl_vec ) ) > epsilon ) {
        std::cout << "# Error at operation: substraction" << std::endl;
        std::cout << "  diff: " << fabs ( diff ( vec, vcl_vec ) ) << std::endl;
        retval = EXIT_FAILURE;
    }

    std::cout << "Testing inplace substraction..." << std::endl;
    vec     -= vec2;
    viennacl::ocl::enqueue ( viennacl::generator::custom_operation ( symv -= symv2, "vec_inplace_sub" ) ( vcl_vec, vcl_vec2 ) );
    if ( fabs ( diff ( vec, vcl_vec ) ) > epsilon ) {
        std::cout << "# Error at operation: inplace substraction" << std::endl;
        std::cout << "  diff: " << fabs ( diff ( vec, vcl_vec ) ) << std::endl;
        retval = EXIT_FAILURE;
    }

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

    std::cout << "testing cpu scalar multiplication ..." << std::endl;
    vec     = vec*cpu_scal;
    viennacl::ocl::enqueue ( viennacl::generator::custom_operation ( symv = symv*cpu_sym_scal2, "vec_cpu_scal_mul") ( vcl_vec, cpu_scal ) );
    if ( fabs ( diff ( vec, vcl_vec ) ) > epsilon ) {
        std::cout << "# Error at operation: cpu scalar multiplication " << std::endl;
        std::cout << "  diff: " << fabs ( diff ( vec, vcl_vec ) ) << std::endl;
        retval = EXIT_FAILURE;
    }

    std::cout << "testing inplace cpu scalar multiplication ..." << std::endl;
    vec     *= cpu_scal;
    viennacl::ocl::enqueue ( viennacl::generator::custom_operation ( symv *= cpu_sym_scal2, "vec_inplace_cpu_scal_mul" ) ( vcl_vec, cpu_scal ) );
    if ( fabs ( diff ( vec, vcl_vec ) ) > epsilon ) {
        std::cout << "# Error at operation: inplace cpu scalar multiplication " << std::endl;
        std::cout << "  diff: " << fabs ( diff ( vec, vcl_vec ) ) << std::endl;
        retval = EXIT_FAILURE;
    }

    std::cout << "testing cpu scalar division ..." << std::endl;
    vec     = vec/cpu_scal;
    viennacl::ocl::enqueue ( viennacl::generator::custom_operation ( symv = symv/cpu_sym_scal2, "vec_cpu_scal_div") ( vcl_vec, cpu_scal ) );
    if ( fabs ( diff ( vec, vcl_vec ) ) > epsilon ) {
        std::cout << "# Error at operation: cpu scalar division " << std::endl;
        std::cout << "  diff: " << fabs ( diff ( vec, vcl_vec ) ) << std::endl;
        retval = EXIT_FAILURE;
    }

    std::cout << "testing inplace cpu scalar division ..." << std::endl;
    vec     /= cpu_scal;
    viennacl::ocl::enqueue ( viennacl::generator::custom_operation ( symv /= cpu_sym_scal2, "vec_inplace_cpu_scal_div" ) ( vcl_vec, cpu_scal ) );
    if ( fabs ( diff ( vec, vcl_vec ) ) > epsilon ) {
        std::cout << "# Error at operation: inplace cpu scalar division " << std::endl;
        std::cout << "  diff: " << fabs ( diff ( vec, vcl_vec ) ) << std::endl;
        retval = EXIT_FAILURE;
    }

    std::cout << "testing gpu scalar multiplication ..." << std::endl;
    vec     = vec*cpu_scal;
    viennacl::ocl::enqueue ( viennacl::generator::custom_operation ( symv = symv*gpu_sym_scal2, "vec_gpu_scal_mul" ) ( vcl_vec, gpu_scal ) );
    if ( fabs ( diff ( vec, vcl_vec ) ) > epsilon ) {
        std::cout << "# Error at operation: gpu scalar multiplication " << std::endl;
        std::cout << "  diff: " << fabs ( diff ( vec, vcl_vec ) ) << std::endl;
        retval = EXIT_FAILURE;
    }

    std::cout << "testing cpu and gpu scalar multiplication ..." << std::endl;
    vec     = cpu_scal*vec*cpu_scal;
    viennacl::ocl::enqueue ( viennacl::generator::custom_operation ( symv = cpu_sym_scal2*symv*gpu_sym_scal3, "vec_cpu_gpu_scal_mul" ) ( vcl_vec, cpu_scal, gpu_scal ) );
    if ( fabs ( diff ( vec, vcl_vec ) ) > epsilon ) {
        std::cout << "# Error at operation: cpu and gpu scalar multiplication " << std::endl;
        std::cout << "  diff: " << fabs ( diff ( vec, vcl_vec ) ) << std::endl;
        retval = EXIT_FAILURE;
    }

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

    std::cout << "testing addition scalar multiplication..." << std::endl;
    vec     = vec + cpu_scal*vec2;
    viennacl::ocl::enqueue ( viennacl::generator::custom_operation ( symv = symv + cpu_sym_scal3*symv2, "vec_multiply_add" ) ( vcl_vec, vcl_vec2, cpu_scal ) );
    if ( fabs ( diff ( vec, vcl_vec ) ) > epsilon ) {
        std::cout << "# Error at operation: addition scalar multiplication" << std::endl;
        std::cout << "  diff: " << fabs ( diff ( vec, vcl_vec ) ) << std::endl;
        retval = EXIT_FAILURE;
    }

    // --------------------------------------------------------------------------
    std::cout << "testing packed operations..." << std::endl;
    vec     = vec - cpu_scal*(vec2 + vec);
    viennacl::ocl::enqueue ( viennacl::generator::custom_operation ( symv = symv - cpu_sym_scal3*(symv2+symv), "vec_packed_operations" ) ( vcl_vec, vcl_vec2,cpu_scal ) );
    if ( fabs ( diff ( vec, vcl_vec ) ) > epsilon ) {
        std::cout << "# Error at operation: multiple addition" << std::endl;
        std::cout << "  diff: " << fabs ( diff ( vec, vcl_vec ) ) << std::endl;
        retval = EXIT_FAILURE;
    }

    // --------------------------------------------------------------------------
    std::cout << "testing multi-line operations..." << std::endl;
    vec3    = vec - cpu_scal*vec2;
    vec     = vec + cpu_scal*vec2;
    viennacl::generator::custom_operation multi_op( symv4 = symv - cpu_sym_scal3 * symv2,
                                                    symv  = symv + cpu_sym_scal3 * symv2,
                                                    "vec_multi_operations" ) ;
    //std::cout << "source: " << multi_op.kernels_source_code() << std::endl;
    viennacl::ocl::enqueue ( multi_op( vcl_vec, vcl_vec2, cpu_scal, vcl_vec3 ) );
    if ( fabs ( diff ( vec, vcl_vec ) ) > epsilon ) {
        std::cout << "# Error at operation: multiple addition" << std::endl;
        std::cout << "  diff: " << fabs ( diff ( vec, vcl_vec ) ) << std::endl;
        retval = EXIT_FAILURE;
    }

    return retval;
}

int main() {
    std::cout << std::endl;
    std::cout << "----------------------------------------------" << std::endl;
    std::cout << "----------------------------------------------" << std::endl;
    std::cout << "## Test :: Vector" << std::endl;
    std::cout << "----------------------------------------------" << std::endl;
    std::cout << "----------------------------------------------" << std::endl;
    std::cout << std::endl;

    int retval = EXIT_SUCCESS;

    std::string vecfile ( "../examples/testdata/rhs65025.txt" );

    std::cout << std::endl;
    std::cout << "----------------------------------------------" << std::endl;
    std::cout << std::endl;
    {
        typedef double NumericT;
        NumericT epsilon = 1.0E-4;
        std::cout << "# Testing setup:" << std::endl;
        std::cout << "  eps:     " << epsilon << std::endl;
        std::cout << "  numeric: float" << std::endl;
        retval = test<NumericT,1> ( epsilon, vecfile );
        retval &= test<NumericT,4> ( epsilon, vecfile );
        retval &= test<NumericT,16> ( epsilon, vecfile );

        if ( retval == EXIT_SUCCESS )
            std::cout << "# Test passed" << std::endl;
        else
            return retval;
    }
}


// This file is part of the dune-stuff project:
//   https://github.com/wwu-numerik/dune-stuff
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_STUFF_GRID_INFORMATION_HH
#define DUNE_STUFF_GRID_INFORMATION_HH

#include <ostream>

#include <boost/format.hpp>
#include <boost/range/adaptor/reversed.hpp>

#include <dune/common/unused.hh>

#if HAVE_DUNE_GRID
#include <dune/grid/common/gridview.hh>
#endif

#include <dune/stuff/common/math.hh>
#include <dune/stuff/grid/intersection.hh>
#include <dune/stuff/common/ranges.hh>
#include <dune/stuff/grid/walker.hh>
#include <dune/stuff/aliases.hh>
#include <dune/stuff/grid/entity.hh>
#include <dune/stuff/grid/walker/functors.hh>

namespace Dune {
namespace Stuff {
namespace Grid {

#if HAVE_DUNE_GRID

struct Statistics
{
  size_t numberOfEntities;
  size_t numberOfIntersections;
  size_t numberOfInnerIntersections;
  size_t numberOfBoundaryIntersections;
  double maxGridWidth;
  template <class GridViewType>
  Statistics(const GridViewType& gridView)
    : numberOfEntities(gridView.size(0))
    , numberOfIntersections(0)
    , numberOfInnerIntersections(0)
    , numberOfBoundaryIntersections(0)
    , maxGridWidth(0)
  {
    for (const auto& entity : DSC::entityRange(gridView)) {
      for (const auto& intIt : DSC::intersectionRange(gridView, entity)) {
        ++numberOfIntersections;
        maxGridWidth = std::max(intIt.geometry().volume(), maxGridWidth);
        // if we are inside the grid
        numberOfInnerIntersections += (intIt.neighbor() && !intIt.boundary());
        // if we are on the boundary of the grid
        numberOfBoundaryIntersections += (!intIt.neighbor() && intIt.boundary());
      }
    }
  }
};

/** \brief grid statistic output to given stream
   */
template <class GridViewType>
void printInfo(const GridViewType& gridView, std::ostream& out)
{
  const Statistics st(gridView);
  out << "found " << st.numberOfEntities << " entities," << std::endl;
  out << "found " << st.numberOfIntersections << " intersections," << std::endl;
  out << "      " << st.numberOfInnerIntersections << " intersections inside and" << std::endl;
  out << "      " << st.numberOfBoundaryIntersections << " intersections on the boundary." << std::endl;
  out << "      maxGridWidth is " << st.maxGridWidth << std::endl;
} // printGridInformation

/**
* \attention Not optimal, does a whole grid walk!
**/
template <class GridViewType>
size_t maxNumberOfNeighbors(const GridViewType& gridView)
{
  size_t maxNeighbours = 0;
  for (const auto& entity : DSC::entityRange(gridView)) {
    size_t neighbours = 0;
    for (const auto& DSC_UNUSED(i) : DSC::intersectionRange(gridView, entity)) {
      ++neighbours;
    }
    maxNeighbours = std::max(maxNeighbours, neighbours);
  }
  return maxNeighbours;
} // size_t maxNumberOfNeighbors(const GridPartType& gridPart)

//! Provide min/max coordinates for all space dimensions of a GridView
template <class GridViewType>
struct Dimensions
{
  static_assert(std::is_base_of<GridView<typename GridViewType::Traits>, GridViewType>::value,
                "GridViewType is no GridView");
  typedef typename GridViewType::Grid GridType;
  //! automatic running min/max
  typedef Dune::Stuff::Common::MinMaxAvg<typename GridType::ctype> MinMaxAvgType;
  typedef std::array<MinMaxAvgType, GridType::dimensionworld> CoordLimitsType;
  typedef typename GridType::template Codim<0>::Entity EntityType;
  CoordLimitsType coord_limits;
  MinMaxAvgType entity_volume;
  MinMaxAvgType entity_width;

  //! gridwalk functor that does the actual work for \ref GridDimensions
  class GridDimensionsFunctor : public Functor::Codim0<GridViewType>
  {
    CoordLimitsType& coord_limits_;
    MinMaxAvgType& entity_volume_;
    MinMaxAvgType& entity_width_;

  public:
    GridDimensionsFunctor(CoordLimitsType& c, MinMaxAvgType& e, MinMaxAvgType& w)
      : coord_limits_(c), entity_volume_(e), entity_width_(w)
    {
    }

    virtual void apply_local(const EntityType& ent)
    {
      const auto& geo = ent.geometry();
      entity_volume_(geo.volume());
      entity_width_(entity_diameter(ent));
      for (auto i : DSC::valueRange(geo.corners())) {
        const auto& corner(geo.corner(i));
        for (size_t k = 0; k < GridType::dimensionworld; ++k)
          coord_limits_[k](corner[k]);
      }
    } // ()
  };

  double volumeRelation() const { return entity_volume.min() != 0.0 ? entity_volume.max() / entity_volume.min() : -1; }

  Dimensions(const GridViewType& gridView)
  {
    GridDimensionsFunctor f(coord_limits, entity_volume, entity_width);
    Walker<GridViewType> gw(gridView);
    gw.add(f);
    gw.walk();
  }

  Dimensions(const EntityType& entity)
  {
    GridDimensionsFunctor f(coord_limits, entity_volume, entity_width);
    f.apply_local(entity);
  }
};

template <class GridType>
Dimensions<typename GridType::LeafGridViewType> dimensions(const GridType& grid)
{
  return Dimensions<typename GridType::LeafGridViewType>(grid.leafGridView());
}

template <class GridViewType>
Dimensions<GridViewType> dimensions(const GridViewType& gridView)
{
  return Dimensions<GridViewType>(gridView);
}

template <class GridViewType>
Dimensions<GridViewType> dimensions(const typename GridViewType::Grid::template Codim<0>::Entity& entity)
{
  return Dimensions<GridViewType>(entity);
}

#endif // HAVE_DUNE_GRID

} // namespace Grid
} // end of namespace Stuff
} // namespace Dune

#if HAVE_DUNE_GRID

template <class T>
inline std::ostream& operator<<(std::ostream& s, const DSG::Dimensions<T>& d)
{
  for (size_t k = 0; k < T::dimensionworld; ++k) {
    const auto& mma = d.coord_limits[k];
    s << boost::format("x%d\tmin: %e\tavg: %e\tmax: %e\n") % k % mma.min() % mma.average() % mma.max();
  }
  s << boost::format("Entity vol min: %e\tavg: %e\tmax: %e\tQout: %e") % d.entity_volume.min()
           % d.entity_volume.average() % d.entity_volume.max() % d.volumeRelation();
  s << std::endl;
  return s;
}

#endif // HAVE_DUNE_GRID

#endif // DUNE_STUFF_GRID_INFORMATION_HH


/**
 * @file GuessPropagator.h
 * @copyright This code is licensed under the 3-clause BSD license.\n
 *            Copyright ETH Zurich, Laboratory of Physical Chemistry, Reiher Group.\n
 *            See LICENSE.txt for details.
 */

#include "GuessPropagator.h"
#include <Eigen/Dense>

namespace Scine {
namespace Sparrow {
namespace RealTimeSpectroscopy {

auto GuessPropagator::calculateGuessAtNewPosition(const Utils::PositionCollection& newPositions)
    -> std::shared_ptr<LinearResponseCalculator::GuessSpecifier> {
  LinearResponseCalculator::GuessSpecifier guess;
  if (excitedStatesHistory_.empty()) {
    return std::shared_ptr<LinearResponseCalculator::GuessSpecifier>();
  }
  Eigen::MatrixXd& excitedStatesGuess = symmetry_ == SpectralType::Unrestricted ? guess.unrestricted : guess.singlet;

  // Generate linear system to solve
  if (excitedStatesHistory_.size() == 1) {
    excitedStatesGuess = excitedStatesHistory_.back();
  }
  else if (!positionsHistory_.empty()) {
    Eigen::MatrixXd lhsMatrix = calculateOverlapMatrix(newPositions);
    Eigen::VectorXd coefficientVector = lhsMatrix.colPivHouseholderQr().solve(calculateRhsVector());
    excitedStatesGuess = Eigen::MatrixXd::Zero(excitedStatesHistory_.front().rows(), excitedStatesHistory_.front().cols());
    int index = 0;
    for (const Eigen::MatrixXd& excitedState : excitedStatesHistory_)
      excitedStatesGuess += excitedState * coefficientVector(index++);
  }

  return std::make_shared<LinearResponseCalculator::GuessSpecifier>(std::move(guess));
}

void GuessPropagator::record(const LinearResponseCalculator::GuessSpecifier& excitedState) {
  if (excitedState.singlet.size() != 0) {
    if (symmetry_ == SpectralType::Unrestricted) {
      reset();
    }
    excitedStatesHistory_.push_front(excitedState.singlet);
    symmetry_ = SpectralType::Singlet;
  }
  else if (excitedState.unrestricted.size() != 0) {
    if (symmetry_ == SpectralType::Singlet) {
      reset();
    }
    excitedStatesHistory_.push_front(excitedState.unrestricted);
    symmetry_ = SpectralType::Unrestricted;
  }
  else {
    throw std::runtime_error("No singlet or unrestricted results.");
  }
  if (static_cast<int>(excitedStatesHistory_.size()) > maxHistoryDimension_) {
    excitedStatesHistory_.pop_back();
  }
}

void GuessPropagator::record(const Utils::PositionCollection& newPositions) {
  positionsHistory_.push_front(newPositions);
  if (static_cast<int>(positionsHistory_.size()) > maxHistoryDimension_) {
    positionsHistory_.pop_back();
  }
}

void GuessPropagator::reset() {
  excitedStatesHistory_.clear();
  positionsHistory_.clear();
}

Eigen::MatrixXd GuessPropagator::calculateErrorVectors(const Utils::PositionCollection& newPosition) const {
  Eigen::MatrixXd errorMatrixBlock(positionsHistory_.front().size(), positionsHistory_.size());
  int index = 0;
  for (const Utils::PositionCollection& position : positionsHistory_) {
    Utils::PositionCollection difference = position - newPosition;
    errorMatrixBlock.col(index++) = Eigen::Map<const Eigen::VectorXd>(difference.data(), difference.size());
  }
  return errorMatrixBlock;
}

Eigen::MatrixXd GuessPropagator::calculateOverlapMatrix(const Utils::PositionCollection& positions) const {
  Eigen::Index dimension = positionsHistory_.size() + 1;
  Eigen::MatrixXd errorOverlapMatrix = Eigen::MatrixXd::Constant(dimension, dimension, -1.0);
  errorOverlapMatrix(0, 0) = 0;
  // Create convert deque to eigen matrix
  Eigen::MatrixXd errorVectors = calculateErrorVectors(positions);
  // Calculate overlap
  errorOverlapMatrix.block(1, 1, dimension - 1, dimension - 1) = errorVectors.transpose() * errorVectors;

  return errorOverlapMatrix;
}

Eigen::VectorXd GuessPropagator::calculateRhsVector() const {
  Eigen::VectorXd result = Eigen::VectorXd::Zero(positionsHistory_.size() + 1);
  result(0) = -1;
  return result;
}

void GuessPropagator::setDimension(int diisDimension) {
  maxHistoryDimension_ = diisDimension;
}
} // namespace RealTimeSpectroscopy
} // namespace Sparrow
} // namespace Scine


#include <openrave-core.h>
#include <openrave/openrave.h>
#include "trajopt/rave_utils.hpp"
#include "trajopt/utils.hpp"
#include "sco/modeling.hpp"
#include <boost/foreach.hpp>
#include "sco/expr_op_overloads.hpp"
using namespace Eigen;
using namespace std;

namespace trajopt {

template <typename T> // var or expr
void FiniteDifferences(const BasicArray<T>& x, AffArray& dx, double dt) {
  dx.resize(x.rows()-1, x.cols());
  for (int i=0; i < x.rows(); ++i) {
    for (int j=0; j < x.cols(); ++j) {
      dx(i,j) = x(i+1,j) - x(i,j);
    }
  }
}

OpenRAVE::Vector toRaveQuat(const Vector4d& v) {
  return OpenRAVE::Vector(v[0], v[1], v[2], v[3]);
}
OpenRAVE::Vector toRaveVector(const Vector3d& v) {
  return OpenRAVE::Vector(v[0], v[1], v[2]);
}

template<typename T>
void extend(vector<T>& a, const vector<T>& b) {
  a.insert(a.end(), b.begin(), b.end());
}

template<typename T>
vector<T> concat(const vector<T>& a, const vector<T>& b, const vector<T>& c) {
  vector<T> out;
  vector<int> x;
  out.insert(out.end(), a.begin(), a.end());
  out.insert(out.end(), b.begin(), b.end());
  out.insert(out.end(), c.begin(), c.end());
  return out;
}
template<typename T>
vector<T> concat(const vector<T>& a, const vector<T>& b, const vector<T>& c, const vector<T>& d) {
  vector<T> out;
  vector<int> x;
  out.insert(out.end(), a.begin(), a.end());
  out.insert(out.end(), b.begin(), b.end());
  out.insert(out.end(), c.begin(), c.end());
  out.insert(out.end(), d.begin(), d.end());
  return out;
}
template<typename T>
vector<T> concat(const vector<T>& a, const vector<T>& b, const vector<T>& c, const vector<T>& d, const vector<T>& e) {
  vector<T> out;
  vector<int> x;
  out.insert(out.end(), a.begin(), a.end());
  out.insert(out.end(), b.begin(), b.end());
  out.insert(out.end(), c.begin(), c.end());
  out.insert(out.end(), d.begin(), d.end());
  out.insert(out.end(), e.begin(), e.end());
  return out;
}

template<typename S, typename T, typename U>
vector<U> cross1(const vector<S>& a, const vector<T>& b) {
  vector<U> c(3);
  c[0] = a[1] * b[2] - a[2] * b[1];
  c[1] = a[2] * b[0] - a[0] * b[2];
  c[2] = a[0] * b[1] - a[1] * b[0];
  return c;
}

void exprInc(AffExprVector& a, const AffExprVector&  b) {
  for (int i=0; i < a.size(); ++i) {
    exprInc(a[i], b[i]);
  }
}
void exprDec(AffExprVector& a, const AffExprVector&  b) {
  for (int i=0; i < a.size(); ++i) {
    exprDec(a[i], b[i]);
  }
}
AffExprVector linearizedCrossProduct(const DblVec& x, const AffExprVector& a, const AffExprVector& b) {
  assert(a.size() == 3 && b.size() == 3);
  DblVec aval(3), bval(3);
  for (int i=0; i < 3; ++i) {
    aval[i] = a[i].value(x);
    bval[i] = b[i].value(x);
  }
  AffExprVector c(3);
  exprInc(c, cross1<AffExpr, double, AffExpr>(a, bval));
  exprInc(c, cross1<double, AffExpr, AffExpr>(aval, b));
  DblVec acrossbval = cross1<double,double,double>(aval, bval);
  for (int i=0; i<3; ++i) exprDec(c[i], acrossbval[i]);
  return c;
}

AffExprVector transformExpr(const OR::Transform& T, const AffExprVector& v) {
  OR::TransformMatrix M(T);
  AffExprVector out(3);
  for (int i=0; i < 3; ++i) {
    for (int j=0; j < 3; ++j) {
      exprInc(out[i], M.rot(i,j) * v[j]);
    }
    exprInc(out[i], T.trans[i]);
  }
  return out;
}
AffExprVector rotateExpr(const OR::Vector& rot, const AffExprVector& v) {
  OR::Transform T;
  T.rot = rot;
  return transformExpr(T, v);
}

}


/*
 *  test_dates.hpp
 *  bondgeek
 *
 *  Created by BART MOSLEY on 6/3/12.
 *  Copyright 2012 BG Research LLC. All rights reserved.
 *
 */

#define BOOST_TEST_DYN_LINK
#include <boost/test/unit_test.hpp>

#include <bg/bondgeek.hpp>

using namespace QuantLib;
using namespace bondgeek;
using namespace boost::unit_test;

#if defined(QL_ENABLE_SESSIONS)
namespace QuantLib {
    Integer sessionId() { return 0; }
}
#endif

struct QDateTests {
	Date date0, date1, date2, date3, date4 ;

	QDateTests() :
	date0(QDate(45000)), // March 15th, 2023
	date1(QDate(Date(7, September, 1980))),
	date2(QDate(19800907)),
	date3(QDate("19600809")),
	date4(QDate("12-13-1976"))
	{
		BOOST_TEST_MESSAGE("\nQDate tests");
	}
};

BOOST_FIXTURE_TEST_SUITE( DateTest, QDateTests )

BOOST_AUTO_TEST_CASE( quantlib_date )
{
	BOOST_TEST_MESSAGE(">>date: " << date1);
	BOOST_CHECK( date1 == Date(7, September, 1980) );
	BOOST_CHECK_EQUAL( date1.year(), 1980 );
	BOOST_CHECK_EQUAL( date1.month(), September);
	BOOST_CHECK_EQUAL( date1.dayOfMonth(), 7 );

}

BOOST_AUTO_TEST_CASE( number_based_dates )
{
	BOOST_CHECK_EQUAL(date0, Date(15, March, 2023));
	BOOST_CHECK_EQUAL(date2, Date(7, September, 1980));
}

BOOST_AUTO_TEST_CASE( string_dates )
{
	BOOST_CHECK_EQUAL( date4.year(), 1976 );
	BOOST_CHECK_EQUAL( date4.month(), December);
	BOOST_CHECK_EQUAL( date4.dayOfMonth(), 13 );

	BOOST_CHECK_EQUAL( date3, Date(9, August, 1960) );
}

BOOST_AUTO_TEST_SUITE_END()


#pragma once

// deal.II includes --------------------------------------------------------
#include <deal.II/base/tensor.h>
#include <deal.II/dofs/dof_accessor.h>

// system includes ---------------------------------------------------------
#include <stdexcept>
#include <unordered_map>
#include <vector>

// dealii includes ---------------------------------------------------------
#include <deal.II/base/quadrature.h>
#include <deal.II/base/quadrature_lib.h>
// own includes ------------------------------------------------------------
#include "aux/hash_specializations.hpp"
#include "var_form/var_form.hpp"

namespace boltzmann {

class GroupFacesByNormals
{
 public:
  constexpr const static int dimX = 2;
  typedef dealii::DoFCellAccessor<dealii::DoFHandler<2>, false> accessor_t;
  typedef int face_index_t;
  /// FUZZY*normal_vector
  typedef std::tuple<long int, long int> key_t;
  typedef std::tuple<accessor_t, face_index_t> value_t;
  typedef std::vector<value_t> entries_t;
  typedef dealii::Tensor<1, 2> vec2_t;
  typedef std::unordered_map<key_t, entries_t> map_t;
  typedef std::unordered_map<key_t, vec2_t> normals_map_t;

 public:
  template <typename DoFHandler>
  GroupFacesByNormals(const DoFHandler& dof_handler,
                      int mpi_this_process = -1,
                      int boundary_id = -1);

  template <typename ITERATOR>
  void insert(vec2_t& normal, ITERATOR& it, face_index_t faceidx);

  constexpr const static double FUZZY = 1e8;

  const map_t& get_map() const { return map_; }
  const normals_map_t& get_normals() const { return normals_; }

 public:
  map_t map_;
  normals_map_t normals_;
};

// ----------------------------------------------------------------------
template <typename DoFHandler>
GroupFacesByNormals::GroupFacesByNormals(const DoFHandler& dof_handler,
                                         int mpi_this_process,
                                         int boundary_id)
{
  VarForm<2, dealii::QGauss> var_form(dof_handler.get_fe(), 2);
  auto& fe_face_values = var_form.get_fe_face_values();

  bool use_bd_ind = boundary_id == -1 ? false : true;
  bool has_mpi = mpi_this_process != -1 ? true : false;
  const int nfaces = dealii::GeometryInfo<dimX>::faces_per_cell;
  for (auto cell : dof_handler.active_cell_iterators()) {
    if (has_mpi)
      if (cell->subdomain_id() != (unsigned int)mpi_this_process) continue;

    if (cell->at_boundary()) {
      for (int face_idx = 0; face_idx < nfaces; ++face_idx) {
        if (cell->face(face_idx)->at_boundary()) {
          if (use_bd_ind)
            if (cell->face(face_idx)->boundary_id() != boundary_id) continue;
          fe_face_values.reinit(cell, face_idx);
          auto normal = fe_face_values.normal_vector(0);
          this->insert(normal, cell, face_idx);
        }
      }
    }
  }
}

// ----------------------------------------------------------------------
template <typename ITERATOR>
void
GroupFacesByNormals::insert(vec2_t& normal, ITERATOR& it, face_index_t faceidx)
{
  long int nx = FUZZY * normal[0];
  long int ny = FUZZY * normal[1];
  auto key = std::make_tuple(nx, ny);
  auto value = std::make_tuple(*it, faceidx);

  map_[key].emplace_back(value);
  normals_[key] = normal;
}

}  // end namespace boltzmann


#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, Eigen::Dynamic, Eigen::Dynamic> test_long_D_D(const Eigen::Matrix<boost::int64_t, Eigen::Dynamic, Eigen::Dynamic> & M)
{
	return M;
}
void export_long_D_D()
{
	boost::python::def("test_long_D_D",test_long_D_D);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, Eigen::Dynamic, 1> test_long_D_1(const Eigen::Matrix<boost::int64_t, Eigen::Dynamic, 1> & M)
{
	return M;
}
void export_long_D_1()
{
	boost::python::def("test_long_D_1",test_long_D_1);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, Eigen::Dynamic, 2> test_long_D_2(const Eigen::Matrix<boost::int64_t, Eigen::Dynamic, 2> & M)
{
	return M;
}
void export_long_D_2()
{
	boost::python::def("test_long_D_2",test_long_D_2);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, Eigen::Dynamic, 3> test_long_D_3(const Eigen::Matrix<boost::int64_t, Eigen::Dynamic, 3> & M)
{
	return M;
}
void export_long_D_3()
{
	boost::python::def("test_long_D_3",test_long_D_3);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, Eigen::Dynamic, 4> test_long_D_4(const Eigen::Matrix<boost::int64_t, Eigen::Dynamic, 4> & M)
{
	return M;
}
void export_long_D_4()
{
	boost::python::def("test_long_D_4",test_long_D_4);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, Eigen::Dynamic, 5> test_long_D_5(const Eigen::Matrix<boost::int64_t, Eigen::Dynamic, 5> & M)
{
	return M;
}
void export_long_D_5()
{
	boost::python::def("test_long_D_5",test_long_D_5);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, Eigen::Dynamic, 6> test_long_D_6(const Eigen::Matrix<boost::int64_t, Eigen::Dynamic, 6> & M)
{
	return M;
}
void export_long_D_6()
{
	boost::python::def("test_long_D_6",test_long_D_6);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 1, Eigen::Dynamic> test_long_1_D(const Eigen::Matrix<boost::int64_t, 1, Eigen::Dynamic> & M)
{
	return M;
}
void export_long_1_D()
{
	boost::python::def("test_long_1_D",test_long_1_D);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 1, 1> test_long_1_1(const Eigen::Matrix<boost::int64_t, 1, 1> & M)
{
	return M;
}
void export_long_1_1()
{
	boost::python::def("test_long_1_1",test_long_1_1);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 1, 2> test_long_1_2(const Eigen::Matrix<boost::int64_t, 1, 2> & M)
{
	return M;
}
void export_long_1_2()
{
	boost::python::def("test_long_1_2",test_long_1_2);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 1, 3> test_long_1_3(const Eigen::Matrix<boost::int64_t, 1, 3> & M)
{
	return M;
}
void export_long_1_3()
{
	boost::python::def("test_long_1_3",test_long_1_3);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 1, 4> test_long_1_4(const Eigen::Matrix<boost::int64_t, 1, 4> & M)
{
	return M;
}
void export_long_1_4()
{
	boost::python::def("test_long_1_4",test_long_1_4);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 1, 5> test_long_1_5(const Eigen::Matrix<boost::int64_t, 1, 5> & M)
{
	return M;
}
void export_long_1_5()
{
	boost::python::def("test_long_1_5",test_long_1_5);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 1, 6> test_long_1_6(const Eigen::Matrix<boost::int64_t, 1, 6> & M)
{
	return M;
}
void export_long_1_6()
{
	boost::python::def("test_long_1_6",test_long_1_6);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 2, Eigen::Dynamic> test_long_2_D(const Eigen::Matrix<boost::int64_t, 2, Eigen::Dynamic> & M)
{
	return M;
}
void export_long_2_D()
{
	boost::python::def("test_long_2_D",test_long_2_D);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 2, 1> test_long_2_1(const Eigen::Matrix<boost::int64_t, 2, 1> & M)
{
	return M;
}
void export_long_2_1()
{
	boost::python::def("test_long_2_1",test_long_2_1);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 2, 2> test_long_2_2(const Eigen::Matrix<boost::int64_t, 2, 2> & M)
{
	return M;
}
void export_long_2_2()
{
	boost::python::def("test_long_2_2",test_long_2_2);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 2, 3> test_long_2_3(const Eigen::Matrix<boost::int64_t, 2, 3> & M)
{
	return M;
}
void export_long_2_3()
{
	boost::python::def("test_long_2_3",test_long_2_3);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 2, 4> test_long_2_4(const Eigen::Matrix<boost::int64_t, 2, 4> & M)
{
	return M;
}
void export_long_2_4()
{
	boost::python::def("test_long_2_4",test_long_2_4);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 2, 5> test_long_2_5(const Eigen::Matrix<boost::int64_t, 2, 5> & M)
{
	return M;
}
void export_long_2_5()
{
	boost::python::def("test_long_2_5",test_long_2_5);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 2, 6> test_long_2_6(const Eigen::Matrix<boost::int64_t, 2, 6> & M)
{
	return M;
}
void export_long_2_6()
{
	boost::python::def("test_long_2_6",test_long_2_6);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 3, Eigen::Dynamic> test_long_3_D(const Eigen::Matrix<boost::int64_t, 3, Eigen::Dynamic> & M)
{
	return M;
}
void export_long_3_D()
{
	boost::python::def("test_long_3_D",test_long_3_D);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 3, 1> test_long_3_1(const Eigen::Matrix<boost::int64_t, 3, 1> & M)
{
	return M;
}
void export_long_3_1()
{
	boost::python::def("test_long_3_1",test_long_3_1);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 3, 2> test_long_3_2(const Eigen::Matrix<boost::int64_t, 3, 2> & M)
{
	return M;
}
void export_long_3_2()
{
	boost::python::def("test_long_3_2",test_long_3_2);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 3, 3> test_long_3_3(const Eigen::Matrix<boost::int64_t, 3, 3> & M)
{
	return M;
}
void export_long_3_3()
{
	boost::python::def("test_long_3_3",test_long_3_3);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 3, 4> test_long_3_4(const Eigen::Matrix<boost::int64_t, 3, 4> & M)
{
	return M;
}
void export_long_3_4()
{
	boost::python::def("test_long_3_4",test_long_3_4);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 3, 5> test_long_3_5(const Eigen::Matrix<boost::int64_t, 3, 5> & M)
{
	return M;
}
void export_long_3_5()
{
	boost::python::def("test_long_3_5",test_long_3_5);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 3, 6> test_long_3_6(const Eigen::Matrix<boost::int64_t, 3, 6> & M)
{
	return M;
}
void export_long_3_6()
{
	boost::python::def("test_long_3_6",test_long_3_6);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 4, Eigen::Dynamic> test_long_4_D(const Eigen::Matrix<boost::int64_t, 4, Eigen::Dynamic> & M)
{
	return M;
}
void export_long_4_D()
{
	boost::python::def("test_long_4_D",test_long_4_D);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 4, 1> test_long_4_1(const Eigen::Matrix<boost::int64_t, 4, 1> & M)
{
	return M;
}
void export_long_4_1()
{
	boost::python::def("test_long_4_1",test_long_4_1);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 4, 2> test_long_4_2(const Eigen::Matrix<boost::int64_t, 4, 2> & M)
{
	return M;
}
void export_long_4_2()
{
	boost::python::def("test_long_4_2",test_long_4_2);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 4, 3> test_long_4_3(const Eigen::Matrix<boost::int64_t, 4, 3> & M)
{
	return M;
}
void export_long_4_3()
{
	boost::python::def("test_long_4_3",test_long_4_3);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 4, 4> test_long_4_4(const Eigen::Matrix<boost::int64_t, 4, 4> & M)
{
	return M;
}
void export_long_4_4()
{
	boost::python::def("test_long_4_4",test_long_4_4);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 4, 5> test_long_4_5(const Eigen::Matrix<boost::int64_t, 4, 5> & M)
{
	return M;
}
void export_long_4_5()
{
	boost::python::def("test_long_4_5",test_long_4_5);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 4, 6> test_long_4_6(const Eigen::Matrix<boost::int64_t, 4, 6> & M)
{
	return M;
}
void export_long_4_6()
{
	boost::python::def("test_long_4_6",test_long_4_6);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 5, Eigen::Dynamic> test_long_5_D(const Eigen::Matrix<boost::int64_t, 5, Eigen::Dynamic> & M)
{
	return M;
}
void export_long_5_D()
{
	boost::python::def("test_long_5_D",test_long_5_D);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 5, 1> test_long_5_1(const Eigen::Matrix<boost::int64_t, 5, 1> & M)
{
	return M;
}
void export_long_5_1()
{
	boost::python::def("test_long_5_1",test_long_5_1);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 5, 2> test_long_5_2(const Eigen::Matrix<boost::int64_t, 5, 2> & M)
{
	return M;
}
void export_long_5_2()
{
	boost::python::def("test_long_5_2",test_long_5_2);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 5, 3> test_long_5_3(const Eigen::Matrix<boost::int64_t, 5, 3> & M)
{
	return M;
}
void export_long_5_3()
{
	boost::python::def("test_long_5_3",test_long_5_3);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 5, 4> test_long_5_4(const Eigen::Matrix<boost::int64_t, 5, 4> & M)
{
	return M;
}
void export_long_5_4()
{
	boost::python::def("test_long_5_4",test_long_5_4);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 5, 5> test_long_5_5(const Eigen::Matrix<boost::int64_t, 5, 5> & M)
{
	return M;
}
void export_long_5_5()
{
	boost::python::def("test_long_5_5",test_long_5_5);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 5, 6> test_long_5_6(const Eigen::Matrix<boost::int64_t, 5, 6> & M)
{
	return M;
}
void export_long_5_6()
{
	boost::python::def("test_long_5_6",test_long_5_6);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 6, Eigen::Dynamic> test_long_6_D(const Eigen::Matrix<boost::int64_t, 6, Eigen::Dynamic> & M)
{
	return M;
}
void export_long_6_D()
{
	boost::python::def("test_long_6_D",test_long_6_D);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 6, 1> test_long_6_1(const Eigen::Matrix<boost::int64_t, 6, 1> & M)
{
	return M;
}
void export_long_6_1()
{
	boost::python::def("test_long_6_1",test_long_6_1);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 6, 2> test_long_6_2(const Eigen::Matrix<boost::int64_t, 6, 2> & M)
{
	return M;
}
void export_long_6_2()
{
	boost::python::def("test_long_6_2",test_long_6_2);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 6, 3> test_long_6_3(const Eigen::Matrix<boost::int64_t, 6, 3> & M)
{
	return M;
}
void export_long_6_3()
{
	boost::python::def("test_long_6_3",test_long_6_3);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 6, 4> test_long_6_4(const Eigen::Matrix<boost::int64_t, 6, 4> & M)
{
	return M;
}
void export_long_6_4()
{
	boost::python::def("test_long_6_4",test_long_6_4);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 6, 5> test_long_6_5(const Eigen::Matrix<boost::int64_t, 6, 5> & M)
{
	return M;
}
void export_long_6_5()
{
	boost::python::def("test_long_6_5",test_long_6_5);
}

#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 6, 6> test_long_6_6(const Eigen::Matrix<boost::int64_t, 6, 6> & M)
{
	return M;
}
void export_long_6_6()
{
	boost::python::def("test_long_6_6",test_long_6_6);
}


//==============================================================================
//         Copyright 2003 - 2012   LASMEA UMR 6602 CNRS/Univ. Clermont II
//         Copyright 2009 - 2012   LRI    UMR 8623 CNRS/Univ Paris Sud XI
//
//          Distributed under the Boost Software License, Version 1.0.
//                 See accompanying file LICENSE.txt or copy at
//                     http://www.boost.org/LICENSE_1_0.txt
//==============================================================================
#define NT2_UNIT_MODULE "boost::simd::constants digits"

#include <boost/simd/include/constants/digits.hpp>
#include <boost/simd/sdk/simd/native.hpp>
#include <nt2/sdk/unit/module.hpp>
#include <nt2/sdk/unit/tests/relation.hpp>

#ifdef BOOST_MSVC
  #pragma warning(disable: 4309) // truncation of constant value
#endif

////////////////////////////////////////////////////////////////////////////////
// Test value of digit constant for every base types
////////////////////////////////////////////////////////////////////////////////
NT2_TEST_CASE_TPL( digit_value, BOOST_SIMD_TYPES )
{
  NT2_TEST_EQUAL( boost::simd::Mten<T>()            , static_cast<T>( -10) );
  NT2_TEST_EQUAL( boost::simd::Mnine<T>()           , static_cast<T>(  -9) );
  NT2_TEST_EQUAL( boost::simd::Meight<T>()          , static_cast<T>(  -8) );
  NT2_TEST_EQUAL( boost::simd::Mseven<T>()          , static_cast<T>(  -7) );
  NT2_TEST_EQUAL( boost::simd::Msix<T>()            , static_cast<T>(  -6) );
  NT2_TEST_EQUAL( boost::simd::Mfive<T>()           , static_cast<T>(  -5) );
  NT2_TEST_EQUAL( boost::simd::Mfour<T>()           , static_cast<T>(  -4) );
  NT2_TEST_EQUAL( boost::simd::Mthree<T>()          , static_cast<T>(  -3) );
  NT2_TEST_EQUAL( boost::simd::Mtwo<T>()            , static_cast<T>(  -2) );
  NT2_TEST_EQUAL( boost::simd::Mone<T>()            , static_cast<T>(  -1) );
  NT2_TEST_EQUAL( boost::simd::Zero<T>()            , static_cast<T>(   0) );
  NT2_TEST_EQUAL( boost::simd::One<T>()             , static_cast<T>(   1) );
  NT2_TEST_EQUAL( boost::simd::Two<T>()             , static_cast<T>(   2) );
  NT2_TEST_EQUAL( boost::simd::Three<T>()           , static_cast<T>(   3) );
  NT2_TEST_EQUAL( boost::simd::Four<T>()            , static_cast<T>(   4) );
  NT2_TEST_EQUAL( boost::simd::Five<T>()            , static_cast<T>(   5) );
  NT2_TEST_EQUAL( boost::simd::Six<T>()             , static_cast<T>(   6) );
  NT2_TEST_EQUAL( boost::simd::Seven<T>()           , static_cast<T>(   7) );
  NT2_TEST_EQUAL( boost::simd::Eight<T>()           , static_cast<T>(   8) );
  NT2_TEST_EQUAL( boost::simd::Nine<T>()            , static_cast<T>(   9) );
  NT2_TEST_EQUAL( boost::simd::Ten<T>()             , static_cast<T>(  10) );
}

////////////////////////////////////////////////////////////////////////////////
// Test for raw 'char' type
////////////////////////////////////////////////////////////////////////////////
NT2_TEST_CASE( char_digit_value )
{
  NT2_TEST_EQUAL( boost::simd::Mten<char>()   , static_cast<char>( -10) );
  NT2_TEST_EQUAL( boost::simd::Mnine<char>()  , static_cast<char>(  -9) );
  NT2_TEST_EQUAL( boost::simd::Meight<char>() , static_cast<char>(  -8) );
  NT2_TEST_EQUAL( boost::simd::Mseven<char>() , static_cast<char>(  -7) );
  NT2_TEST_EQUAL( boost::simd::Msix<char>()   , static_cast<char>(  -6) );
  NT2_TEST_EQUAL( boost::simd::Mfive<char>()  , static_cast<char>(  -5) );
  NT2_TEST_EQUAL( boost::simd::Mfour<char>()  , static_cast<char>(  -4) );
  NT2_TEST_EQUAL( boost::simd::Mthree<char>() , static_cast<char>(  -3) );
  NT2_TEST_EQUAL( boost::simd::Mtwo<char>()   , static_cast<char>(  -2) );
  NT2_TEST_EQUAL( boost::simd::Mone<char>()   , static_cast<char>(  -1) );
  NT2_TEST_EQUAL( boost::simd::Zero<char>()   , static_cast<char>(   0) );
  NT2_TEST_EQUAL( boost::simd::One<char>()    , static_cast<char>(   1) );
  NT2_TEST_EQUAL( boost::simd::Two<char>()    , static_cast<char>(   2) );
  NT2_TEST_EQUAL( boost::simd::Three<char>()  , static_cast<char>(   3) );
  NT2_TEST_EQUAL( boost::simd::Four<char>()   , static_cast<char>(   4) );
  NT2_TEST_EQUAL( boost::simd::Five<char>()   , static_cast<char>(   5) );
  NT2_TEST_EQUAL( boost::simd::Six<char>()    , static_cast<char>(   6) );
  NT2_TEST_EQUAL( boost::simd::Seven<char>()  , static_cast<char>(   7) );
  NT2_TEST_EQUAL( boost::simd::Eight<char>()  , static_cast<char>(   8) );
  NT2_TEST_EQUAL( boost::simd::Nine<char>()   , static_cast<char>(   9) );
  NT2_TEST_EQUAL( boost::simd::Ten<char>()    , static_cast<char>(  10) );
}

////////////////////////////////////////////////////////////////////////////////
// Test integral_constant for every base types
////////////////////////////////////////////////////////////////////////////////
NT2_TEST_CASE_TPL( integral_constant, BOOST_SIMD_INTEGRAL_TYPES )
{
  NT2_TEST_EQUAL( (boost::simd::integral_constant<T,42>()), static_cast<T>(42) );
}

////////////////////////////////////////////////////////////////////////////////
// Test integral_constant for raw 'char'
////////////////////////////////////////////////////////////////////////////////
NT2_TEST_CASE( char_integral_constant )
{
  NT2_TEST_EQUAL( (boost::simd::integral_constant<char,65>()), 'A' );
}


/*******************************************************************************
 * Copyright 2013-2014 Sebastian Niemann <niemann@sra.uni-hannover.de>.
 *
 * Licensed under the MIT License (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://opensource.org/licenses/MIT
 *
 * Developers:
 *   Sebastian Niemann - Lead developer
 *   Daniel Kiechle - Unit testing
 ******************************************************************************/
#include <Expected.hpp>
using armadilloJava::Expected;

#include <iostream>
using std::cout;
using std::endl;

#include <utility>
using std::pair;

#include <armadillo>
using arma::Mat;
using arma::span;

#include <InputClass.hpp>
using armadilloJava::InputClass;

#include <Input.hpp>
using armadilloJava::Input;

namespace armadilloJava {
  class ExpectedInPlaceGenMatRowIndRangeColIndRangeGenMat : public Expected {
    public:
      ExpectedInPlaceGenMatRowIndRangeColIndRangeGenMat() {
        cout << "Compute ExpectedInPlaceGenMatRowIndRangeColIndRangeGenMat(): " << endl;

          vector<vector<pair<string, void*>>> inputs = Input::getTestParameters({
            InputClass::GenMat,
            InputClass::RowIndRange,
            InputClass::ColIndRange,
            InputClass::GenMat
          });

          for (vector<pair<string, void*>> input : inputs) {
            _fileSuffix = "";

            int n = 0;
            for (pair<string, void*> value : input) {
              switch (n) {
                case 0:
                  _fileSuffix += value.first;
                  _genMatA = *static_cast<Mat<double>*>(value.second);
                  break;
                case 1:
                  _fileSuffix += "," + value.first;
                  _rowIndRange = *static_cast<span*>(value.second);
                  break;
                case 2:
                  _fileSuffix += "," + value.first;
                  _colIndRange = *static_cast<span*>(value.second);
                  break;
                case 3:
                  _fileSuffix += "," + value.first;
                  _genMatB = *static_cast<Mat<double>*>(value.second);
                  break;
              }
              ++n;
            }

            cout << "Using input: " << _fileSuffix << endl;

            _copyOfGenMatA = _genMatA;
            _copyOfRowIndRange = _rowIndRange;
            _copyOfIndRange = _colIndRange;
            _copyOfGenMatB = _genMatB;

            expectedMatSubmatEqual();

            _genMatA = _copyOfGenMatA;
            _rowIndRange = _copyOfRowIndRange;
            _colIndRange = _copyOfIndRange;
            _genMatB = _copyOfGenMatB;
            expectedMatSubmatPlus();

            _genMatA = _copyOfGenMatA;
            _rowIndRange = _copyOfRowIndRange;
            _colIndRange = _copyOfIndRange;
            _genMatB = _copyOfGenMatB;
            expectedMatSubmatMinus();

            _genMatA = _copyOfGenMatA;
            _rowIndRange = _copyOfRowIndRange;
            _colIndRange = _copyOfIndRange;
            _genMatB = _copyOfGenMatB;
            expectedMatSubmatElemTimes();

            _genMatA = _copyOfGenMatA;
            _rowIndRange = _copyOfRowIndRange;
            _colIndRange = _copyOfIndRange;
            _genMatB = _copyOfGenMatB;
            expectedMatSubmatElemDivide();
          }

          cout << "done." << endl;
        }

    protected:
      Mat<double> _genMatA;
      Mat<double> _copyOfGenMatA;

      span _rowIndRange;
      span _copyOfRowIndRange;

      span _colIndRange;
      span _copyOfIndRange;

      Mat<double> _genMatB;
      Mat<double> _copyOfGenMatB;

      void expectedMatSubmatEqual() {
        if(!_genMatA.in_range(_rowIndRange, _colIndRange)) {
          return;
        }

        if(!_rowIndRange.whole) {
          if(_genMatB.n_rows != _rowIndRange.b - _rowIndRange.a + 1) {
            return;
          }
        } else {
          if(_genMatB.n_rows != _genMatA.n_rows) {
            return;
          }
        }

        if(!_colIndRange.whole) {
          if(_genMatB.n_cols != _colIndRange.b - _colIndRange.a + 1) {
            return;
          }
        } else {
          if(_genMatB.n_cols != _genMatA.n_cols) {
            return;
          }
        }

        cout << "- Compute expectedMatSubmatEqual() ... ";

        _genMatA.submat(_rowIndRange, _colIndRange) = _genMatB;
        save<double>("Mat.submatEqual", _genMatA);

        cout << "done." << endl;
      }

      void expectedMatSubmatPlus() {
        if(!_genMatA.in_range(_rowIndRange, _colIndRange)) {
          return;
        }

        if(!_rowIndRange.whole) {
          if(_genMatB.n_rows != _rowIndRange.b - _rowIndRange.a + 1) {
            return;
          }
        } else {
          if(_genMatB.n_rows != _genMatA.n_rows) {
            return;
          }
        }

        if(!_colIndRange.whole) {
          if(_genMatB.n_cols != _colIndRange.b - _colIndRange.a + 1) {
            return;
          }
        } else {
          if(_genMatB.n_cols != _genMatA.n_cols) {
            return;
          }
        }

        cout << "- Compute expectedMatSubmatPlus() ... ";

        _genMatA.submat(_rowIndRange, _colIndRange) += _genMatB;
        save<double>("Mat.submatPlus", _genMatA);

        cout << "done." << endl;
      }

      void expectedMatSubmatMinus() {
        if(!_genMatA.in_range(_rowIndRange, _colIndRange)) {
          return;
        }

        if(!_rowIndRange.whole) {
          if(_genMatB.n_rows != _rowIndRange.b - _rowIndRange.a + 1) {
            return;
          }
        } else {
          if(_genMatB.n_rows != _genMatA.n_rows) {
            return;
          }
        }

        if(!_colIndRange.whole) {
          if(_genMatB.n_cols != _colIndRange.b - _colIndRange.a + 1) {
            return;
          }
        } else {
          if(_genMatB.n_cols != _genMatA.n_cols) {
            return;
          }
        }

        cout << "- Compute expectedMatSubmatMinus() ... ";

        _genMatA.submat(_rowIndRange, _colIndRange) -= _genMatB;
        save<double>("Mat.submatMinus", _genMatA);

        cout << "done." << endl;
      }

      void expectedMatSubmatElemTimes() {
        if(!_genMatA.in_range(_rowIndRange, _colIndRange)) {
          return;
        }

        if(!_rowIndRange.whole) {
          if(_genMatB.n_rows != _rowIndRange.b - _rowIndRange.a + 1) {
            return;
          }
        } else {
          if(_genMatB.n_rows != _genMatA.n_rows) {
            return;
          }
        }

        if(!_colIndRange.whole) {
          if(_genMatB.n_cols != _colIndRange.b - _colIndRange.a + 1) {
            return;
          }
        } else {
          if(_genMatB.n_cols != _genMatA.n_cols) {
            return;
          }
        }

        cout << "- Compute expectedMatSubmatElemTimes() ... ";

        _genMatA.submat(_rowIndRange, _colIndRange) %= _genMatB;
        save<double>("Mat.submatElemTimes", _genMatA);

        cout << "done." << endl;
      }

      void expectedMatSubmatElemDivide() {
        if(!_genMatA.in_range(_rowIndRange, _colIndRange)) {
          return;
        }

        if(!_rowIndRange.whole) {
          if(_genMatB.n_rows != _rowIndRange.b - _rowIndRange.a + 1) {
            return;
          }
        } else {
          if(_genMatB.n_rows != _genMatA.n_rows) {
            return;
          }
        }

        if(!_colIndRange.whole) {
          if(_genMatB.n_cols != _colIndRange.b - _colIndRange.a + 1) {
            return;
          }
        } else {
          if(_genMatB.n_cols != _genMatA.n_cols) {
            return;
          }
        }

        cout << "- Compute expectedMatSubmatElemDivide() ... ";

        _genMatA.submat(_rowIndRange, _colIndRange) /= _genMatB;
        save<double>("Mat.submatElemDivide", _genMatA);

        cout << "done." << endl;
      }
  };
}


#include <boost/numeric/conversion/bounds.hpp>


/** \file
 * nearest_neighbour.cpp
 *
 *  Created on: Mar 25, 2018
 *      Author: itto
 */

#include "nearest_neighbour.h"
#include "Eigen/Core"
#include <boost/log/trivial.hpp>
#include <limits.h>

namespace MouseTrack {

NearestNeighbour::~NearestNeighbour() {}

std::vector<long> NearestNeighbour::operator()(
    const std::vector<std::shared_ptr<const ClusterDescriptor>> &descriptors,
    const std::vector<ClusterChain> &chains) {
  // Prepare an empty vector that will store the index of each chain
  std::vector<long> matchIndex;
  for (size_t i = 0; i < descriptors.size(); i++) {
    if (i % 100 == 0) {
      BOOST_LOG_TRIVIAL(trace) << "Matching descriptor " << i;
    }
    // Initialize a maximum distance and match index
    double nearest = std::numeric_limits<double>::max();
    long match = -1;
    for (size_t j = 0; j < chains.size(); j++) {
      // Check if we already assigned this chain
      if (std::find(matchIndex.begin(), matchIndex.end(), j) ==
          matchIndex.end()) {
        // We are only really concerned with the last cluster.
        // Get the frame number and the descriptor
        auto descriptor = chains[j].descriptors().rbegin();
        // Get the descriptor for that frame.
        auto lastDescriptor = descriptor->second;
        // Compare the descriptor to the cluster. If it's closer than the
        // previous chain then choose that one.
        double distance = descriptors[i]->compare(lastDescriptor.get());
        if (nearest > distance) {
          // Better match than previous chain. Pick that one.
          match = j;
          nearest = distance;
        }
      }
    }
    // Done comparing. Push.
    matchIndex.push_back(match);
  }
  return matchIndex;
};

} // namespace MouseTrack


#include <boost/compute/container/valarray.hpp>


// Copyright Stephan T. Lavavej, http://nuwen.net .
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://boost.org/LICENSE_1_0.txt .

#include "arith.hh"
#include "bwt.hh"
#include "clock.hh"
#include "file.hh"
#include "gluon.hh"
#include "mtf.hh"
#include "test.hh"
#include "typedef.hh"
#include "zle.hh"

#include "external_begin.hh"
    #include <iostream>
    #include <ostream>
    #include <stdexcept>
    #include <string>
    #include <boost/format.hpp>
#include "external_end.hh"

using namespace std;
using namespace boost;
using namespace nuwen;
using namespace nuwen::chrono;
using namespace nuwen::file;

bool test_vector(const vuc_t& v) {
    return unarith(arith(v)) == v;
}

bool test_empty() {
    return test_vector(vuc_t());
}

bool test_rainbow() {
    vuc_t v;

    for (int i = 0; i < 256; ++i) {
        v += cat(vuc_t(i + 10, i));
    }

    return test_vector(v);
}

bool test_huge() {
    return test_vector(vec(cat(vuc_t(1000000, 0x00))(vuc_t(1000000, 0x01))(vuc_t(1000000, 0xFF))));
}

void test_helper(const vuc_t& orig) {
    watch w;
    const vuc_t& a = arith(orig);
    const double arith_time = w.seconds();

    w.reset();
    const vuc_t& unarithed = unarith(a);
    const double unarith_time = w.seconds();

    if (unarithed != orig) {
        throw runtime_error("RUNTIME ERROR: test_helper() - Mangled data.");
    }

    cout << " Original Size: " << orig.size()                          << endl;
    cout << "  Arithed Size: " << a.size()                             << endl;
    cout << " Bits Per Byte: " << 8.0 * a.size() / orig.size()         << endl;
    cout << "  Arith (MB/s): " << orig.size() /   arith_time / 1048576 << endl;
    cout << "Unarith (MB/s): " << orig.size() / unarith_time / 1048576 << endl;
}

bool test_file(const string& filename) {
    const vuc_t orig_file = read_file(filename);

    cout << "[Plain File]" << endl;
    test_helper(orig_file);

    cout << endl;

    vuc_t v = bwt(orig_file);
    mtf2(v);
    v = zle(v);

    cout << "[BWT/MTF-2/ZLEd File]" << endl;
    test_helper(v);

    return true;
}

int main(int argc, char * argv[]) {
    if (argc == 2) {
        cout << format("Triple: (%1%, %2%, %3%)")
            % pham::arith::CODE_VALUE_BITS
            % pham::arith::MAX_FREQUENCY
            % pham::arith::INCREMENT_VALUE << endl << endl;

        NUWEN_TEST("arith1", test_empty())
        NUWEN_TEST("arith2", test_rainbow())
        NUWEN_TEST("arith3", test_huge())
        NUWEN_TEST("arith4", test_file(argv[1]))
    } else {
        cout << "USAGE: arith_test <filename>" << endl;
    }
}