#include <boost/test/unit_test.hpp>

#include <crave/experimental/Coverage.hpp>
#include <crave/experimental/Variable.hpp>

#include <vector>

using namespace crave;

BOOST_FIXTURE_TEST_SUITE(CoverageSampling, Context_Fixture)

struct my_covergroup : public crv_covergroup {
  crv_variable<unsigned> a{"a"};
  crv_variable<unsigned> b{"b"};

  crv_coverpoint cp1{"coverpoint1"};
  crv_coverpoint cp2{"coverpoint2"};

  my_covergroup(crv_object_name) {
    cp1.bins() = {crv_bin(a() == 0, 10), crv_bin(a() == 1, 10), crv_bin(a() == 2, 5)};
    cp2.bins() = {crv_bin(a() == 0, 10), crv_bin(a() == 1, 10), crv_bin(a() == 2, 5)};
  }
};

BOOST_AUTO_TEST_CASE(basic_test) {
  my_covergroup cg{"covergroup1"};

  for (int i = 0; i < 5; i++)
    for (int j = 0; j < 5; j++) {
      cg.a = i % 3;
      cg.b = j * 11 % 20;
      cg.sample();
    }

  BOOST_CHECK(cg.covered());

  crv_object::root()->print_object_hierarchy();
}

BOOST_AUTO_TEST_SUITE_END()  // CoverageSampling

//  vim: ft=cpp:ts=2:sw=2:expandtab


//==================================================================================================
/*!

  Copyright 2016 NumScale SAS

  Distributed under the Boost Software License, Version 1.0.
  (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
//==================================================================================================
#include <boost/simd/function/pack_cast.hpp>
#include <boost/simd/pack.hpp>
#include <simd_test.hpp>
#include <boost/simd/function/enumerate.hpp>

namespace bs = boost::simd;
using bs::pack;

template <typename T, typename Env>
void test_type(Env& runtime)
{
  static const std::size_t N = T::static_size;
  STF_EXPR_IS(bs::pack_cast<std::int8_t  >(T()), (bs::pack<std::int8_t,   N>));
  STF_EXPR_IS(bs::pack_cast<std::int16_t >(T()), (bs::pack<std::int16_t,  N>));
  STF_EXPR_IS(bs::pack_cast<std::int32_t >(T()), (bs::pack<std::int32_t,  N>));
  STF_EXPR_IS(bs::pack_cast<std::int64_t >(T()), (bs::pack<std::int64_t,  N>));
  STF_EXPR_IS(bs::pack_cast<std::uint8_t >(T()), (bs::pack<std::uint8_t,  N>));
  STF_EXPR_IS(bs::pack_cast<std::uint16_t>(T()), (bs::pack<std::uint16_t, N>));
  STF_EXPR_IS(bs::pack_cast<std::uint32_t>(T()), (bs::pack<std::uint32_t, N>));
  STF_EXPR_IS(bs::pack_cast<std::uint64_t>(T()), (bs::pack<std::uint64_t, N>));
  STF_EXPR_IS(bs::pack_cast<float        >(T()), (bs::pack<float        , N>));
  STF_EXPR_IS(bs::pack_cast<double       >(T()), (bs::pack<double       , N>));
}

STF_CASE_TPL( "Check cast return type", STF_NUMERIC_TYPES )
{
  static const std::size_t N = bs::pack<T>::static_size;

  test_type<bs::pack<T, N>>(runtime);
  test_type<bs::pack<T, N/2>>(runtime);
  test_type<bs::pack<T, N*2>>(runtime);
}


#include <fstream>
#include <vector>
#include <cstdlib>
#include <iostream>
#include <armadillo>
using namespace arma;
using namespace std;

mat readQ()
{

  /* read */

    // std::ifstream ifile("Collector/posmat.txt", std::ios::in);
    std::ifstream ifile("Collector/posCollected_cut.txt", std::ios::in);

    std::vector<double> scores;

    //check to see that the file was opened correctly:
    if (!ifile.is_open()) {
        std::cerr << "There was a problem opening the input file!\n";
        exit(1);//exit or do additional error checking
    }

    int DIM = 7;
    double num = 0.0;
    int i = 0;

    //keep storing values from the text file so long as data exists:
    while (ifile >> num) {
        scores.push_back(num);
    }

    mat m(DIM,int(scores.size()/DIM));
    int t=-1;

    for (int i = 0; i < int(scores.size()/DIM); ++i)
    {
      for (int e = 0; e<DIM; e++)
      {
        t++;
        m(e,i) = scores[t] ;
      }
    }

    // //verify that the scores were stored correctly:
    // for (int i = 0; i < int(scores.size()/DIM); ++i) {
    //     for (int e = 0; e<DIM; e++)
    //     {
    //       // std::cout << scores[i+e] << "\t";
    //       std::cout << m(e,i) << std::endl ;
    //     }
    // }

    return m;
}


#define BOOST_TEST_MODULE lue core time clock
#include <boost/test/unit_test.hpp>
#include "lue/core/time.hpp"

BOOST_AUTO_TEST_CASE(seconds)
{
    using namespace lue::data_model::time;

    // Clock with a Unix time epoch and a tick period of 10 seconds
    std::size_t const nr_seconds_per_tick = 10;

    using TickPeriod = TickPeriod<Second>;
    using Clock = Clock<TickPeriod>;

    TickPeriod tick_period(nr_seconds_per_tick);
    Clock clock;

    BOOST_CHECK(clock.epoch().kind() == Epoch::Kind::common_era);
    BOOST_REQUIRE(clock.epoch().origin());
    BOOST_CHECK_EQUAL(*clock.epoch().origin(), "1970-01-01T00:00:00+00:00");
    BOOST_REQUIRE(clock.epoch().calendar());
    BOOST_CHECK(*clock.epoch().calendar() == Calendar::gregorian);
}


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

#include <allegro_flare/random.h>

using namespace allegro_flare;

BOOST_AUTO_TEST_CASE(gets_the_current_seed)
{
   Random number_generator = Random(123);

   BOOST_CHECK_EQUAL(123, number_generator.get_seed());
}

BOOST_AUTO_TEST_CASE(sets_the_current_seed)
{
   Random number_generator = Random(123);
   number_generator.set_seed(456);

   BOOST_CHECK_EQUAL(456, number_generator.get_seed());
}

BOOST_AUTO_TEST_CASE(only_returns_integers_within_the_bounds_inclusive)
{
   Random number_generator = Random(123);
   const int min_random_num = 1;
   const int max_random_num = 3;

   for (int i=0; i<1000; i++)
   {
      int val = number_generator.get_random_int(min_random_num, max_random_num);

      BOOST_CHECK(val <= max_random_num);
      BOOST_CHECK(val >= min_random_num);
   }
}

BOOST_AUTO_TEST_CASE(only_returns_doubles_within_the_bounds_inclusive)
{
   Random number_generator = Random(123);
   const double min_random_num = 1.0;
   const double max_random_num = 3.0;

   for (int i=0; i<1000; i++)
   {
      double val = number_generator.get_random_double(min_random_num, max_random_num);

      BOOST_CHECK(val <= max_random_num);
      BOOST_CHECK(val >= min_random_num);
   }
}

BOOST_AUTO_TEST_CASE(only_returns_floats_within_the_bounds_inclusive)
{
   Random number_generator = Random(123);
   const float min_random_num = 1.0;
   const float max_random_num = 3.0;

   for (int i=0; i<1000; i++)
   {
      float val = number_generator.get_random_float(min_random_num, max_random_num);

      BOOST_CHECK(val <= max_random_num);
      BOOST_CHECK(val >= min_random_num);
   }
}

BOOST_AUTO_TEST_CASE(returns_an_expected_sequence_of_random_numbers_given_a_seed)
{
   Random number_generator = Random(123456);
   const int min_random_num = 0;
   const int max_random_num = 10;
   std::vector<int> expected_numbers = {1, 10, 2, 1, 8};

   for (int i=0; i<expected_numbers.size(); i++)
   {
      int val = number_generator.get_random_int(min_random_num, max_random_num);

      BOOST_CHECK_EQUAL(expected_numbers[i], val);
   }
}


/*
 *
 * Copyright (c) 2002, 2003 Kresimir Fresl, Toon Knapen and Karl Meerbergen
 *
 * Permission to copy, modify, use and distribute this software
 * for any non-commercial or commercial purpose is granted provided
 * that this license appear on all copies of the software source code.
 *
 * Authors assume no responsibility whatsoever for its use and makes
 * no guarantees about its quality, correctness or reliability.
 *
 * KF acknowledges the support of the Faculty of Civil Engineering,
 * University of Zagreb, Croatia.
 *
 */

#ifndef BOOST_NUMERIC_BINDINGS_TRAITS_UBLAS_VECTOR_AS_MATRIX_H
#define BOOST_NUMERIC_BINDINGS_TRAITS_UBLAS_VECTOR_AS_MATRIX_H

#include <boost/numeric/bindings/traits/config.hpp>

#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS

#ifndef BOOST_UBLAS_HAVE_BINDINGS
#  include <boost/numeric/bindings/traits/ublas_vector.hpp>
#endif
#include <boost/numeric/bindings/traits/matrix_traits.hpp>

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

namespace boost { namespace numeric { namespace bindings { namespace traits {

  // ublas::vector<> treated as matrix (nx1)
  template <typename T, typename ArrT, typename V>
  struct matrix_detail_traits<boost::numeric::ublas::vector<T, ArrT>, V>
  {
#ifndef BOOST_NUMERIC_BINDINGS_NO_SANITY_CHECK
    BOOST_STATIC_ASSERT(
      (boost::is_same<
         boost::numeric::ublas::vector<T, ArrT>,
         typename boost::remove_const<V>::type
       >::value) );
#endif

    typedef boost::numeric::ublas::vector<T, ArrT> identifier_type;
    typedef V matrix_type;
    typedef general_t matrix_structure;
    typedef column_major_t ordering_type;

    typedef T value_type;
    typedef typename detail::generate_const<V,T>::type* pointer;

    static pointer storage (matrix_type& v) {
      typedef typename detail::generate_const<V,ArrT>::type array_type;
      return vector_traits<array_type>::storage (v.data());
    }
    static int size1 (matrix_type& v) { return v.size(); }
    static int size2 (matrix_type&) { return 1; }
    static int storage_size (matrix_type& v) { return v.size(); }
    static int leading_dimension (matrix_type& v) { return v.size(); }
  };

  // ublas::vector_range<> treated as matrix (nx1)
  template <typename T, typename V>
  struct matrix_detail_traits<boost::numeric::ublas::vector_range<T>, V>
  {
#ifndef BOOST_NUMERIC_BINDINGS_NO_SANITY_CHECK
    BOOST_STATIC_ASSERT(
      (boost::is_same<
         boost::numeric::ublas::vector_range<T>,
         typename boost::remove_const<V>::type
       >::value) );
#endif

    typedef boost::numeric::ublas::vector_range<T> identifier_type;
    typedef V matrix_type;
    typedef general_t matrix_structure;
    typedef column_major_t ordering_type;

    typedef typename T::value_type value_type;
    typedef typename detail::generate_const<V,value_type>::type* pointer;

    static pointer storage (matrix_type& v) {
      return vector_traits<V>::storage (v);
    }
    static int size1 (matrix_type& v) { return v.size(); }
    static int size2 (matrix_type&) { return 1; }
    static int storage_size (matrix_type& v) { return v.size(); }
    static int leading_dimension (matrix_type& v) { return v.size(); }
  };

#ifndef BOOST_NUMERIC_BINDINGS_FORTRAN

  // (undocumented) ublas::c_vector<>
  template <typename T, std::size_t N, typename V>
  struct matrix_detail_traits<boost::numeric::ublas::c_vector<T,N>, V>
  {
#ifndef BOOST_NUMERIC_BINDINGS_NO_SANITY_CHECK
    BOOST_STATIC_ASSERT(
      (boost::is_same<
         boost::numeric::ublas::c_vector<T,N>,
         typename boost::remove_const<V>::type
       >::value) );
#endif

    typedef boost::numeric::ublas::c_vector<T,N> identifier_type;
    typedef V matrix_type;
    typedef general_t matrix_structure;
    typedef row_major_t ordering_type; // consistent with c_matrix<>

    typedef T value_type;
    typedef typename detail::generate_const<V,T>::type* pointer;

    static pointer storage (matrix_type& v) { return v.data(); }
    static int size1 (matrix_type&) { return 1; }
    static int size2 (matrix_type& v) { return v.size(); }
    static int storage_size (matrix_type&) { return N; }
    static int leading_dimension (matrix_type&) { return N; }
  };

#endif // BOOST_NUMERIC_BINDINGS_FORTRAN

}}}}

#else // BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS

#error with your compiler ublas::vector<> cannot be used as matrix

#endif // BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS

#endif // BOOST_NUMERIC_BINDINGS_TRAITS_UBLAS_VECTOR_AS_MATRIX_H


#include "kernel_debrun_spiky.hpp"

#include "kernel_test.hpp"

#include <boost/test/unit_test.hpp>

using namespace GooBalls;
using namespace d2;
using namespace Physics;

namespace utf = boost::unit_test;

using KKernel = DebrunSpiky;

BOOST_AUTO_TEST_CASE(debrun_spiky_zero_border_1d, *utf::tolerance(0.0001)){
    KKernel k;
    testZeroBorder1d(k);
}

BOOST_AUTO_TEST_CASE(debrun_spiky_normalization_1d, *utf::tolerance(0.0001)){
    KKernel k;
    testNormalization1d(k, 1000);
}

BOOST_AUTO_TEST_CASE(debrun_spiky_zero_border_gradient_1d, *utf::tolerance(0.0001)){
    KKernel k;
    testZeroBorderGradient1d(k);
}

BOOST_AUTO_TEST_CASE(debrun_spiky_grad_finite_diff_1d, *utf::tolerance(0.01)){
    KKernel k;
    testGradientFiniteDifference1d(k, 100);
}

BOOST_AUTO_TEST_CASE(debrun_spiky_lap_grad_finite_diff_1d, *utf::tolerance(0.0001)){
    KKernel k;
    testLaplacianFromGradientFiniteDifferences1d(k, 100);
}

BOOST_AUTO_TEST_CASE(debrun_spiky_lap_finite_diff_1d, *utf::tolerance(0.00001)){
    KKernel k;
    testLaplacianFiniteDifference1d(k, 100);
}

BOOST_AUTO_TEST_CASE(debrun_spiky_zero_border, *utf::tolerance(0.0001)){
    KKernel k;
    testZeroBorder(k, 100);
}

BOOST_AUTO_TEST_CASE(debrun_spiky_zero_border_gradient, *utf::tolerance(0.0001)){
    KKernel k;
    testZeroBorderGradient(k, 100);
}

BOOST_AUTO_TEST_CASE(debrun_spiky_normalization, *utf::tolerance(0.0001)){
    KKernel k;
    testNormalization(k, 1000);
}

BOOST_AUTO_TEST_CASE(debrun_spiky_monotonicity, *utf::tolerance(0.0001)){
    KKernel k;
    testMonotonicity(k, 100);
}

BOOST_AUTO_TEST_CASE(debrun_spiky_non_negativity){
    KKernel k;
    testNonNegativity(k, 100);
}

BOOST_AUTO_TEST_CASE(debrun_spiky_radial_symmetric){
    KKernel k;
    testRadialSymmetry(k, 100);
}

BOOST_AUTO_TEST_CASE(debrun_spiky_grad_finite_diff, *utf::tolerance(0.01)){
    KKernel k;
    testGradientFiniteDifference(k, 100);
}

BOOST_AUTO_TEST_CASE(debrun_spiky_lap_grad_finite_diff, *utf::tolerance(0.011)){
    KKernel k;
    testLaplacianFromGradientFiniteDifferences(k, 100);
}

BOOST_AUTO_TEST_CASE(debrun_spiky_lap_finite_diff, *utf::tolerance(0.01)){
    KKernel k;
    testLaplacianFiniteDifference(k, 100);
}


#ifndef PIXVEC_VTK_CURVE_WIRTER_IS_INCLUDED
#define PIXVEC_VTK_CURVE_WIRTER_IS_INCLUDED

#include <Eigen/Core>
#include <string>
#include <vector>

namespace polyvec {

class VtkCurveWriter {
public:

    void add_line ( const Eigen::Vector2d&, const Eigen::Vector2d& );
    void add_polyline ( const Eigen::Matrix2Xd&, const bool is_close=false );
    void add_point ( const Eigen::Vector2d& );
    void dump ( const std::string );
    void clear();

private:
    template<typename DataType>
    using EigenVector = std::vector<DataType, Eigen::aligned_allocator<DataType>>;

    EigenVector<Eigen::Matrix2Xd> _lines;
    EigenVector<Eigen::Vector2d> _points;
};

} // end of polyvec

#endif /* PIXVEC_VTK_CURVE_WIRTER_IS_INCLUDED */


// File: insert.cpp

#include <iostream>
#include <boost/numeric/mtl/mtl.hpp>

using namespace mtl;

template <typename Matrix>
void fill(Matrix& m)
{
    // Matrices are not initialized by default
    m= 0.0;

    // Create inserter for matrix m
    mat::inserter<Matrix> ins(m);

    // Insert value in m[0][0]
    ins[0][0] << 2.0;
    ins[1][2] << 0.5;
    ins[2][1] << 3.0;

    // Destructor of ins sets final state of m
}

template <typename Matrix>
void modify(Matrix& m)
{
    // Type of m's elements
    typedef typename Collection<Matrix>::value_type value_type;

    // Create inserter for matrix m
    // Existing values are not overwritten but inserted
    mat::inserter<Matrix, update_plus<value_type> > ins(m, 3);

    // Increment value in m[0][0]
    ins[0][0] << 1.0;

    // Elements that doesn't exist (in sparse matrices) are inserted
    ins[1][1] << 2.5;
    ins[2][1] << 1.0;
    ins[2][2] << 4.0;

    // Destructor of ins sets final state of m
}

int main(int, char**)
{
    // Matrices of different types
    compressed2D<double>              A(3, 3);
    dense2D<double>                   B(3, 3);
    morton_dense<float, morton_mask>  C(3, 3);

    // Fill the matrices generically
    fill(A); fill(B); fill(C);
    std::cout << "A is \n" << A << "\nB is \n" << B << "\nC is \n" << C;

    // Modify the matrices generically
    modify(A); modify(B); modify(C);
    std::cout << "\n\nAfter modification:\nA is \n" << A
	      << "\nB is \n" << B << "\nC is \n" << C;

    return 0;
}


/*
 * NullConstraint.cpp
 * @brief NullConstraint constraint
 * @date Mar 20, 2022
 * @author Yoonwoo Kim
 */

#include <gtsam/base/Testable.h>
#include <gtsam/discrete/DecisionTreeFactor.h>
#include <cpp/planning/NullConstraint.h>
#include <cpp/planning/BinarySameConstraint.h>

#include <boost/make_shared.hpp>
using namespace gtsam;
using namespace std;

namespace gtsam_planner {

/* ************************************************************************* */
NullConstraint::NullConstraint(const DiscreteKeys& dkeys)
  : DiscreteFactor(dkeys.indices()) {
  dkeys_ = dkeys;
  for (const DiscreteKey& dkey : dkeys) cardinalities_.insert(dkey);
  for (size_t i = 0; i < dkeys.size(); i++) {
    if (i < dkeys.size()/2) dkeys_t_.push_back(dkeys[i]);
    else dkeys_tp_.push_back(dkeys[i]);
  }
}

/* ************************************************************************* */
void NullConstraint::print(const string& s, const KeyFormatter& formatter) const {
  cout << s << "NullConstraint on ";
  for (Key dkey : keys_) cout << formatter(dkey) << " ";
  cout << endl;
}

/* ************************************************************************* */
DiscreteKeys NullConstraint::discreteKeys() const {
  return dkeys_;
}

/* ************************************************************************* */
double NullConstraint::operator()(const DiscreteValues& values) const {
  for (size_t i = 0; i < dkeys_t_.size(); i++) {
    if ((values.count(dkeys_t_[i].first) != 0) && (values.count(dkeys_tp_[i].first) != 0)) {
      if (values.at(dkeys_t_[i].first) != values.at(dkeys_tp_[i].first)) return 0.0;
    }
  }
  return 1.0;
}

/* ************************************************************************* */
DecisionTreeFactor NullConstraint::toDecisionTreeFactor() const {
  DecisionTreeFactor converted;
  size_t nrKeys = dkeys_.size();
  for (size_t i=0; i<dkeys_t_.size(); i++) {
    BinarySameConstraint bsame(dkeys_t_[i], dkeys_tp_[i]);
    converted = converted * bsame.toDecisionTreeFactor();
  }
  return converted;
}

/* ************************************************************************* */
DecisionTreeFactor NullConstraint::operator*(const DecisionTreeFactor& f) const {
  // TODO: can we do this more efficiently?
  return toDecisionTreeFactor() * f;
}

}  // namespace gtsam_planner


//  Copyright John Maddock 2012.
//  Use, modification and distribution are subject to 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)

//
// This tests that cpp_dec_float_50 meets our
// conceptual requirements when used with Boost.Math.
//
#ifdef _MSC_VER
#  define _SCL_SECURE_NO_WARNINGS
#  pragma warning(disable:4800)
#  pragma warning(disable:4512)
#  pragma warning(disable:4127)
#  pragma warning(disable:4512)
#  pragma warning(disable:4503) // decorated name length exceeded, name was truncated
#endif

#if !defined(TEST_MPF_50) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) \
   && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR_50)\
   && !defined(TEST_MPFR_6) && !defined(TEST_MPFR_15) && !defined(TEST_MPFR_17) && !defined(TEST_MPFR_30) && !defined(TEST_CPP_DEC_FLOAT_NO_ET)
#  define TEST_MPF_50
#  define TEST_BACKEND
#  define TEST_MPZ
#  define TEST_MPFR_50
#  define TEST_MPFR_6
#  define TEST_MPFR_15
#  define TEST_MPFR_17
#  define TEST_MPFR_30
#  define TEST_CPP_DEC_FLOAT
#  define TEST_CPP_DEC_FLOAT_NO_ET

#ifdef _MSC_VER
#pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!")
#endif
#ifdef __GNUC__
#pragma warning "CAUTION!!: No backend type specified so testing everything.... this will take some time!!"
#endif

#endif

#if defined(TEST_MPF_50) || defined(TEST_MPZ)
#include <boost/multiprecision/gmp.hpp>
#endif
#ifdef TEST_BACKEND
#include <boost/multiprecision/concepts/mp_number_archetypes.hpp>
#endif
#if defined(TEST_CPP_DEC_FLOAT) || defined(TEST_CPP_DEC_FLOAT_NO_ET)
#include <boost/multiprecision/cpp_dec_float.hpp>
#endif
#if defined(TEST_MPFR_50) || defined(TEST_MPFR_6) || defined(TEST_MPFR_15) || defined(TEST_MPFR_17) || defined(TEST_MPFR_30)
#include <boost/multiprecision/mpfr.hpp>
#endif

#include <boost/math/special_functions.hpp>

template <class T>
void test_extra(T)
{
   T v1, v2, v3;
   int i;
   (boost::math::fpclassify)(v1);
   (boost::math::isfinite)(v1);
   (boost::math::isnormal)(v1);
   (boost::math::isnan)(v1);
   (boost::math::isinf)(v1);
   (boost::math::signbit)(v1);
   (boost::math::copysign)(v1, v2);
   (boost::math::changesign)(v1);
   (boost::math::sign)(v1);
   boost::math::log1p(v1);
   boost::math::expm1(v1);
   boost::math::cbrt(v1);
   boost::math::sqrt1pm1(v1);
   boost::math::powm1(v1, v2);
   boost::math::hypot(v1, v2);
   boost::math::sinc_pi(v1);
   boost::math::sinhc_pi(v1);
   boost::math::asinh(v1);
   boost::math::acosh(v1);
   boost::math::atanh(v1);
   boost::math::sin_pi(v1);
   boost::math::cos_pi(v1);
   boost::math::trunc(v1);
   boost::math::itrunc(v1);
   boost::math::ltrunc(v1);
   boost::math::round(v1);
   boost::math::iround(v1);
   boost::math::lround(v1);
   boost::math::modf(v1, &v1);
   boost::math::modf(v1, &i);
   long l;
   boost::math::modf(v1, &l);
#ifdef BOOST_HAS_LONG_LONG
   boost::math::lltrunc(v1);
   boost::math::llround(v1);
   boost::long_long_type ll;
   boost::math::modf(v1, &ll);
#endif
   boost::math::pow<2>(v1);
   boost::math::nextafter(v1, v1);
   boost::math::float_next(v1);
   boost::math::float_prior(v1);
   boost::math::float_distance(v1, v1);
   // Misc functions that don't fit elsewhere:
   boost::math::expint(v1);
   boost::math::expint(i);
   boost::math::expint(i, v2);
   boost::math::expint(i, i);
   boost::math::zeta(v1);
   boost::math::zeta(i);
   boost::math::owens_t(v1, v2);
}

void foo()
{
#ifdef TEST_BACKEND
   test_extra(boost::multiprecision::concepts::mp_number_float_architype());
#endif
#ifdef TEST_MPF_50
   test_extra(boost::multiprecision::mpf_float_50());
#endif
#ifdef TEST_MPFR_50
   test_extra(boost::multiprecision::mpfr_float_50());
#endif
#ifdef TEST_MPFR_6
   test_extra(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<6> >());
#endif
#ifdef TEST_MPFR_15
   test_extra(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<15> >());
#endif
#ifdef TEST_MPFR_17
   test_extra(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<17> >());
#endif
#ifdef TEST_MPFR_30
   test_extra(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<30> >());
#endif
#ifdef TEST_CPP_DEC_FLOAT
   test_extra(boost::multiprecision::cpp_dec_float_50());
#endif
#ifdef TEST_CPP_DEC_FLOAT_NO_ET
   test_extra(boost::multiprecision::number<boost::multiprecision::cpp_dec_float<100>, boost::multiprecision::et_off>());
#endif
}

int main()
{
   foo();
}


#include <bits/stdc++.h>
#include <boost/algorithm/string.hpp>
#include <boost/multi_array.hpp>
#include <boost/optional.hpp>
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/range/irange.hpp>
#include <atcoder/all>
using namespace std;
using namespace atcoder;
namespace adaptor = boost::adaptors;
// clang-format off
#pragma GCC target("avx")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#define YESNO(bool) if(bool){cout<<"YES"<<endl;}else{cout<<"NO"<<endl;}
#define yesno(bool) if(bool){cout<<"yes"<<endl;}else{cout<<"no"<<endl;}
#define YesNo(bool) if(bool){cout<<"Yes"<<endl;}else{cout<<"No"<<endl;}
using ui = unsigned int;
using ll = long long;
template <typename T> inline T getvalue(){T r;string s;getline(cin, s);istringstream(s)>>r;return r;}
template <typename T> inline vector<T> getvalues(){vector<T> v;T r;string s;getline(cin,s);istringstream iss(s);while(iss>>r){v.push_back(r);}return v;}
template <typename T> inline vector<T> getlines(){vector<T> v;T r;string s;while(getline(cin,s)){istringstream iss(s);iss>>r;v.push_back(r);}return v;}
template <typename T, typename S> inline tuple<T,S> getpair(){T r1;S r2;string s;getline(cin,s);istringstream iss(s);iss>>r1>>r2;return {r1,r2};}
template <typename T,typename S,typename R> inline tuple<T,S,R> gettriple(){T r1;S r2;R r3;string s;getline(cin,s);istringstream iss(s);iss>>r1>>r2>>r3;return {r1,r2,r3};}
template <typename T,typename S,typename R,typename Q> inline tuple<T,S,R,Q> getquad(){T r1;S r2;R r3;Q r4;string s;getline(cin,s);istringstream iss(s);iss>>r1>>r2>>r3>>r4;return {r1,r2,r3,r4};}
template <typename T> inline string join(vector<T>& v,string d){stringstream s;copy(v.begin(),v.end(),ostream_iterator<T>(s,d.c_str()));return s.str();}
vector<int> sieve(int n) {vector<int> r(n+1);iota(r.begin(),r.end(),0);for(int i=2;i*i<=n;++i){if(r[i]<i)continue;for(int j=i*i;j<=n;j+=i)if(r[j]==j)r[j]=i;}return r;}
vector<int> factor(int n) {vector<int> m=sieve(n);vector<int> r;while(n>1){r.push_back(m[n]);n/=m[n];}return r;}
template <typename T> inline bool chmin(T& a, const T& b){bool compare=a>b;if(a>b)a=b;return compare;}
template <typename T> inline bool chmax(T& a, const T& b){bool compare=a<b;if(a<b)a=b;return compare;}
// clang-format on

void logic()
{
    auto abc = getvalues<int>();
    sort(abc.begin(), abc.end());
    cout << abc[1] + abc[2] << "\n";
}

int main()
{
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(15);
    logic();
    return 0;
}


#include "count_objective_function_task.h"

#include <stdexcept>

#ifdef BUILD_WITH_MPI

#include <boost/mpi.hpp>
#include <k52/parallel/mpi/constants.h>
#include <k52/parallel/mpi/identifyable_objects_manager.h>

#endif

#include "objective_function_task_result.h"

namespace k52
{
namespace optimization
{

CountObjectiveFunctionTask::CountObjectiveFunctionTask()
    : function_to_optimize_(NULL)
    , parameters_(NULL)
    , was_created_(false)
{}

CountObjectiveFunctionTask::CountObjectiveFunctionTask(
    const IParameters*  parameters,
    const IObjectiveFunction* function_to_optimize)
    : function_to_optimize_(function_to_optimize)
    , parameters_(parameters)
    , was_created_(true) {}

#ifdef BUILD_WITH_MPI

k52::parallel::mpi::IMpiTaskResult::shared_ptr CountObjectiveFunctionTask::CreateEmptyResult() const
{
    return ObjectiveFunctionTaskResult::shared_ptr ( new ObjectiveFunctionTaskResult() );
}

CountObjectiveFunctionTask* CountObjectiveFunctionTask::Clone() const
{
    CountObjectiveFunctionTask* clone = NULL;
    if(was_created_)
    {
        clone = new CountObjectiveFunctionTask(parameters_, function_to_optimize_);
    }
    else
    {
        clone = new CountObjectiveFunctionTask();
        if(received_function_ != NULL)
        {
            clone->received_function_ = IObjectiveFunction::shared_ptr( received_function_->Clone() );
        }
        if(received_parameters_ != NULL)
        {
            clone->received_parameters_ = IParameters::shared_ptr( received_parameters_->Clone() );
        }
    }
    return clone;
}

void CountObjectiveFunctionTask::Send(boost::mpi::communicator* communicator, int target) const
{
    communicator->send(target, k52::parallel::mpi::constants::kCommonTag, k52::parallel::mpi::IdentifyableObjectsManager::GetId(*get_objective_function()));
    communicator->send(target, k52::parallel::mpi::constants::kCommonTag, k52::parallel::mpi::IdentifyableObjectsManager::GetId(*get_parameters()));
    get_parameters()->Send(communicator, target);
}

void CountObjectiveFunctionTask::Receive(boost::mpi::communicator* communicator, int source)
{
    std::string objective_function_id;
    communicator->recv(source, k52::parallel::mpi::constants::kCommonTag, objective_function_id);
    const IObjectiveFunction* function_to_optimize = dynamic_cast<const IObjectiveFunction*>( k52::parallel::mpi::IdentifyableObjectsManager::Instance().GetObject(objective_function_id) );
    if (!function_to_optimize)
    {
        throw std::runtime_error("Unexpected function object received");
    }
    received_function_ = IObjectiveFunction::shared_ptr( function_to_optimize->Clone() );

    std::string parameters_id;
    communicator->recv(source, k52::parallel::mpi::constants::kCommonTag, parameters_id);
    const IParameters* parameters = dynamic_cast<const IParameters*>( k52::parallel::mpi::IdentifyableObjectsManager::Instance().GetObject(parameters_id) );
    if (!parameters)
    {
        throw std::runtime_error("Unexpected parameters object received");
    }
    received_parameters_ = IParameters::shared_ptr( parameters->Clone() );
    received_parameters_->Receive(communicator, source);
}

k52::parallel::mpi::IMpiTaskResult* CountObjectiveFunctionTask::Perform() const

#else

k52::parallel::ITaskResult* CountObjectiveFunctionTask::Perform() const

#endif
{
    double value = get_objective_function()->operator ()( get_parameters() );
    ObjectiveFunctionTaskResult* result = new ObjectiveFunctionTaskResult();
    result->set_objective_function_value(value);
    return result;
}

const IObjectiveFunction* CountObjectiveFunctionTask::get_objective_function() const
{
    if(was_created_)
    {
        return function_to_optimize_;
    }
    else
    {
        return received_function_.get();
    }
}

const IParameters* CountObjectiveFunctionTask::get_parameters() const
{
    if(was_created_)
    {
        return parameters_;
    }
    else
    {
        return received_parameters_.get();
    }
}

}/* namespace optimization */
}/* namespace k52 */


/*
 * use.cpp
 *
 *  Created on: Mar 26, 2012
 *      Author: david
 */

#include <Slimage/Slimage.hpp>
#include <boost/assert.hpp>
#include <iostream>
#include <map>
#include <set>
#include <cmath>
#include <vector>
#include <numeric>

//#define DASP_DEBUG_GUI

#ifdef DASP_DEBUG_GUI
 #include <Slimage/Gui.hpp>
#endif

namespace dasp {
namespace eval {

std::vector<std::pair<int,int>> UndersegmentationErrorImpl(const slimage::Image1i& labels_relevant, const slimage::Image1i& labels_retrieved)
{
	constexpr float GAMMA = 0.05f;
	BOOST_ASSERT(labels_relevant.dimensions() == labels_retrieved.dimensions());
	// area of labels
	std::map<int, unsigned int> retrieved_area;
	std::map<int, unsigned int> relevant_area;
	// given relevant label: store how often each retrieved labels occurrs
	std::map<int, std::map<int,unsigned int> > label_intersection;
	unsigned int total_retrieved = 0;
	// generate data
	for(unsigned int i=0; i<labels_relevant.size(); i++) {
		int label_retrieved = labels_retrieved[i];
		int label_relevant = labels_relevant[i];
		total_retrieved ++;
		retrieved_area[label_retrieved] ++;
		relevant_area[label_relevant] ++;
		label_intersection[label_relevant][label_retrieved] ++;
	}
	// compute error
	std::vector<std::pair<int,int>> error;
	for(auto it=label_intersection.begin(); it!=label_intersection.end(); ++it) {
#ifdef DASP_DEBUG_GUI
		std::cout << "Relevant label " << it->first << std::endl;
#endif
		// sum up the area of all retreived labels which intersect the relevant label
		unsigned int common_area = 0;
		for(auto p : it->second) {
			// total area of retreived label
			// treat unassigned pixels as own label for each relevant label
			unsigned int area_retrieved = (p.first == -1) ? p.second : retrieved_area[p.first];
			// area of intersection of relevant and retrieved label
			unsigned int area_intersect = p.second;
			// only count if overlap is big enough with respect to retreived segment size
			float percentage = static_cast<float>(area_intersect)/static_cast<float>(area_retrieved);
			if(percentage > GAMMA)
				common_area += area_retrieved;
		}
#ifdef DASP_DEBUG_GUI
		std::cout << "label=" << it->first << ", A_g=" << g_area << ", S_g=" << s_area << ", error=" << q << std::endl;
#endif
		error.push_back({
			static_cast<int>(common_area),
			static_cast<int>(relevant_area[it->first])
		});
	}

#ifdef DASP_DEBUG_GUI
	{
		for(auto p : relevant_superpixel_labels) {
			slimage::Image3ub vis(labels_relevant.dimensions(), slimage::Pixel3ub{{0,0,0}});
			unsigned int label = p.first;
			std::set<int> ids = p.second;
			for(unsigned int i=0; i<vis.size(); i++) {
				bool is_ground = (labels_relevant[i] == label);
				bool is_super = (ids.find(labels_retrieved[i]) != ids.end());
				if(is_ground && is_super) {
					vis[i] = slimage::Pixel3ub{{255,255,255}};
				}
				else if(is_ground) {
					vis[i] = slimage::Pixel3ub{{255,0,0}};
				}
				else if(is_super) {
					vis[i] = slimage::Pixel3ub{{0,128,255}};
				}
			}
			std::cout << "label=" << label << std::endl;
			slimage::gui::Show("undersegmentation error", vis);
			slimage::gui::WaitForKeypress();
		}
	}
#endif

	return error;
}

float UndersegmentationError(const slimage::Image1i& labels_relevant, const slimage::Image1i& labels_retrieved)
{
	std::vector<std::pair<int,int>> error = UndersegmentationErrorImpl(labels_relevant, labels_retrieved);
#ifdef DASP_DEBUG_GUI
	std::cout << "USE: " << std::endl;
	for(auto p : error) {
		std::cout << p.first << " / " << p.second << std::endl;
	}
#endif
	float total1 = std::accumulate(error.begin(), error.end(), 0.0f,
		[](float a, const std::pair<int,int>& p) { return a + p.first; });
	float total2 = std::accumulate(error.begin(), error.end(), 0.0f,
		[](float a, const std::pair<int,int>& p) { return a + p.second; });
	return total1 / total2 - 1.0f;
}

}}


//  Copyright Thijs van den Berg, 2008.
//  Copyright John Maddock 2008.
//  Copyright Paul A. Bristow 2008.

//  Use, modification and distribution are subject to 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)

// This module implements the Laplace distribution.
// Weisstein, Eric W. "Laplace Distribution." From MathWorld--A Wolfram Web Resource.
// http://mathworld.wolfram.com/LaplaceDistribution.html
// http://en.wikipedia.org/wiki/Laplace_distribution
//
// Abramowitz and Stegun 1972, p 930
// http://www.math.sfu.ca/~cbm/aands/page_930.htm

#ifndef BOOST_STATS_LAPLACE_HPP
#define BOOST_STATS_LAPLACE_HPP

#include <boost/math/distributions/detail/common_error_handling.hpp>
#include <boost/math/distributions/complement.hpp>
#include <boost/math/constants/constants.hpp>
#include <limits>

namespace boost{ namespace math{

template <class RealType = double, class Policy = policies::policy<> >
class laplace_distribution
{
public:
   // ----------------------------------
   // public Types
   // ----------------------------------
   typedef RealType value_type;
   typedef Policy policy_type;

   // ----------------------------------
   // Constructor(s)
   // ----------------------------------
   laplace_distribution(RealType location = 0, RealType scale = 1)
      : m_location(location), m_scale(scale)
   {
      RealType result;
      check_parameters("boost::math::laplace_distribution<%1%>::laplace_distribution()", &result);
   }

   // ----------------------------------
   // Public functions
   // ----------------------------------

   RealType location() const
   {
      return m_location;
   }

   RealType scale() const
   {
      return m_scale;
   }

   bool check_parameters(const char* function, RealType* result) const
   {
         if(false == detail::check_scale(function, m_scale, result, Policy())) return false;
         if(false == detail::check_location(function, m_location, result, Policy())) return false;
         return true;
   }

private:
   RealType m_location;
   RealType m_scale;

}; // class laplace_distribution

//
// Convenient type synonym
//
typedef laplace_distribution<double> laplace;

//
// Non member functions
//
template <class RealType, class Policy>
inline const std::pair<RealType, RealType> range(const laplace_distribution<RealType, Policy>&)
{
   using boost::math::tools::max_value;
   return std::pair<RealType, RealType>(-max_value<RealType>(), max_value<RealType>());
}

template <class RealType, class Policy>
inline const std::pair<RealType, RealType> support(const laplace_distribution<RealType, Policy>&)
{
   using boost::math::tools::max_value;
   return std::pair<RealType, RealType>(-max_value<RealType>(),  max_value<RealType>());
}

template <class RealType, class Policy>
inline RealType pdf(const laplace_distribution<RealType, Policy>& dist, const RealType& x)
{
   BOOST_MATH_STD_USING // for ADL of std functions

   // Checking function argument
   RealType result;
   const char* function = "boost::math::pdf(const laplace_distribution<%1%>&, %1%))";
   if (false == dist.check_parameters(function, &result)) return result;
   if (false == detail::check_x(function, x, &result, Policy())) return result;

   // Special pdf values
   if((boost::math::isinf)(x))
      return 0; // pdf + and - infinity is zero.

   // General case
   RealType scale( dist.scale() );
   RealType location( dist.location() );

   RealType exponent = x - location;
   if (exponent>0) exponent = -exponent;
   exponent /= scale;

   result = exp(exponent);
   result /= 2 * scale;

   return result;
} // pdf

template <class RealType, class Policy>
inline RealType cdf(const laplace_distribution<RealType, Policy>& dist, const RealType& x)
{
   BOOST_MATH_STD_USING  // for ADL of std functions

   // Checking function argument
   RealType result;
   const char* function = "boost::math::cdf(const laplace_distribution<%1%>&, %1%)";
   if (false == dist.check_parameters(function, &result)) return result;
   if (false == detail::check_x(function, x, &result, Policy())) return result;

   // Special cdf values
   if((boost::math::isinf)(x))
   {
     if(x < 0) return 0; // -infinity
     return 1; // + infinity
   }

   // General cdf  values
   RealType scale( dist.scale() );
   RealType location( dist.location() );

   if (x < location)
      result = exp( (x-location)/scale )/2;
   else
      result = 1 - exp( (location-x)/scale )/2;

   return result;
} // cdf

template <class RealType, class Policy>
inline RealType quantile(const laplace_distribution<RealType, Policy>& dist, const RealType& p)
{
   BOOST_MATH_STD_USING // for ADL of std functions

   // Checking function argument
   RealType result;
   const char* function = "boost::math::quantile(const laplace_distribution<%1%>&, %1%)";
   if (false == dist.check_parameters(function, &result)) return result;
   if(false == detail::check_probability(function, p, &result, Policy())) return result;

   // extreme values
   if(p == 0) return -std::numeric_limits<RealType>::infinity();
   if(p == 1) return std::numeric_limits<RealType>::infinity();

   // Calculate Quantile
   RealType scale( dist.scale() );
   RealType location( dist.location() );

   if (p - 0.5 < 0.0)
      result = location + scale*log( static_cast<RealType>(p*2) );
   else
      result = location - scale*log( static_cast<RealType>(-p*2 + 2) );

   return result;
} // quantile

template <class RealType, class Policy>
inline RealType cdf(const complemented2_type<laplace_distribution<RealType, Policy>, RealType>& c)
{
   BOOST_MATH_STD_USING // for ADL of std functions

   RealType scale = c.dist.scale();
   RealType location = c.dist.location();
   RealType x = c.param;

   // Checking function argument
   RealType result;
   const char* function = "boost::math::cdf(const complemented2_type<laplace_distribution<%1%>, %1%>&)";
   if(false == detail::check_x(function, x, &result, Policy()))return result;

   // Calculate cdf

   // Special cdf value
   if((boost::math::isinf)(x))
   {
     if(x < 0) return 1; // cdf complement -infinity is unity.
     return 0; // cdf complement +infinity is zero
   }

   // Cdf interval value
   if (-x < location)
      result = exp( (-x-location)/scale )/2;
   else
      result = 1 - exp( (location+x)/scale )/2;

   return result;
} // cdf complement

template <class RealType, class Policy>
inline RealType quantile(const complemented2_type<laplace_distribution<RealType, Policy>, RealType>& c)
{
   BOOST_MATH_STD_USING // for ADL of std functions

   // Calculate quantile
   RealType scale = c.dist.scale();
   RealType location = c.dist.location();
   RealType q = c.param;

   // Checking function argument
   RealType result;
   const char* function = "quantile(const complemented2_type<laplace_distribution<%1%>, %1%>&)";
   if(false == detail::check_probability(function, q, &result, Policy())) return result;

   // extreme values
   if(q == 0) return std::numeric_limits<RealType>::infinity();
   if(q == 1) return -std::numeric_limits<RealType>::infinity();

   if (0.5 - q < 0.0)
      result = location + scale*log( static_cast<RealType>(-q*2 + 2) );
   else
      result = location - scale*log( static_cast<RealType>(q*2) );

   return result;
} // quantile

template <class RealType, class Policy>
inline RealType mean(const laplace_distribution<RealType, Policy>& dist)
{
   return dist.location();
}

template <class RealType, class Policy>
inline RealType standard_deviation(const laplace_distribution<RealType, Policy>& dist)
{
   return constants::root_two<RealType>() * dist.scale();
}

template <class RealType, class Policy>
inline RealType mode(const laplace_distribution<RealType, Policy>& dist)
{
   return dist.location();
}

template <class RealType, class Policy>
inline RealType median(const laplace_distribution<RealType, Policy>& dist)
{
   return dist.location();
}

template <class RealType, class Policy>
inline RealType skewness(const laplace_distribution<RealType, Policy>& /*dist*/)
{
   return 0;
}

template <class RealType, class Policy>
inline RealType kurtosis(const laplace_distribution<RealType, Policy>& /*dist*/)
{
   return 6;
}

template <class RealType, class Policy>
inline RealType kurtosis_excess(const laplace_distribution<RealType, Policy>& /*dist*/)
{
   return 3;
}

} // namespace math
} // namespace boost

// This include must be at the end, *after* the accessors
// for this distribution have been defined, in order to
// keep compilers that support two-phase lookup happy.
#include <boost/math/distributions/detail/derived_accessors.hpp>

#endif // BOOST_STATS_LAPLACE_HPP


//==============================================================================
//         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::dispatch::meta::as_integer"

#include <boost/simd/sdk/config/types.hpp>
#include <boost/dispatch/meta/as_integer.hpp>
#include <boost/type_traits/is_same.hpp>

#include <nt2/sdk/unit/module.hpp>
#include <nt2/sdk/unit/tests/basic.hpp>

////////////////////////////////////////////////////////////////////////////////
// Test that as_integer is correct w/r to original sign
////////////////////////////////////////////////////////////////////////////////
NT2_TEST_CASE(as_integer_native_sign)
{
  using boost::dispatch::meta::as_integer;
  using boost::is_same;

  NT2_TEST( (is_same<as_integer<double  >::type,boost::simd::int64_t >::value ));
  NT2_TEST( (is_same<as_integer<float   >::type,boost::simd::int32_t >::value ));
  NT2_TEST( (is_same<as_integer<boost::simd::int64_t >::type,boost::simd::int64_t >::value ));
  NT2_TEST( (is_same<as_integer<boost::simd::int32_t >::type,boost::simd::int32_t >::value ));
  NT2_TEST( (is_same<as_integer<boost::simd::int16_t >::type,boost::simd::int16_t >::value ));
  NT2_TEST( (is_same<as_integer<boost::simd::int8_t  >::type,boost::simd::int8_t  >::value ));
  NT2_TEST( (is_same<as_integer<boost::simd::uint64_t>::type,boost::simd::uint64_t>::value ));
  NT2_TEST( (is_same<as_integer<boost::simd::uint32_t>::type,boost::simd::uint32_t>::value ));
  NT2_TEST( (is_same<as_integer<boost::simd::uint16_t>::type,boost::simd::uint16_t>::value ));
  NT2_TEST( (is_same<as_integer<boost::simd::uint8_t >::type,boost::simd::uint8_t >::value ));
  NT2_TEST( (is_same<as_integer<bool    >::type,boost::simd::uint8_t >::value ));
}

////////////////////////////////////////////////////////////////////////////////
// Test that as_integer is correct w/r to forced sign
////////////////////////////////////////////////////////////////////////////////
NT2_TEST_CASE(as_integer_native_forced_signed)
{
  using boost::dispatch::meta::as_integer;
  using boost::is_same;
  using namespace boost::simd;

  NT2_TEST( (is_same<as_integer<double  ,unsigned>::type,boost::simd::uint64_t >::value ));
  NT2_TEST( (is_same<as_integer<float   ,unsigned>::type,boost::simd::uint32_t >::value ));
  NT2_TEST( (is_same<as_integer<boost::simd::int64_t ,unsigned>::type,boost::simd::uint64_t >::value ));
  NT2_TEST( (is_same<as_integer<boost::simd::int32_t ,unsigned>::type,boost::simd::uint32_t >::value ));
  NT2_TEST( (is_same<as_integer<boost::simd::int16_t ,unsigned>::type,boost::simd::uint16_t >::value ));
  NT2_TEST( (is_same<as_integer<boost::simd::int8_t  ,unsigned>::type,boost::simd::uint8_t  >::value ));
  NT2_TEST( (is_same<as_integer<boost::simd::uint64_t,unsigned>::type,boost::simd::uint64_t >::value ));
  NT2_TEST( (is_same<as_integer<boost::simd::uint32_t,unsigned>::type,boost::simd::uint32_t >::value ));
  NT2_TEST( (is_same<as_integer<boost::simd::uint16_t,unsigned>::type,boost::simd::uint16_t >::value ));
  NT2_TEST( (is_same<as_integer<boost::simd::uint8_t ,unsigned>::type,boost::simd::uint8_t  >::value ));
  NT2_TEST( (is_same<as_integer<bool    ,unsigned>::type,boost::simd::uint8_t >::value ));
}

////////////////////////////////////////////////////////////////////////////////
// Test that as_integer is correct w/r to forced sign
////////////////////////////////////////////////////////////////////////////////
NT2_TEST_CASE(as_integer_native_forced_unsigned)
{
  using boost::dispatch::meta::as_integer;
  using boost::is_same;
  using namespace boost::simd;

  NT2_TEST( (is_same<as_integer<double  ,signed>::type,boost::simd::int64_t>::value ));
  NT2_TEST( (is_same<as_integer<float   ,signed>::type,boost::simd::int32_t>::value ));
  NT2_TEST( (is_same<as_integer<boost::simd::int64_t ,signed>::type,boost::simd::int64_t>::value ));
  NT2_TEST( (is_same<as_integer<boost::simd::int32_t ,signed>::type,boost::simd::int32_t>::value ));
  NT2_TEST( (is_same<as_integer<boost::simd::int16_t ,signed>::type,boost::simd::int16_t>::value ));
  NT2_TEST( (is_same<as_integer<boost::simd::int8_t  ,signed>::type,boost::simd::int8_t >::value ));
  NT2_TEST( (is_same<as_integer<boost::simd::uint64_t,signed>::type,boost::simd::int64_t>::value ));
  NT2_TEST( (is_same<as_integer<boost::simd::uint32_t,signed>::type,boost::simd::int32_t>::value ));
  NT2_TEST( (is_same<as_integer<boost::simd::uint16_t,signed>::type,boost::simd::int16_t>::value ));
  NT2_TEST( (is_same<as_integer<boost::simd::uint8_t ,signed>::type,boost::simd::int8_t >::value ));
  NT2_TEST( (is_same<as_integer<bool    ,signed>::type,boost::simd::int8_t >::value ));
}


/*
 * Copyright (c) 2011-2021, The DART development contributors
 * All rights reserved.
 *
 * The list of contributors can be found at:
 *   https://github.com/dartsim/dart/blob/master/LICENSE
 *
 * This file is provided under the following "BSD-style" License:
 *   Redistribution and use in source and binary forms, with or
 *   without modification, are permitted provided that the following
 *   conditions are met:
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * 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.
 *   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 HOLDER 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.
 */

#pragma once

#include <map>
#include <vector>

#include <Eigen/Core>

#include "dart/math/TriMesh.hpp"

namespace dart {
namespace math {

/// The class Icosphere represents an icosphere where the subdivision and radius
/// are configurable.
template <typename S_>
class Icosphere : public TriMesh<S_>
{
public:
  // Type aliases
  using S = S_;
  using Base = TriMesh<S>;
  using Index = typename Base::Index;
  using Vector3 = typename Base::Vector3;
  using Triangle = typename Base::Triangle;
  using Vertices = std::vector<Vector3>;
  using Normals = typename Base::Normals;
  using Triangles = std::vector<Triangle>;

  /// Returns the number of vertices of icosphere given subdivisions.
  static std::size_t getNumVertices(std::size_t subdivisions);

  /// Returns the number of edges of icosphere given subdivisions.
  static std::size_t getNumEdges(std::size_t subdivisions);

  /// Returns the number of triangles of icosphere given subdivisions.
  static std::size_t getNumTriangles(std::size_t subdivisions);

  /// Returns vertices and faces of icosahedron given radius.
  static std::pair<Vertices, Triangles> computeIcosahedron(S radius);

  /// Construct an icosphere given radius and subdivisions.
  ///
  /// \param[in] radius: The radius of the icosphere.
  /// \param[in] subdivisions: The number of subdividing an icosahedron. Passing
  /// 1 generates icosahedron without subdividing.
  Icosphere(S radius, std::size_t subdivisions);

  /// Returns the radius of the icosphere.
  S getRadius() const;

  /// Returns the number of subdivisions of the icosphere.
  std::size_t getNumSubdivisions() const;

private:
  /// Internal function to build icosphere given radius and subdivisions.
  void build();

  /// Radius of icosphere.
  S mRadius;

  /// Number of subdividing an icosahedron.
  std::size_t mSubdivisions;
};

using Icospheref = Icosphere<float>;
using Icosphered = Icosphere<double>;

} // namespace math
} // namespace dart

#include "dart/math/detail/Icosphere-impl.hpp"


/**

Copyright (c) 2016, Aumann Florian, Heller Florian, Meißner Pascal
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 copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

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 HOLDER 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 "Transformation/transformationfile_manager_data.h"
#include <iostream>
#include <fstream>
#include <string>
#ifndef Q_MOC_RUN
#include <ros/ros.h>
#include <boost/algorithm/string.hpp>
#endif

using namespace std;

TransformationFile_Manager_Data::TransformationFile_Manager_Data (string filePath) : Abstract_TransformationFile_Manager(filePath) {}

bool TransformationFile_Manager_Data::writeToFile(Transformation_Data data)
{
    ofstream myfile;
    myfile.open (this->filePath, std::ofstream::out | std::ofstream::app);

    Eigen::Affine3d tr(data.PTU_Frame);
    Eigen::Matrix3d rotation = tr.rotation();

    //Eigen::Vector3d angles = rotation.eulerAngles(2, 0, 2);
    Eigen::Vector3d translation(Eigen::Vector3d(data.PTU_Frame(0, 3), data.PTU_Frame(1, 3), data.PTU_Frame(2, 3)));
    //myfile << angles[0] << "; " << angles[1] << "; " << angles[2] << "; " << translation[0] << "; " << translation[1] << "; " << translation[2] << "; ";

    Eigen::Quaterniond quaternion(rotation);

    myfile << quaternion.x() << "; " << quaternion.y() << "; " <<  quaternion.z() << "; " << quaternion.w() << "; " << translation[0] << "; " << translation[1] << "; " << translation[2]<< "; ";

    /*transform = data.PTU_Frame;
    roll  = atan2f(transform(2,0), transform(0,0));
    pitch = asinf(transform(1,0));
    yaw   = atan2f(-transform(1,2), transform(1,1));
    translation = Eigen::Vector3d(transform(3, 0), transform(3, 1), transform(3, 2));
    myfile << roll << " " << pitch << " " << yaw << " " << translation[0] << " " << translation[1] << " " << translation[2] << " ";
*/
    myfile << data.pan << "; " << data.tilt << std::endl;

    myfile.close();

    return true;
}

std::vector<Transformation_Data> TransformationFile_Manager_Data::readFromFile(string filePath)
{
    std::vector<Transformation_Data> output;
    std::ifstream input(filePath);
    std::string line;
    unsigned int lineNumber = 1;
    while(std::getline( input, line ))
    {
        std::vector<std::string> strs;
        boost::split(strs, line, boost::is_any_of(";"));
        if (strs.size() == 9)
        {
            std::vector<double> numericValues;
            bool success = true;
            for (unsigned int i = 0; i < strs.size(); i++)
            {
                try
                {
                    std::string temp = strs.at(i);
                    boost::algorithm::trim(temp);
                    numericValues.push_back(boost::lexical_cast<double>(temp));
                }
                catch (boost::bad_lexical_cast const&)
                {
                    ROS_ERROR_STREAM("Line " << lineNumber << ": " <<strs.at(i) << " is not a number.");
                    success = false;
                    break;
                }
            }
            if (success)
            {
                Eigen::Affine3d rotation(Eigen::Quaterniond(numericValues.at(3),numericValues.at(0),numericValues.at(1),numericValues.at(2)));
                /*Eigen::Affine3d rotation1(Eigen::AngleAxisd(numericValues.at(0), Eigen::Vector3d(0.0,0.0,1.0)));
                Eigen::Affine3d rotation2(Eigen::AngleAxisd(numericValues.at(1), Eigen::Vector3d(1.0,0.0,0.0)));
                Eigen::Affine3d rotation3(Eigen::AngleAxisd(numericValues.at(2), Eigen::Vector3d(0.0,0.0,1.0)));*/
                Eigen::Affine3d translation(Eigen::Translation3d(Eigen::Vector3d(numericValues.at(4),numericValues.at(5),numericValues.at(6))));
                Eigen::Affine3d transformation = translation * rotation;
                Transformation_Data data;
                data.PTU_Frame = transformation.matrix();
                data.pan = numericValues.at(7);
                data.tilt = numericValues.at(8);
                output.push_back(data);
            }
        }
        else
        {
            ROS_ERROR_STREAM("Line " << lineNumber << ": Expected 8 items, got " << strs.size());
        }
        lineNumber ++;
    }

    return output;
}

std::vector<Eigen::Matrix4d, Eigen::aligned_allocator<Eigen::Matrix4d>> TransformationFile_Manager_Data::readTransformationFromFile(string filePath)
{
    std::vector<Eigen::Matrix4d, Eigen::aligned_allocator<Eigen::Matrix4d>> output;
    std::ifstream input(filePath);
    std::string line;
    unsigned int lineNumber = 1;
    while(std::getline( input, line ))
    {
        std::vector<std::string> strs;
        boost::split(strs, line, boost::is_any_of(";"));
        if (strs.size() == 7)
        {
            std::vector<double> numericValues;
            bool success = true;
            for (unsigned int i = 0; i < strs.size(); i++)
            {
                try
                {
                    std::string temp = strs.at(i);
                    boost::algorithm::trim(temp);
                    numericValues.push_back(boost::lexical_cast<double>(temp));
                }
                catch (boost::bad_lexical_cast const&)
                {
                    ROS_ERROR_STREAM("Line " << lineNumber << ": " <<strs.at(i) << " is not a number.");
                    success = false;
                    break;
                }
            }
            if (success)
            {
                Eigen::Affine3d rotation(Eigen::Quaterniond(numericValues.at(3),numericValues.at(0),numericValues.at(1),numericValues.at(2)));
                /*Eigen::Affine3d rotation1(Eigen::AngleAxisd(numericValues.at(0), Eigen::Vector3d(0.0,0.0,1.0)));
                Eigen::Affine3d rotation2(Eigen::AngleAxisd(numericValues.at(1), Eigen::Vector3d(1.0,0.0,0.0)));
                Eigen::Affine3d rotation3(Eigen::AngleAxisd(numericValues.at(2), Eigen::Vector3d(0.0,0.0,1.0)));*/
                Eigen::Affine3d translation(Eigen::Translation3d(Eigen::Vector3d(numericValues.at(4),numericValues.at(5),numericValues.at(6))));
                Eigen::Affine3d transformation = rotation * translation;
                Eigen::Matrix4d data;
                data = transformation.matrix();
                output.push_back(data);
            }
        }
        else
        {
            ROS_ERROR_STREAM("Line " << lineNumber << ": Expected 7 items, got " << strs.size());
        }
        lineNumber ++;
    }

    return output;
}

bool TransformationFile_Manager_Data::writeTransformationToFile(const std::vector<Eigen::Matrix4d, Eigen::aligned_allocator<Eigen::Matrix4d>> transformation)
{
    ofstream myfile;
    myfile.open (this->filePath, std::ofstream::out | std::ofstream::app);
    for (unsigned int i = 0; i < transformation.size(); i++)
    {

        Eigen::Matrix4d temp = transformation.at(i);
        Eigen::Affine3d tr(temp);
        Eigen::Matrix3d rotation = tr.rotation();
        Eigen::Quaterniond quaternion(rotation);
        Eigen::Vector3d translation(Eigen::Vector3d(temp(0, 3), temp(1, 3), temp(2, 3)));

        myfile << quaternion.x() << "; " << quaternion.y() << "; " <<  quaternion.z() << "; " << quaternion.w() << "; " << translation[0] << "; " << translation[1] << "; " << translation[2] << std::endl;

        /*!!!Angles!!!
        Eigen::Vector3d angles = rotation.eulerAngles(2, 0, 2);

        myfile << angles[0] << "; " << angles[1] << "; " << angles[2] << "; " << translation[0] << "; " << translation[1] << "; " << translation[2] << std::endl;
        */

    }
    myfile.close();

    return true;
}

bool TransformationFile_Manager_Data::writeCameraOffsetToFile(const PanTiltOffsetTupleList &offsetData)
{
    ofstream myfile;
    myfile.open (this->filePath, std::ofstream::out | std::ofstream::app);
    for (unsigned int i = 0; i < offsetData.size(); i++)
    {
        PanTiltOffsetTuple currentTuple = offsetData.at(i);
        double pan = std::get<0>(currentTuple);
        double tilt = std::get<1>(currentTuple);
        Eigen::Matrix4d temp = std::get<2>(currentTuple);
        Eigen::Matrix4d tempOld = std::get<3>(currentTuple);

        myfile << pan << "; " << tilt << "; " << temp(0,3) << "; " << temp(1,3) << "; " << temp(2,3) << "; "<< tempOld(0,3) << "; " << tempOld(1,3) << "; " << tempOld(2,3) << "; " << std::endl;
        //myfile << quaternion.x() << "; " << quaternion.y() << "; " <<  quaternion.z() << "; " << quaternion.w() << "; " << translation[0] << "; " << translation[1] << "; " << translation[2] << std::endl;

        /*!!!Angles!!!
        Eigen::Vector3d angles = rotation.eulerAngles(2, 0, 2);

        myfile << angles[0] << "; " << angles[1] << "; " << angles[2] << "; " << translation[0] << "; " << translation[1] << "; " << translation[2] << std::endl;
        */

    }
    myfile.close();

    return true;
}


#include "Basic2DGenericPFlowPositionCalc.h"

#include "FWCore/MessageLogger/interface/MessageLogger.h"
#include "FWCore/Utilities/interface/isFinite.h"

#include <cmath>
#include "CommonTools/Utils/interface/DynArray.h"
#include<iterator>
#include <boost/function_output_iterator.hpp>

#include "vdt/vdtMath.h"

namespace {
  inline
  bool isBarrel(int cell_layer){
    return (cell_layer == PFLayer::HCAL_BARREL1 ||
	    cell_layer == PFLayer::HCAL_BARREL2 ||
	    cell_layer == PFLayer::ECAL_BARREL);
  }
}

void Basic2DGenericPFlowPositionCalc::
calculateAndSetPosition(reco::PFCluster& cluster) {
  calculateAndSetPositionActual(cluster);
}

void Basic2DGenericPFlowPositionCalc::
calculateAndSetPositions(reco::PFClusterCollection& clusters) {
  for( reco::PFCluster& cluster : clusters ) {
    calculateAndSetPositionActual(cluster);
  }
}

void Basic2DGenericPFlowPositionCalc::
calculateAndSetPositionActual(reco::PFCluster& cluster) const {
  if( !cluster.seed() ) {
    throw cms::Exception("ClusterWithNoSeed")
      << " Found a cluster with no seed: " << cluster;
  }
  double cl_energy = 0;
  double cl_time = 0;
  double cl_timeweight=0.0;
  double max_e = 0.0;
  PFLayer::Layer max_e_layer = PFLayer::NONE;
  // find the seed and max layer and also calculate time
  //Michalis : Even if we dont use timing in clustering here we should fill
  //the time information for the cluster. This should use the timing resolution(1/E)
  //so the weight should be fraction*E^2
  //calculate a simplistic depth now. The log weighted will be done
  //in different stage

  auto const recHitCollection = &(*cluster.recHitFractions()[0].recHitRef()) - cluster.recHitFractions()[0].recHitRef().key();
  auto nhits = cluster.recHitFractions().size();
  struct LHit{ reco::PFRecHit const * hit; float energy; float fraction;};
  declareDynArray(LHit,nhits,hits);
  for(auto i=0U; i<nhits; ++i) {
    auto const & hf = cluster.recHitFractions()[i];
    auto k = hf.recHitRef().key();
    auto p = recHitCollection+k;
    hits[i]= {p,(*p).energy(), float(hf.fraction())};
  }

  bool resGiven = bool(_timeResolutionCalcBarrel) & bool(_timeResolutionCalcEndcap);
  LHit mySeed={nullptr};
  for( auto const & rhf : hits ) {
    const reco::PFRecHit & refhit = *rhf.hit;
    if( refhit.detId() == cluster.seed() )  mySeed = rhf;
    const auto rh_fraction = rhf.fraction;
    const auto rh_rawenergy = rhf.energy;
    const auto rh_energy = rh_rawenergy * rh_fraction;
#ifdef PF_DEBUG
    if UNLIKELY( edm::isNotFinite(rh_energy) ) {
      throw cms::Exception("PFClusterAlgo")
	<<"rechit " << refhit.detId() << " has a NaN energy... "
	<< "The input of the particle flow clustering seems to be corrupted.";
    }
#endif
    cl_energy += rh_energy;
    // If time resolution is given, calculated weighted average
    if ( resGiven ) {
      double res2 = 1.e-4;
      int cell_layer = (int)refhit.layer();
      res2 =  isBarrel(cell_layer) ? 1./_timeResolutionCalcBarrel->timeResolution2(rh_rawenergy) :
                                     1./_timeResolutionCalcEndcap->timeResolution2(rh_rawenergy);
      cl_time += rh_fraction*refhit.time()*res2;
      cl_timeweight += rh_fraction*res2;
    }
    else { // assume resolution = 1/E**2
      const double rh_rawenergy2 = rh_rawenergy*rh_rawenergy;
      cl_timeweight+=rh_rawenergy2*rh_fraction;
      cl_time += rh_rawenergy2*rh_fraction*refhit.time();
    }

    if( rh_energy > max_e ) {
      max_e = rh_energy;
      max_e_layer = refhit.layer();
    }
  }

  cluster.setEnergy(cl_energy);
  cluster.setTime(cl_time/cl_timeweight);
  if (resGiven) {
    cluster.setTimeError(std::sqrt(1.0f/float(cl_timeweight)));
  }
  cluster.setLayer(max_e_layer);

  // calculate the position
  double depth = 0.0;
  double position_norm = 0.0;
  double x(0.0),y(0.0),z(0.0);
  if( nullptr != mySeed.hit ) {
    auto seedNeighbours = mySeed.hit->neighbours();
    switch( _posCalcNCrystals ) {
    case 5:
      seedNeighbours = mySeed.hit->neighbours4();
      break;
    case 9:
      seedNeighbours = mySeed.hit->neighbours8();
      break;
    default:
      break;
    }

    auto compute = [&](LHit const& rhf) {
      const reco::PFRecHit & refhit = *rhf.hit;

      int cell_layer = (int)refhit.layer();
      float threshold=0;

      for (unsigned int j=0; j<(std::get<2>(_logWeightDenom)).size(); ++j) {
	// barrel is detecor type1
	int detectorEnum=std::get<0>(_logWeightDenom)[j];
	int depth=std::get<1>(_logWeightDenom)[j];

	if( ( cell_layer == PFLayer::HCAL_BARREL1 && detectorEnum==1 && refhit.depth()== depth)
	    || ( cell_layer == PFLayer::HCAL_ENDCAP && detectorEnum==2 && refhit.depth()== depth)
	    || detectorEnum==0
	    ) threshold=std::get<2>(_logWeightDenom)[j];

      }

      const auto rh_energy = rhf.energy * rhf.fraction;
      const auto norm = ( rhf.fraction < _minFractionInCalc ?
			  0.0f :
			  std::max(0.0f,vdt::fast_logf(rh_energy*threshold)) );
      const auto rhpos_xyz = refhit.position()*norm;
      x += rhpos_xyz.x();
      y += rhpos_xyz.y();
      z += rhpos_xyz.z();
      depth += refhit.depth()*norm;
      position_norm += norm;

    };

    if(_posCalcNCrystals != -1) // sorted to make neighbour search faster (maybe)
      std::sort(hits.begin(),hits.end(),[](LHit const& a, LHit const& b) { return a.hit<b.hit;});

    if(_posCalcNCrystals == -1)
      for( auto const & rhf : hits ) compute(rhf);
    else {  // only seed and its neighbours
      compute(mySeed);
      // search seedNeighbours to find energy fraction in cluster (sic)
      unInitDynArray(reco::PFRecHit const *,seedNeighbours.size(),nei);
      for(auto k : seedNeighbours){
	nei.push_back(recHitCollection+k);
      }
      std::sort(nei.begin(),nei.end());
      struct LHitLess {
	auto operator()(LHit const &a, reco::PFRecHit const * b) const {return a.hit<b;}
	auto operator()(reco::PFRecHit const * b, LHit const &a) const {return b<a.hit;}
      };
      std::set_intersection(hits.begin(),hits.end(),nei.begin(),nei.end(),
			    boost::make_function_output_iterator(compute),
			    LHitLess()
			    );
    }
  } else {
    throw cms::Exception("Basic2DGenerticPFlowPositionCalc")
      << "Cluster seed hit is null, something is wrong with PFlow RecHit!";
  }

  if( position_norm < _minAllowedNorm ) {
    edm::LogError("WeirdClusterNormalization")
      << "PFCluster too far from seeding cell: set position to (0,0,0).";
    cluster.setPosition(math::XYZPoint(0,0,0));
    cluster.calculatePositionREP();
  } else {
    const double norm_inverse = 1.0/position_norm;
    x *= norm_inverse;
    y *= norm_inverse;
    z *= norm_inverse;
    depth *= norm_inverse;
    cluster.setPosition(math::XYZPoint(x,y,z));
    cluster.setDepth(depth);
    cluster.calculatePositionREP();
  }
}


//============================================================================
//
// This file is part of the Thea toolkit.
//
// This software is distributed under the BSD license, as detailed in the
// accompanying LICENSE.txt file. Portions are derived from other works:
// their respective licenses and copyright information are reproduced in
// LICENSE.txt and/or in the relevant source files.
//
// Author: Siddhartha Chaudhuri
// First version: 2009
//
//============================================================================

#include "EdgeWelder.hpp"
#include "../UnorderedMap.hpp"
#include <boost/functional/hash.hpp>
#include <cmath>
#include <utility>

namespace Thea {
namespace Graphics {

class EdgeWelderImpl
{
  private:
    struct WeldableEdge
    {
      WeldableEdge(void * edge_, Vector3 const & e0_, Vector3 const & e1_) : edge(edge_), e0(e0_), e1(e1_) {}

      void * edge;
      Vector3 e0, e1;
    };

    struct Long3
    {
      intx x, y, z;

      Long3(intx x_, intx y_, intx z_) : x(x_), y(y_), z(z_) {}

      bool operator==(Long3 const & other) const { return x == other.x && y == other.y && z == other.z; }
    };

    typedef std::pair<Long3, Long3> Long3Pair;

    struct Long3PairHasher
    {
      std::size_t operator()(Long3Pair const & a) const
      {
        std::size_t s = boost::hash_value(a.first.x);
        boost::hash_combine(s, a.first.y);
        boost::hash_combine(s, a.first.z);
        boost::hash_combine(s, a.second.x);
        boost::hash_combine(s, a.second.y);
        boost::hash_combine(s, a.second.z);
        return s;
      }
    };

    typedef UnorderedMultiMap<Long3Pair, WeldableEdge, Long3PairHasher> EdgeMap;

    Long3 toGrid(Vector3 const & pos) const
    {
      return Long3(static_cast<intx>(std::floor(pos.x() / (double)weld_radius)),
                   static_cast<intx>(std::floor(pos.y() / (double)weld_radius)),
                   static_cast<intx>(std::floor(pos.z() / (double)weld_radius)));
    }

    Real weld_radius;
    Real squared_weld_radius;
    EdgeMap edge_map;

  public:
    EdgeWelderImpl(Real weld_radius_) : weld_radius(weld_radius_), squared_weld_radius(weld_radius_ * weld_radius_) {}

    void addEdge(void * edge, Vector3 const & e0, Vector3 const & e1)
    {
      WeldableEdge value(edge, e0, e1);
      Long3Pair key(toGrid(e0), toGrid(e1));
      edge_map.insert(EdgeMap::value_type(key, value));
    }

    void * getUndirectedEdge(Vector3 const & e0, Vector3 const & e1) const
    {
      void * edge = getDirectedEdge(e0, e1);
      if (edge)
        return edge;
      else
        return getDirectedEdge(e1, e0);
    }

    void * getDirectedEdge(Vector3 const & e0, Vector3 const & e1) const
    {
      typedef std::pair<EdgeMap::const_iterator, EdgeMap::const_iterator> IteratorRange;
      Long3Pair base_key(toGrid(e0), toGrid(e1));

      // Every edge within welding distance of the given edge must be inside a neighbor of the grid cell containing the edge
      for (int dx0 = -1; dx0 <= 1; ++dx0)
        for (int dy0 = -1; dy0 <= 1; ++dy0)
          for (int dz0 = -1; dz0 <= 1; ++dz0)
            for (int dx1 = -1; dx1 <= 1; ++dx1)
              for (int dy1 = -1; dy1 <= 1; ++dy1)
                for (int dz1 = -1; dz1 <= 1; ++dz1)
                {
                  Long3Pair key(Long3(base_key.first.x + dx0, base_key.first.y + dy0, base_key.first.z + dz0),
                                Long3(base_key.second.x + dx1, base_key.second.y + dy1, base_key.second.z + dz1));
                  IteratorRange nbrs = edge_map.equal_range(key);
                  for (EdgeMap::const_iterator ni = nbrs.first; ni != nbrs.second; ++ni)
                  {
                    if ((ni->second.e0 - e0).squaredNorm() <= squared_weld_radius
                     && (ni->second.e1 - e1).squaredNorm() <= squared_weld_radius)
                      return ni->second.edge;
                  }
                }

      return nullptr;
    }

}; // class EdgeWelderImpl

EdgeWelder::EdgeWelder(Real weld_radius)
: impl(new EdgeWelderImpl(weld_radius))
{
  alwaysAssertM(weld_radius >= 0, "EdgeWelder: Weld radius cannot be negative");
}

EdgeWelder::~EdgeWelder()
{
  delete impl;
}

void
EdgeWelder::addEdge(void * edge, Vector3 const & e0, Vector3 const & e1)
{
  impl->addEdge(edge, e0, e1);
}

void *
EdgeWelder::getDirectedEdge(Vector3 const & e0, Vector3 const & e1) const
{
  return impl->getDirectedEdge(e0, e1);
}

void *
EdgeWelder::getUndirectedEdge(Vector3 const & e0, Vector3 const & e1) const
{
  return impl->getUndirectedEdge(e0, e1);
}

} // namespace Graphics
} // namespace Thea


//  Copyright 2010 Vicente J. Botet Escriba
//  Distributed under the Boost Software License, Version 1.0.
//  See http://www.boost.org/LICENSE_1_0.txt

#ifndef BOOST_CHRONO_TEST_CYCLE_COUNT_HPP
#define BOOST_CHRONO_TEST_CYCLE_COUNT_HPP

#include <boost/chrono/ceil.hpp>
#include <boost/chrono/duration.hpp>
#include <boost/chrono/time_point.hpp>
#include <boost/chrono/stopwatches/reporters/stopwatch_reporter_default_formatter.hpp>
#include <boost/chrono/stopwatches/formatters/elapsed_formatter.hpp>
#include <boost/chrono/stopwatches/strict_stopwatch.hpp>

namespace ex
{
  template <long long speed>
  struct cycle_count
  {
      typedef typename boost::ratio_multiply<boost::ratio<speed>, boost::mega>::type frequency;  // Mhz
      typedef typename boost::ratio_divide<boost::ratio<1>, frequency>::type period;
      typedef long long rep;
      typedef boost::chrono::duration<rep, period> duration;
      typedef boost::chrono::time_point<cycle_count> time_point;
      BOOST_STATIC_CONSTEXPR bool is_steady =             true;
      static long long ticks_;

      static time_point now()
      {
          // return exact cycle count
          return time_point(duration(ticks_));
      }
      static time_point now(boost::system::error_code & )
      {
          // return exact cycle count
        return time_point(duration(ticks_));
      }
      static void advance(std::size_t ticks)
      {
        ticks_ += ticks;
      }
      template <typename D>
      static void advance(D const& d)
      {
        ticks_ += boost::chrono::ceil<duration>(d).count();
      }
  };
  template <long long speed>
  long long cycle_count<speed>::ticks_ = 0;

  template<class Clock, class Rep, class Period>
  void sleep_for(const boost::chrono::duration<Rep, Period>& d)
  {
    Clock::advance(d);
  }

}

namespace boost
{
  namespace chrono
  {

    template <typename CharT, long long speed>
    struct basic_stopwatch_reporter_default_formatter<CharT, strict_stopwatch<ex::cycle_count<speed> > >
    {
      typedef basic_elapsed_formatter<milli, CharT> type;
    };

//    template <long long speed>
//    struct wstopwatch_reporter_default_formatter<strict_stopwatch<ex::cycle_count<speed> > >
//    {
//      typedef welapsed_formatter type;
//    };

  } // namespace chrono
} // namespace boost

#endif


//
// Created by eriks on 4/24/18.
//

#include "energy_error_observer.hpp"
#include "initial_conditions/initial_conditions.hpp"
#include "dynamics/ray_dynamics.hpp"

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <utility>
namespace pt = boost::property_tree;

EnergyErrorObserver::EnergyErrorObserver(std::string file_name) : ThreadLocalObserver(std::move(file_name))
{
}

void EnergyErrorObserver::startTrajectory(const InitialCondition& start, std::size_t trajectory)
{
    mInitialEnergy = mDynamics->getEnergy(start.getState());
}

void EnergyErrorObserver::endTrajectory(const State& final_state)
{
    double finalEnergy = mDynamics->getEnergy(final_state);
    double rel_err = std::abs((mInitialEnergy - finalEnergy) / mInitialEnergy);

    mCount += 1;
    mSum += rel_err;
    mMax = std::max(mMax, rel_err);
}

std::shared_ptr<ThreadLocalObserver> EnergyErrorObserver::clone() const
{
    return std::make_shared<EnergyErrorObserver>( filename() );
}

void EnergyErrorObserver::combine(ThreadLocalObserver& other)
{
    auto& data = dynamic_cast<EnergyErrorObserver&>( other );
    mSum += data.mSum;
    mCount += data.mCount;
    mMax = std::max(mMax, data.mMax);
}

void EnergyErrorObserver::save(std::ostream& target)
{
    pt::ptree tree;

    tree.put("count", mCount);
    tree.put("max", mMax);
    tree.put("sum", mSum);
    tree.put("mean", mSum / mCount);

    pt::write_json(target, tree);
}

double EnergyErrorObserver::getMaximumError() const
{
    return mMax;
}

void EnergyErrorObserver::startTracing()
{
    if(!mDynamics)
        THROW_EXCEPTION(std::logic_error, "Starting energy observation before dynamics have been set.");
}

double EnergyErrorObserver::getMeanError() const {
    return mSum / mCount;
}


#pragma once

#include <boost/date_time/posix_time/posix_time.hpp>
#include <pybind11/pybind11.h>

namespace pybind11 { namespace detail {

long get_usecs(boost::posix_time::time_duration const& d);

inline long get_usecs(boost::posix_time::time_duration const& d)
{
    using namespace boost::posix_time;

    auto resolution = boost::posix_time::time_duration::ticks_per_second();
    auto fractional_seconds = d.fractional_seconds();
    if (resolution > 1000000)
        return fractional_seconds / (resolution / 1000000);
    else
        return fractional_seconds * (1000000 / resolution);
}

template <>
class type_caster<boost::posix_time::time_duration>
{
public:
PYBIND11_TYPE_CASTER(boost::posix_time::time_duration, _("datetime.timedelta"));

    bool load(handle src, bool);
    static handle cast(const boost::posix_time::time_duration &src, return_value_policy /* policy */, handle /* parent */);

};

}} // namespace pybind11::detail

#include "time_duration.ipp"


#ifndef XF_BLAS_L1_TESTS_UTIL_HPP
#define XF_BLAS_L1_TESTS_UTIL_HPP
#include <iostream>
#include <vector>
#include <fstream>
#include <string>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/filtering_streambuf.hpp>
#include <boost/algorithm/string.hpp>

/*!
  @brief read Diagonal matrix from .csv file
  @preCondition number of matrix lines, t_NumDiag, along the diagonal direction must be odd and > 1
  @param t_DataType data type
  @param t_N maximum number of entries in each diagonal line
  @param t_NumDiag number of diagonal lines indexed low to up
  @param p_fileName .csv file containing diagonal matrix data
  @param p_n number of entries in each diagonal line
  @param p_out output diagonal matrix
*/
template <typename t_DataType, unsigned int t_N, unsigned int t_NumDiag>
int readDiag(std::string p_fileName, unsigned int p_n, t_DataType p_out[t_N][t_NumDiag]) {
    std::ifstream l_file(p_fileName);

    std::vector<std::string> l_v;
    std::string l_line;

    if (l_file.good()) {
        std::cout << "Opened " << p_fileName << " OK" << std::endl;

        int i = 0;
        while (l_file.good() && (l_file.peek() != EOF)) {
            getline(l_file, l_line);
            boost::split(l_v, l_line, [](char c) { return c == ','; });
            if (l_v.size() == t_NumDiag) {
                for (unsigned int d = 0; d < t_NumDiag; ++d) {
                    p_out[i][d] = (t_DataType)std::stod(l_v[d]);
                }
                i++;
            }
            if (i > p_n) {
                std::cout << "Warning! File has more than expected " << p_n << " lines..." << std::endl;
                break;
            }
        }
    } else {
        std::cout << "Couldn't open " << p_fileName << std::endl;
        return -1;
    }
    return 0;
}

/*!
  @brief read vector from .csv file
  @param t_DataType data type
  @param t_N maximum number of entries in the input vector
  @param p_fileName .csv file containing the input vector data
  @param p_n number of entries in the input vector
  @param p_out output vector
 */
template <typename t_DataType, unsigned int t_N>
int readVector(std::string p_fileName, unsigned int p_n, t_DataType p_out[t_N]) {
    std::ifstream l_file(p_fileName);
    std::string l_line;

    if (l_file.good()) {
        std::cout << "Opened " << p_fileName << " OK" << std::endl;
        int i = 0;
        while (l_file.good() && (l_file.peek() != EOF)) {
            getline(l_file, l_line);
            p_out[i] = (t_DataType)std::stod(l_line);
            i++;
            if (i > p_n) {
                std::cout << "Warning! File has more than expected " << p_n << " lines/entries..." << std::endl;
                break;
            }
        }
    } else {
        std::cout << "Couldn't open " << p_fileName << std::endl;
        return -1;
    }
    return 0;
}

/*!
  @brief calculate golden reference for diagonal matrix vector multiplication
  @preCondition number of matrix lines, t_NumDiag, along the diagonal direction must be odd and > 1
  @param t_DataType data type
  @param t_N maximum number of entries in each diagonal line
  @param t_NumDiag number of diagonal lines indexed low to up
  @param p_in input diagonal matrix
  @param p_n number of entries in each diagonal line
  @param p_inV input dense vector pointer
  @param p_outV output dense vector
*/
template <typename t_DataType, unsigned int t_N, unsigned int t_NumDiag>
void diagMult(t_DataType p_in[t_N][t_NumDiag], t_DataType p_inV[t_N], unsigned int p_n, t_DataType p_outV[t_N]) {
    for (unsigned int i = 0; i < p_n; ++i) {
        p_outV[i] = 0;
    }
    for (unsigned int i = 0; i < t_NumDiag / 2; ++i) {
        for (unsigned int d = 0; d < (t_NumDiag / 2 + i + 1); ++d) {
            p_outV[i] += p_in[i][d + (t_NumDiag / 2 - i)] * p_inV[d];
        }
    }
    for (int i = t_NumDiag / 2; i < p_n; ++i) {
        for (unsigned int d = 0; d < t_NumDiag; ++d) {
            t_DataType l_vec = ((i - t_NumDiag / 2 + d) < p_n) ? p_inV[i - t_NumDiag / 2 + d] : 0;
            p_outV[i] += p_in[i][d] * l_vec;
        }
    }
}

/*!
  @brief calculate golden reference for amin
  @param t_DataType data type
  @param t_N maximum number of entries in the input vector
  @param t_IndexType type of indices
  @param p_in input vector
  @param p_n number of entries in the input vector
  @param p_res index for the entry that has minimum magnitude
*/
template <typename t_DataType, unsigned int t_N, typename t_IndexType>
void aminRef(t_DataType p_in[t_N], unsigned int p_n, t_IndexType& p_res) {
    unsigned int l_index = 0;
    t_DataType l_minMagVal = (p_in[0] < 0) ? -p_in[0] : p_in[0];
    ;

    for (unsigned int i = 0; i < p_n; ++i) {
        t_DataType l_val = (p_in[i] < 0) ? -p_in[i] : p_in[i];
        if (l_minMagVal > l_val) {
            l_minMagVal = l_val;
            l_index = i;
        }
    }
    p_res = l_index;
}
/*!
  @brief calculate golden reference for amax
  @param t_DataType data type
  @param t_N maximum number of entries in the input vector
  @param t_IndexType type of indices
  @param p_in input vector
  @param p_n number of entries in the input vector
  @param p_res index for the entry that has maximum magnitude
*/
template <typename t_DataType, unsigned int t_N, typename t_IndexType>
void amaxRef(t_DataType p_in[t_N], unsigned int p_n, t_IndexType& p_res) {
    unsigned int l_index = 0;
    t_DataType l_maxMagVal = 0;

    for (unsigned int i = 0; i < p_n; ++i) {
        t_DataType l_val = (p_in[i] < 0) ? -p_in[i] : p_in[i];
        if (l_maxMagVal < l_val) {
            l_maxMagVal = l_val;
            l_index = i;
        }
    }
    p_res = l_index;
}
#endif


//  Copyright John Maddock 2007.
//  Use, modification and distribution are subject to 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)

// Note that this file contains quickbook mark-up as well as code
// and comments, don't change any of the special comment mark-ups!

double some_value = 2;

//[policy_ref_snip3

#include <boost/math/special_functions/gamma.hpp>

using namespace boost::math::policies;
using namespace boost::math;

// Define a policy:
typedef policy<
      promote_double<false>
      > my_policy;

// Call the function:
double t1 = tgamma(some_value, my_policy());

// Alternatively we could use make_policy and define everything at the call site:
double t2 = tgamma(some_value, make_policy(promote_double<false>()));

//]

#include <iostream>

int main()
{
   std::cout << t1 << " " << t2 << std::endl;
}


//==============================================================================
//         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 "nt2 complex.arithmetic toolbox - cmplx_testing/simd Mode"

//////////////////////////////////////////////////////////////////////////////
// unit test behavior of complex.arithmetic components in simd  mode
//////////////////////////////////////////////////////////////////////////////

#include <boost/simd/sdk/simd/io.hpp>
#include <boost/simd/sdk/simd/native.hpp>
#include <nt2/include/constants/one.hpp>
#include <nt2/include/constants/zero.hpp>
#include <nt2/toolbox/constant/common.hpp>
#include <nt2/include/constants/i.hpp>
#include <nt2/include/functions/real.hpp>
#include <nt2/include/functions/imag.hpp>
#include <nt2/sdk/unit/tests/relation.hpp>
#include <nt2/sdk/unit/module.hpp>
#include <nt2/sdk/complex/meta/as_imaginary.hpp>
#include <nt2/sdk/complex/meta/as_dry.hpp>

NT2_TEST_CASE_TPL ( abs_cplx__1_0,  BOOST_SIMD_SIMD_REAL_TYPES)
{
  using boost::simd::native;
  typedef NT2_SIMD_DEFAULT_EXTENSION  ext_t;
  typedef std::complex<T>                              cT;
  typedef native<T ,ext_t>                             vT;
  typedef native<cT ,ext_t>                           vcT;
  typedef typename nt2::meta::as_imaginary<T>::type   ciT;
  typedef native<ciT ,ext_t>                         vciT;
  typedef typename nt2::meta::as_dry<T>::type          dT;
  typedef native<dT ,ext_t>                           vdT;

  NT2_TEST_EQUAL(nt2::real(nt2::One<vcT>()), nt2::One<vT>());
  NT2_TEST_EQUAL(nt2::imag(nt2::One<vcT>()), nt2::Zero<vT>());
  NT2_TEST_EQUAL(nt2::real(nt2::One<vdT>()), nt2::One<vT>());
  NT2_TEST_EQUAL(nt2::imag(nt2::One<vdT>()), nt2::Zero<vT>());
  NT2_TEST_EQUAL(nt2::real(nt2::One<vciT>()), nt2::Zero<vT>());
  NT2_TEST_EQUAL(nt2::imag(nt2::One<vciT>()), nt2::One<vT>());
  NT2_TEST_EQUAL(nt2::real(nt2::I<vcT>()), nt2::Zero<vT>());
  NT2_TEST_EQUAL(nt2::imag(nt2::I<vcT>()), nt2::One<vT>());
  NT2_TEST_EQUAL(nt2::real(nt2::I<vciT>()), nt2::Zero<vT>());
  NT2_TEST_EQUAL(nt2::imag(nt2::I<vciT>()), nt2::One<vT>());

}


// json parser
#include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/ptree.hpp>
#include <utility>
namespace pt = boost::property_tree;

#include "../GreensTensor/GreensTensorFactory.h"
#include "../MemoryKernel/MemoryKernelFactory.h"
#include "Polarizability.h"

// Constructor without an internal bath
Polarizability::Polarizability(double omega_a, double alpha_zero,
                               std::shared_ptr<GreensTensor> greens_tensor)
    : omega_a(omega_a), alpha_zero(alpha_zero),
      greens_tensor(std::move(greens_tensor)) {
  this->mu = nullptr;
}
// Constructor with internal bath mu
Polarizability::Polarizability(double omega_a, double alpha_zero,
                               std::shared_ptr<MemoryKernel> mu,
                               std::shared_ptr<GreensTensor> greens_tensor)
    : omega_a(omega_a), alpha_zero(alpha_zero), mu(std::move(mu)),
      greens_tensor(std::move(greens_tensor)) {}

Polarizability::Polarizability(const std::string &input_file) {
  // Create a root
  pt::ptree root;

  // Load the json file in this ptree
  pt::read_json(input_file, root);

  // read parameters
  this->omega_a = root.get<double>("Polarizability.omega_a");
  this->alpha_zero = root.get<double>("Polarizability.alpha_zero");

  // read greens tensor
  this->greens_tensor = GreensTensorFactory::create(input_file);

  // Check if the category Polarizability.MemoryKernel exists
  boost::optional<pt::ptree &> kernel_given =
      root.get_child_optional("Polarizability.MemoryKernel");

  if (kernel_given) {
    this->mu =
        MemoryKernelFactory::create(input_file, "Polarizability.MemoryKernel");
  } else {
    this->mu = nullptr;
  }
}

void Polarizability::calculate_tensor(double omega, cx_mat::fixed<3, 3> &alpha,
                                      Tensor_Options fancy_complex) const {
  // imaginary unit
  std::complex<double> I(0.0, 1.0);

  // calculate diagonal entries
  cx_mat::fixed<3, 3> diag;
  diag.zeros();
  if (mu != nullptr) {
    diag(0, 0) = diag(1, 1) = diag(2, 2) =
        (omega_a * omega_a - omega * omega) - I * omega * mu->calculate(omega);
  } else {
    diag(0, 0) = diag(1, 1) = diag(2, 2) = omega_a * omega_a - omega * omega;
  }
  // calculate integral over green's tensor with fancy R
  cx_mat::fixed<3, 3> greens_R;
  this->greens_tensor->integrate_k(omega, greens_R, RE, UNIT);

  // calculate integral over green's tensor with fancy I
  cx_mat::fixed<3, 3> greens_I;
  this->greens_tensor->integrate_k(omega, greens_I, IM, UNIT);

  // put everything together
  alpha =
      alpha_zero * omega_a * omega_a *
      inv(diag - alpha_zero * omega_a * omega_a * (greens_R + I * greens_I));

  if (fancy_complex == IM) {
    alpha = (alpha - trans(alpha)) /
            (2.0 * I); // trans is hermitean conjugation in armadillo
  } else if (fancy_complex == RE) {
    alpha = (alpha + trans(alpha)) /
            (2.0); // trans is hermitean conjugation in armadillo
  }
}

double Polarizability::integrand_omega(double omega,
                                       const uvec::fixed<2> &indices,
                                       Tensor_Options fancy_complex) const {
  cx_mat::fixed<3, 3> alpha;
  calculate_tensor(omega, alpha, fancy_complex);

  assert(imag(alpha(indices(0), indices(1))) == 0);
  double result = real(alpha(indices(0), indices(1)));

  return result;
}

double Polarizability::integrate_omega(const uvec::fixed<2> &indices,
                                       Tensor_Options fancy_complex,
                                       double omega_min, double omega_max,
                                       double relerr, double abserr) const {
  auto F = [=](double x) -> double {
    return this->integrand_omega(x, indices, fancy_complex);
  };
  return cquad(F, omega_min, omega_max, relerr, abserr);
}

void Polarizability::print_info(std::ostream &stream) const {
  stream << "# Polarizability\n#\n"
         << "# omega_a = " << omega_a << "\n"
         << "# alpha_zero = " << alpha_zero << "\n";
  if (mu != nullptr) {
    mu->print_info(stream);
  }
  greens_tensor->print_info(stream);
}


#include <boost/array.hpp>

boost::array<unsigned char, 60> chars_65_125_pre11() {
    boost::array<unsigned char, 60> res;

    const unsigned char offset = 65;
    for (std::size_t i = 0; i < res.size(); ++i) {
        res[i] = i + offset;
    }

    return res;
}

#include <boost/algorithm/cxx11/iota.hpp>
#include <boost/array.hpp>

boost::array<unsigned char, 60> chars_65_125() {
    boost::array<unsigned char, 60> res;
    boost::algorithm::iota(res.begin(), res.end(), 65);
    return res;
}

#include <boost/algorithm/hex.hpp>
#include <iterator>
#include <iostream>

void to_hex_test1() {
    const std::string data = "Hello word";
    boost::algorithm::hex(
        data.begin(), data.end(),
        std::ostream_iterator<char>(std::cout)
    );

    std::cout << '\n';
}

void to_hex_test2() {
    const std::string data = "Hello word";
    boost::algorithm::hex(
        data,
        std::ostream_iterator<char>(std::cout)
    );

    std::cout << '\n';
}

#include <cassert>
int main() {
    assert(chars_65_125_pre11() == chars_65_125());
    to_hex_test1();
    to_hex_test2();
}


#ifndef RandomDescriptorCreatorVisitor_HPP
#define RandomDescriptorCreatorVisitor_HPP

#include <boost/graph/graph_traits.hpp>
#include <boost/property_map/property_map.hpp>

/**
 * This is a simplified visitor type that models with the InpaintingVisitorConcept and does
 * nothing but create random descriptors to initialize nodes.
 */
template <typename TDescriptorMap>
struct RandomDescriptorCreatorVisitor
{
  TDescriptorMap& DescriptorMap;
  unsigned int Dimension;

  RandomDescriptorCreatorVisitor(TDescriptorMap& descriptorMap, const unsigned int dimension) :
  DescriptorMap(descriptorMap), Dimension(dimension)
  {

  }

  template <typename VertexType, typename Graph>
  void InitializeVertex(VertexType v, Graph& g) const
  {
    typedef typename boost::property_traits<TDescriptorMap>::value_type DescriptorType;
    DescriptorType descriptor;
    for(unsigned int i = 0; i < dimension; ++i)
    {
      descriptor[i] = drand48();
    }
    put(this->DescriptorMap, v, descriptor);
  }

};

#endif