#include <blitz/array.h>

using namespace blitz;

int main()
{
    Array<float,4> A(3,7,8,2,FortranArray<4>());
    A.dumpStructureInformation(cerr);
    return 0;
}


//==================================================================================================
/*!
  @file

  Copyright 2015 NumScale SAS
  Copyright 2015 J.T.Lapreste

  Distributed under the Boost Software License, Version 1.0.
  (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
//==================================================================================================
#ifndef BOOST_SIMD_FUNCTION_ABSS_HPP_INCLUDED
#define BOOST_SIMD_FUNCTION_ABSS_HPP_INCLUDED

#if defined(DOXYGEN_ONLY)
namespace boost { namespace simd
{

 /*!
    @ingroup group-arithmetic
    Function object implementing abss capabilities

    Computes the saturated absolute value of its parameter.
    The result is always positive or 0.

    @par Semantic

    For any value @c x of type @c T,

    @code
    T r = abss(x);
    @endcode

    is equivalent to:

    @code
    T r = (x == Valmin) ? Valmax : (x < T(0) ? -x : x);
    @endcode

    @par Note:

    For integral types, the function always returns a positive value of the same type as the
    entry. For floating types @ref Nan is the obvious and lone exception to this rule.

    @par Note
    This functor is generally equivalent to @c abs functor except for signed integer
    types for which \c abss(@ref Valmin) is  @ref Valmax.

    @see  abs, sqr_abss, sqrs

  **/
  const boost::dispatch::functor<tag::abss_> abss = {};
} }
#endif

#include <boost/simd/function/scalar/abss.hpp>
#include <boost/simd/function/simd/abss.hpp>

#endif


#include <fstream>
#include <string>

#include <boost/random.hpp>
#include <boost/generator_iterator.hpp>
#include <random>

#include "midi_misc.h"

using namespace std;

/* Ended up using boost::filesystem instead
 * This bool func is not in use
 */
bool does_file_exist(string fileName)
{
	ifstream infile(fileName);
	return infile.good();
}

int random_int(int min, int max) {
	random_device rd;		// I think I prefer seeding with random device vs ctime
	mt19937 rng(rd()); 		// seed with Mersenne-Twister engine VS ctime
	uniform_int_distribution<int> uni(min, max);
	return uni(rng);
}

/* Another way to implement random function */
// void MIDI_Scale::seed_gen() {
// 	gen.seed(static_cast<unsigned int>(std::time(0)));
// }

// int MIDI_Scale::gen_rand_num() {
// 	// seed_gen(); // put in main.cpp
// 	boost::uniform_int<> dist(1, 2);
//     	boost::variate_generator<boost::mt19937&, boost::uniform_int<> > num(gen, dist);
//     	return num();
// }


#include "utils.hpp"
#include "sco/solver_interface.hpp"
#include <Eigen/Geometry>
namespace trajopt {
TrajArray getTraj(const vector<double>& x, const VarArray& vars) {
  TrajArray out(vars.rows(), vars.cols());
  for (size_t i=0; i < (size_t)vars.rows(); ++i) {
    for (size_t j=0; j < (size_t)vars.cols(); ++j) {
      out(i,j) = vars(i,j).value(x.data());
    }
  }
  return out;
}

Eigen::Matrix3d toRot(const OR::Vector& rq) {
  Eigen::Affine3d T;
  T = Eigen::Quaterniond(rq[0], rq[1], rq[2], rq[3]);
  return T.rotation();
}

}


//==================================================================================================
/**
  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/shuffle.hpp>
#include <boost/simd/function/deinterleave_first.hpp>
#include <boost/simd/function/deinterleave_second.hpp>
#include <boost/simd/constant/valmin.hpp>
#include <boost/simd/constant/valmax.hpp>
#include <boost/simd/pack.hpp>
#include <simd_test.hpp>

namespace bs = boost::simd;

STF_CASE_TPL( "Direct deinterleave shuffle", STF_NUMERIC_TYPES)
{
  // cardinal 2
  {
    bs::pack<T,2> a{ bs::Valmax<T>(), T(42) };
    bs::pack<T,2> b{ T(13), bs::Valmin<T>() };

    STF_ALL_EQUAL( (bs::shuffle<0,2>(a,b)), (bs::deinterleave_first (a,b)) );
    STF_ALL_EQUAL( (bs::shuffle<1,3>(a,b)), (bs::deinterleave_second(a,b)) );
    STF_ALL_EQUAL( (bs::shuffle<2,0>(a,b)), (bs::deinterleave_first (b,a)) );
    STF_ALL_EQUAL( (bs::shuffle<3,1>(a,b)), (bs::deinterleave_second(b,a)) );
  }

 // cardinal 4
  {
    bs::pack<T,4> a{ bs::Valmax<T>(), T(42), T(69), bs::Valmin<T>() };
    bs::pack<T,4> b{ T(13), bs::Valmin<T>(), T(37), bs::Valmax<T>() };

    STF_ALL_EQUAL( (bs::shuffle<0,2,4,6>(a,b)), (bs::deinterleave_first (a,b)) );
    STF_ALL_EQUAL( (bs::shuffle<1,3,5,7>(a,b)), (bs::deinterleave_second(a,b)) );
    STF_ALL_EQUAL( (bs::shuffle<4,6,0,2>(a,b)), (bs::deinterleave_first (b,a)) );
    STF_ALL_EQUAL( (bs::shuffle<5,7,1,3>(a,b)), (bs::deinterleave_second(b,a)) );
  }

  // cardinal 8
  {
    bs::pack<T,8> a { bs::Valmax<T>(),T(66),T(99),T(55), T(-1),T(77), T(23), bs::Valmin<T>()};
    bs::pack<T,8> b{ T(13), bs::Valmin<T>(), T(37), bs::Valmax<T>(), T(54),T(13),T(37),T(69) };

    STF_ALL_EQUAL( (bs::shuffle<0,2,4,6,8,10,12,14>(a,b)), (bs::deinterleave_first (a,b)) );
    STF_ALL_EQUAL( (bs::shuffle<1,3,5,7,9,11,13,15>(a,b)), (bs::deinterleave_second(a,b)) );
    STF_ALL_EQUAL( (bs::shuffle<8,10,12,14,0,2,4,6>(a,b)), (bs::deinterleave_first (b,a)) );
    STF_ALL_EQUAL( (bs::shuffle<9,11,13,15,1,3,5,7>(a,b)), (bs::deinterleave_second(b,a)) );
  }
}


//
// Copyright 2013 Christian Henning
// Copyright 2013 Davide Anastasia <davideanastasia@users.sourceforge.net>
// Copyright 2020 Mateusz Loskot <mateusz at loskot dot net>
//
// Distributed under the Boost Software License, Version 1.0
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
#include <boost/gil.hpp>
#include <boost/gil/extension/toolbox/color_converters/rgb_to_luminance.hpp>

#include <boost/core/lightweight_test.hpp>

#include "test_utility_output_stream.hpp"

namespace gil = boost::gil;

struct double_zero { static double apply() { return 0.0; } };
struct double_one  { static double apply() { return 1.0; } };

using gray64f_pixel_t = gil::pixel<double, gil::gray_layout_t>;
using rgb64f_pixel_t = gil::pixel<double, gil::rgb_layout_t>;

void test_rgb_to_luminance()
{
    rgb64f_pixel_t a(10, 20, 30);
    gray64f_pixel_t b;
    gil::color_convert(a, b);
    BOOST_TEST_EQ(b, b);
}

int main()
{
    test_rgb_to_luminance();

    return ::boost::report_errors();
}


/**
 * @file tests/sumtree_test.cpp
 * @author Xiaohong
 *
 * Test for Sumtree implementation.
 *
 * mlpack is free software; you may redistribute it and/or modify it under the
 * terms of the 3-clause BSD license.  You should have received a copy of the
 * 3-clause BSD license along with mlpack.  If not, see
 * http://www.opensource.org/licenses/BSD-3-Clause for more information.
 */
#include <mlpack/core.hpp>

#include <mlpack/methods/reinforcement_learning/replay/sumtree.hpp>

#include <boost/test/unit_test.hpp>
#include "test_tools.hpp"

using namespace mlpack;
using namespace mlpack::rl;

BOOST_AUTO_TEST_SUITE(SumTreeTest);

/**
 * Test that we set the element.
 */
BOOST_AUTO_TEST_CASE(SetElement)
{
  SumTree<double> sumtree(4);
  sumtree.Set(0, 1.0);
  sumtree.Set(1, 0.8);
  sumtree.Set(2, 0.6);
  sumtree.Set(3, 0.4);

  BOOST_CHECK_CLOSE(sumtree.Sum(), 2.8, 1e-8);
  BOOST_CHECK_CLOSE(sumtree.Sum(0, 1), 1.0, 1e-8);
  BOOST_CHECK_CLOSE(sumtree.Sum(0, 3), 2.4, 1e-8);
  BOOST_CHECK_CLOSE(sumtree.Sum(1, 4), 1.8, 1e-8);
}

/**
 * Test that we get the element.
 */
BOOST_AUTO_TEST_CASE(GetElement)
{
  SumTree<double> sumtree(4);
  sumtree.Set(0, 1.0);
  sumtree.Set(1, 0.8);
  sumtree.Set(2, 0.6);
  sumtree.Set(3, 0.4);

  BOOST_CHECK_CLOSE(sumtree.Get(0), 1.0, 1e-8);
  BOOST_CHECK_CLOSE(sumtree.Get(1), 0.8, 1e-8);
  BOOST_CHECK_CLOSE(sumtree.Get(2), 0.6, 1e-8);
  BOOST_CHECK_CLOSE(sumtree.Get(3), 0.4, 1e-8);
}

/**
 * Test that we find the highest index in the array such that
 * Sum(arr[0] + arr[1] + arr[2] ... + arr[i]) <= mass.
 */
BOOST_AUTO_TEST_CASE(FindPrefixSum)
{
  SumTree<double> sumtree(4);
  sumtree.Set(0, 1.0);
  sumtree.Set(1, 0.8);
  sumtree.Set(2, 0.6);
  sumtree.Set(3, 0.4);

  BOOST_CHECK_EQUAL(sumtree.FindPrefixSum(0), 0);
  BOOST_CHECK_EQUAL(sumtree.FindPrefixSum(1), 1);
  BOOST_CHECK_EQUAL(sumtree.FindPrefixSum(2.8), 3);
  BOOST_CHECK_EQUAL(sumtree.FindPrefixSum(3.0), 3);
}

/**
 * Test that we find the highest index in the array such that
 * sum(arr[0] + arr[1] + arr[2] ... + arr[i]) <= mass.
 */
BOOST_AUTO_TEST_CASE(BatchUpdate)
{
  SumTree<double> sumtree(4);
  arma::ucolvec indices = {0, 1, 2, 3};
  arma::colvec data = {1.0, 0.8, 0.6, 0.4};

  sumtree.BatchUpdate(indices, data);

  BOOST_CHECK_EQUAL(sumtree.FindPrefixSum(0), 0);
  BOOST_CHECK_EQUAL(sumtree.FindPrefixSum(1), 1);
  BOOST_CHECK_EQUAL(sumtree.FindPrefixSum(2.8), 3);
  BOOST_CHECK_EQUAL(sumtree.FindPrefixSum(3.0), 3);
}

BOOST_AUTO_TEST_SUITE_END();


#ifndef HMLIB_ODEINT_EQSTATEBREAKOBSERVER_INC
#define HMLIB_ODEINT_EQSTATEBREAKOBSERVER_INC 100
#
#include <array>
#include <boost/geometry.hpp>
#include "container_observer.hpp"
#include "break_observer.hpp"
#include "../utility.hpp"
namespace hmLib{
	namespace odeint{
		namespace detail{
			template<typename state_, typename time_>
			struct eqstate_breaker{
			public:
				using state = state_;
				using time = time_;
			private:
				unsigned int Cnt;
				unsigned int Interval;
				unsigned int IgnoreNum;
				double Error;
			public:
				eqstate_breaker(unsigned int Interval_,unsigned int IgnoreNum_, double Error_) :Cnt(0), Interval(Interval_), IgnoreNum(IgnoreNum_), Error(Error_){}
				bool operator()(const state& x, time t, container_observer<state,time>& Observer){
					if(++Cnt < Interval)return false;
					Cnt = 0;

					auto Beg = Observer.rbegin();
					auto End = Observer.rend();

					if(End - Beg <= IgnoreNum)return false;
					Beg += IgnoreNum;

					for(auto Itr = Beg; Itr != End; ++Itr){
						if(hmLib::odeint::distance_norm_inf(x, Itr->second) < Error){
							return true;
						}
					}

					return false;
				}
			};
			template<typename time_>
			struct eqstate_breaker < std::array<double, 2> , time_>{
				using state = std::array<double, 2>;
				using time = time_;
			private:
				unsigned int Cnt;
				unsigned int Interval;
			private:
				bool is_cross_segment(std::array<double, 2> a1, std::array<double, 2> a2, std::array<double, 2> b1, std::array<double, 2> b2){
					if(a1[0] >= a2[0]){
						if((a1[0] < b1[0] && a1[0] < b2[0]) || (a2[0] > b1[0] && a2[0] > b2[0])){
							return false;
						}
					} else{
						if((a2[0] < b1[0] && a2[0] < b2[0]) || (a1[0] > b1[0] && a1[0] > b2[0])){
							return false;
						}
					}
					if(a1[1] >= a2[1]){
						if((a1[1] < b1[1] && a1[1] < b2[1]) || (a2[1] > b1[1] && a2[1] > b2[1])){
							return false;
						}
					} else{
						if((a2[1] < b1[1] && a2[1] < b2[1]) || (a1[1] > b1[1] && a1[1] > b2[1])){
							return false;
						}
					}

					if(((a1[0] - a2[0]) * (b1[1] - a1[1]) + (a1[1] - a2[1]) * (a1[0] - b1[0])) *
						((a1[0] - a2[0]) * (b2[1] - a1[1]) + (a1[1] - a2[1]) * (a1[0] - b2[0])) > 0){
						return false;
					}
					if(((b1[0] - b2[0]) * (a1[1] - b1[1]) + (b1[1] - b2[1]) * (b1[0] - a1[0])) *
						((b1[0] - b2[0]) * (a2[1] - b1[1]) + (b1[1] - b2[1]) * (b1[0] - a2[0])) > 0){
						return false;
					}
					return true;
				}
			public:
				eqstate_breaker(unsigned int Interval_):Cnt(0),Interval(Interval_){}
				bool operator()(const state& x, time t, container_observer<state, time>& Observer){
					if(++Cnt < Interval)return false;
					Cnt = 0;

					auto Beg = Observer.rbegin();
					auto End = Observer.rend();

					state y = Beg->second;
					state p = Beg->second;
					++Beg;

					for(; Beg != End; ++Beg){
						if(is_cross_segment(x, y, p, Beg->second))return true;
						p = Beg->second;
					}
					return false;
				}
			};
		}
		template<typename state_, typename time_=double>
		using eqstate_break_observer = observer_based_break_observer<container_observer<state_, time_>, detail::eqstate_breaker<state_,time_> >;
	}
}
#
#endif


/*
 * This file is part of the statismo library.
 *
 * Author: Christoph Jud (christoph.jud@unibas.ch)
 *
 * Copyright (c) 2015 University of Basel
 * All rights reserved.
 *
 * 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.
 *
 * Neither the name of the project's author 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 "StatismoUnitTest.h"
#include "statismo/core/Exceptions.h"

#include "statismo/core/CommonTypes.h"
#include "statismo/core/DataManager.h"
#include "statismo/core/Domain.h"
#include "statismo/core/RandUtils.h"
#include "statismo/core/PCAModelBuilder.h"
#include "statismo/VTK/vtkStandardMeshRepresenter.h"
#include "vtkTestHelper.h"

#include <Eigen/Geometry>

#include <vtkMath.h>
#include <vtkPoints.h>
#include <vtkPolyDataReader.h>
#include <vtkPolyDataWriter.h>
#include <vtkVersion.h>

#include <memory>
#include <string>
#include <vector>

using namespace statismo;
using namespace statismo::test;

namespace
{
using RepresenterType = vtkStandardMeshRepresenter;
using DataManagerType = statismo::BasicDataManager<vtkPolyData>;
using PointType = vtkStandardMeshRepresenter::PointType;
using DomainType = vtkStandardMeshRepresenter::DomainType;
using DomainPointsListType = DomainType::DomainPointsListType;
using StatisticalModelType = statismo::StatisticalModel<vtkPolyData>;
using PCAModelBuilderType = statismo::PCAModelBuilder<vtkPolyData>;

std::vector<std::string> g_filenames;
std::string              g_outdir;
unsigned                 g_pointCount;

/**
 * The test works as follows:
 *  - First a standard PCA model is built out of the sample hand-shapes of statismo
 *    It is ensured that the standard argument results in exactly the same model
 *    as if JacobiSVD is provided.
 *  - In the second test, a PCA model is built out of 5000 samples drawn from the
 *    previous built model. Here, the SelfAdjointEigenSolver is used, since there
 *    are more samples than variables.
 *
 * Arguments:
 *  - one can provide a number of points with which the samples should be subsampled (default is 100)
 *  - additionally, one can provide an output directory. If this is provided, the principal
 *    components of the model are sampled and stored in this directory. This is meant for visual inspection.
 */

int
TestBuildModel()
{
  // Necessary to have deterministic results
  rand::RandGen(0);

  auto reference = ReducePoints(LoadPolyData(g_filenames[0]), g_pointCount);
  auto representer = RepresenterType::SafeCreate(reference);
  auto dataManager = DataManagerType::SafeCreate(representer.get());

  for (const auto & f : g_filenames)
  {
    dataManager->AddDataset(ReducePoints(LoadPolyData(f), g_pointCount), "dataset");
  }

  const double kDataNoise = 0.0;

  // ----------------------------------------------------------
  // First compute PCA model using standard JacobiSVD
  // ----------------------------------------------------------
  auto pcaModelBuilder = PCAModelBuilderType::SafeCreate();

  // perform with standard argument
  auto       jacobiModel = pcaModelBuilder->BuildNewModel(dataManager->GetData(), kDataNoise, false);
  VectorType variance1 = jacobiModel->GetPCAVarianceVector();
  MatrixType pcbasis1 = jacobiModel->GetPCABasisMatrix();

  // perform with providing JacobiSVD
  jacobiModel = pcaModelBuilder->BuildNewModel(
    dataManager->GetData(), kDataNoise, false, PCAModelBuilderType::EigenValueMethod::JACOBI_SVD);

  VectorType variance2 = jacobiModel->GetPCAVarianceVector();
  MatrixType pcbasis2 = jacobiModel->GetPCABasisMatrix();

  STATISMO_ASSERT_DOUBLE_EQ(CompareVectors(variance1, variance2), 0.0f);
  STATISMO_ASSERT_DOUBLE_EQ(CompareMatrices(pcbasis1, pcbasis2), 0.0);

  // ----------------------------------------------------------
  // Generate a lot of samples out of the JacobiSVD model
  // ----------------------------------------------------------
  auto dataManager2 = DataManagerType::SafeCreate(representer.get());
  dataManager2->AddDataset(reference, "ref");
  for (unsigned i = 0; i < 5000; i++)
  {
    std::stringstream ss;
    ss << "sample" << i;
    dataManager2->AddDataset(jacobiModel->DrawSample(), ss.str());
  }

  // ----------------------------------------------------------
  // Compute PCA model using the SelfAdjointEigenSolver
  // ----------------------------------------------------------
  auto saesModel = pcaModelBuilder->BuildNewModel(
    dataManager2->GetData(), kDataNoise, false, PCAModelBuilderType::EigenValueMethod::SELF_ADJOINT_EIGEN_SOLVER);

  // ----------------------------------------------------------
  // Comparing the models
  // - compare each principal component
  // ----------------------------------------------------------
  double error{ 0.0 };
  for (unsigned i = 0;
       i < std::min(jacobiModel->GetNumberOfPrincipalComponents(), saesModel->GetNumberOfPrincipalComponents());
       i++)
  {
    VectorType coeff1 = VectorType::Zero(jacobiModel->GetNumberOfPrincipalComponents());
    coeff1[i] = 2;
    VectorType coeff2 = VectorType::Zero(saesModel->GetNumberOfPrincipalComponents());
    coeff2[i] = 2;

    // it might be, that the direction of the pc is in the opposite direction
    double equalDir =
      CompareVectors(jacobiModel->DrawSampleVector(coeff1, false), saesModel->DrawSampleVector(coeff2, false));
    coeff2[i] = -2;
    double oppositeDir =
      CompareVectors(jacobiModel->DrawSampleVector(coeff1, false), saesModel->DrawSampleVector(coeff2, false));

    error += std::min(equalDir, oppositeDir);

    if (!g_outdir.empty())
    {
      std::stringstream ss1;
      ss1 << g_outdir << "/jacobi-" << i << ".vtk";
      WritePolyData(jacobiModel->DrawSample(coeff1, false), ss1.str());

      std::stringstream ss2;
      ss2 << g_outdir << "/saes-" << i << ".vtk";
      if (equalDir < oppositeDir)
      {
        coeff2[i] = 2;
      }
      WritePolyData(saesModel->DrawSample(coeff2, false), ss2.str());
    }
  }

  STATISMO_ASSERT_LT(error, 150.0);

  double varError{ 0.0 };
  for (unsigned i = 0;
       i < std::min(jacobiModel->GetNumberOfPrincipalComponents(), saesModel->GetNumberOfPrincipalComponents());
       i++)
  {
    varError += std::sqrt(std::pow(jacobiModel->GetPCAVarianceVector()[i] - saesModel->GetPCAVarianceVector()[i], 2));
  }

  STATISMO_ASSERT_LT(varError, 250.0);

  return EXIT_SUCCESS;
}

} // namespace

int
PCAModelBuilderWithSelfAdjointEigenSolverTest(int argc, char * argv[]) // NOLINT
{
  if (argc < 2)
  {
    std::cout << "Usage: " << argv[0] << " datadir "
              << "number_of_points(default=100) g_outdir" << std::endl;
    exit(EXIT_FAILURE);
  }

  std::string datadir = argv[1];

  // number of points which are used for building the model
  // the number of points is reduced since the SelfAdjointEigenSolver operates
  // on the full covariance matrix.
  g_pointCount = 100;
  if (argc == 3)
  {
    g_pointCount = std::stoi(argv[2]);
  }

  if (argc == 4)
  {
    g_outdir = argv[3];
  }

  for (unsigned i = 0; i <= 16; ++i)
  {
    g_filenames.emplace_back(datadir + "/hand_polydata/hand-" + std::to_string(i) + ".vtk");
  }

  auto res = statismo::Translate([]() {
    return statismo::test::RunAllTests("PCAModelBuilderWithSelfAdjointEigenSolverTest",
                                       { { "TestBuildModel", TestBuildModel } });
  });

  return !CheckResultAndAssert(res, EXIT_SUCCESS);
}


//==================================================================================================
/*!
  @file

  @copyright 2012-2015 NumScale SAS
  @copyright 2015 J.T.Lapreste

  Distributed under the Boost Software License, Version 1.0.
  (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
//==================================================================================================
#ifndef BOOST_SIMD_FUNCTION_EPS_HPP_INCLUDED
#define BOOST_SIMD_FUNCTION_EPS_HPP_INCLUDED

#if defined(DOXYGEN_ONLY)
namespace boost { namespace simd
{
  /*!

    @ingroup group-ieee
    Function object implementing eps capabilities

    This is the distance between x and the next representable value of the type.

    For floating types (except denormal numbers)  @c eps(x) returns 2^(exponent(x))*Eps

    @par Semantic:

    @code
    T r = eps(x);
    @endcode

    is similar to:

    @code

    if T is floating
      r = 2^(exponent(x))*Eps<T>()
    else if T is integral
      r = 1;
    @endcode

    @see ulp,  ulpdist,  Eps

    @return a value of same type as the input

**/
  const boost::dispatch::functor<tag::abs_> eps = {};

} }
#endif

#include <boost/simd/function/scalar/eps.hpp>
#include <boost/simd/function/simd/eps.hpp>

#endif


#include "generalizedassignmentsolver/generator.hpp"

#include <boost/program_options.hpp>

using namespace generalizedassignmentsolver;

int main(int argc, char *argv[])
{
    namespace po = boost::program_options;

    // Parse program options
    Generator data;
    std::string output_file = "";
    po::options_description desc("Allowed options");
    desc.add_options()
        ("help,h", "produce help message")
        (",t", po::value<std::string>(&data.t)->required(), "set t")
        (",n", po::value<ItemIdx>(&data.n)->required(), "set n")
        (",m", po::value<AgentIdx>(&data.m), "set m")
        (",r", po::value<Weight>(&data.r), "set r")
        (",x", po::value<double>(&data.x), "set x")
        (",s", po::value<Seed>(&data.s), "set seed")
        (",o", po::value<std::string>(&output_file), "set output file")
        ;
    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, desc), vm);
    if (vm.count("help")) {
        std::cout << desc << std::endl;;
        return 1;
    }
    try {
        po::notify(vm);
    } catch (const po::required_option& e) {
        std::cout << desc << std::endl;;
        return 1;
    }

    std::cout << data << std::endl;
    Instance ins = data.generate();

    if (output_file != "")
        ins.write(output_file);

    return 0;
}


// Copyright 2004 The Trustees of Indiana University.

// Use, modification and distribution is 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)

//  Authors: Douglas Gregor
//           Andrew Lumsdaine
#include <boost/graph/fruchterman_reingold.hpp>
#include <boost/graph/random_layout.hpp>
#include <boost/graph/kamada_kawai_spring_layout.hpp>
#include <boost/graph/circle_layout.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/random/linear_congruential.hpp>
#include <boost/test/minimal.hpp>
#include <iostream>
#include <boost/limits.hpp>
#include <fstream>
#include <string>
using namespace boost;

enum vertex_position_t { vertex_position };
namespace boost { BOOST_INSTALL_PROPERTY(vertex, position); }

struct point
{
  double x;
  double y;
};

template<typename Graph, typename PositionMap>
void print_graph_layout(const Graph& g, PositionMap position)
{
  typename graph_traits<Graph>::vertex_iterator vi, vi_end;
  int xmin = 0, xmax = 0, ymin = 0, ymax = 0;
  for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) {
    if ((int)position[*vi].x < xmin) xmin = (int)position[*vi].x;
    if ((int)position[*vi].x > xmax) xmax = (int)position[*vi].x;
    if ((int)position[*vi].y < ymin) ymin = (int)position[*vi].y;
    if ((int)position[*vi].y > ymax) ymax = (int)position[*vi].y;
  }

  for (int y = ymin; y <= ymax; ++y) {
    for (int x = xmin; x <= xmax; ++x) {
      // Find vertex at this position
      typename graph_traits<Graph>::vertices_size_type index = 0;
      for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi, ++index) {
        if ((int)position[*vi].x == x && (int)position[*vi].y == y)
          break;
      }

      if (vi == vi_end) std::cout << ' ';
      else std::cout << (char)(index + 'A');
    }
    std::cout << std::endl;
  }
}

template<typename Graph, typename PositionMap>
void dump_graph_layout(std::string name, const Graph& g, PositionMap position)
{
  std::ofstream out((name + ".dot").c_str());
  out << "graph " << name << " {" << std::endl;

  typename graph_traits<Graph>::vertex_iterator vi, vi_end;
  for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) {
    out << "  n" << get(vertex_index, g, *vi) << "[ pos=\""
        << (int)position[*vi].x + 25 << ", " << (int)position[*vi].y + 25
        << "\" ];\n";
  }

  typename graph_traits<Graph>::edge_iterator ei, ei_end;
  for (tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) {
    out << "  n" << get(vertex_index, g, source(*ei, g)) << " -- n"
        << get(vertex_index, g, target(*ei, g)) << ";\n";
  }
  out << "}\n";
}

template<typename Graph>
void
test_circle_layout(Graph*, typename graph_traits<Graph>::vertices_size_type n)
{
  typedef typename graph_traits<Graph>::vertex_descriptor vertex;
  typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator;
  typedef typename graph_traits<Graph>::vertices_size_type vertices_size_type;
  typedef typename graph_traits<Graph>::edges_size_type edges_size_type;

  Graph g(n);

  // Initialize vertex indices
  vertex_iterator vi = vertices(g).first;
  for (vertices_size_type i = 0; i < n; ++i, ++vi)
    put(vertex_index, g, *vi, i);

  circle_graph_layout(g, get(vertex_position, g), 10.0);

  std::cout << "Regular polygon layout with " << n << " points.\n";
  print_graph_layout(g, get(vertex_position, g));
}

struct simple_edge
{
  int first, second;
};

struct kamada_kawai_done
{
  kamada_kawai_done() : last_delta() {}

  template<typename Graph>
  bool operator()(double delta_p,
                  typename boost::graph_traits<Graph>::vertex_descriptor p,
                  const Graph& g,
                  bool global)
  {
    if (global) {
      double diff = last_delta - delta_p;
      if (diff < 0) diff = -diff;
      last_delta = delta_p;
      return diff < 0.01;
    } else {
      return delta_p < 0.01;
    }
  }

  double last_delta;
};

template<typename Graph>
void
test_triangle(Graph*)
{
  typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
  typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;

  Graph g;

  vertex_descriptor u = add_vertex(g); put(vertex_index, g, u, 0);
  vertex_descriptor v = add_vertex(g); put(vertex_index, g, v, 1);
  vertex_descriptor w = add_vertex(g); put(vertex_index, g, w, 2);

  edge_descriptor e1 = add_edge(u, v, g).first; put(edge_weight, g, e1, 1.0);
  edge_descriptor e2 = add_edge(v, w, g).first; put(edge_weight, g, e2, 1.0);
  edge_descriptor e3 = add_edge(w, u, g).first; put(edge_weight, g, e3, 1.0);

  circle_graph_layout(g, get(vertex_position, g), 25.0);

  bool ok = kamada_kawai_spring_layout(g,
                                       get(vertex_position, g),
                                       get(edge_weight, g),
                                       side_length(50.0));
  BOOST_CHECK(ok);

  std::cout << "Triangle layout (Kamada-Kawai).\n";
  print_graph_layout(g, get(vertex_position, g));
}

template<typename Graph>
void
test_cube(Graph*)
{
  enum {A, B, C, D, E, F, G, H};
  simple_edge cube_edges[12] = {
    {A, E}, {A, B}, {A, D}, {B, F}, {B, C}, {C, D}, {C, G}, {D, H},
    {E, H}, {E, F}, {F, G}, {G, H}
  };

  Graph g(&cube_edges[0], &cube_edges[12], 8);

  typedef typename graph_traits<Graph>::edge_iterator edge_iterator;
  typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator;

  vertex_iterator vi, vi_end;
  int i = 0;
  for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
    put(vertex_index, g, *vi, i++);

  edge_iterator ei, ei_end;
  for (tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) {
    put(edge_weight, g, *ei, 1.0);
    std::cerr << "(" << (char)(get(vertex_index, g, source(*ei, g)) + 'A')
              << ", " << (char)(get(vertex_index, g, target(*ei, g)) + 'A')
              << ") ";
  }
  std::cerr << std::endl;

  circle_graph_layout(g, get(vertex_position, g), 25.0);

  bool ok = kamada_kawai_spring_layout(g,
                                       get(vertex_position, g),
                                       get(edge_weight, g),
                                       side_length(50.0),
                                       kamada_kawai_done());
  BOOST_CHECK(ok);

  std::cout << "Cube layout (Kamada-Kawai).\n";
  print_graph_layout(g, get(vertex_position, g));

  dump_graph_layout("cube", g, get(vertex_position, g));

  minstd_rand gen;
  random_graph_layout(g, get(vertex_position, g), -25.0, 25.0, -25.0, 25.0,
                      gen);

  std::vector<point> displacements(num_vertices(g));
  fruchterman_reingold_force_directed_layout
    (g,
     get(vertex_position, g),
     50.0,
     50.0,
     square_distance_attractive_force(),
     square_distance_repulsive_force(),
     all_force_pairs(),
     linear_cooling<double>(100),
     make_iterator_property_map(displacements.begin(),
                                get(vertex_index, g),
                                point()));

  std::cout << "Cube layout (Fruchterman-Reingold).\n";
  print_graph_layout(g, get(vertex_position, g));

  dump_graph_layout("cube-fr", g, get(vertex_position, g));
}

template<typename Graph>
void
test_triangular(Graph*)
{
  enum {A, B, C, D, E, F, G, H, I, J};
  simple_edge triangular_edges[18] = {
    {A, B}, {A, C}, {B, C}, {B, D}, {B, E}, {C, E}, {C, F}, {D, E}, {D, G},
    {D, H}, {E, F}, {E, H}, {E, I}, {F, I}, {F, J}, {G, H}, {H, I}, {I, J}
  };

  Graph g(&triangular_edges[0], &triangular_edges[18], 10);

  typedef typename graph_traits<Graph>::edge_iterator edge_iterator;
  typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator;

  vertex_iterator vi, vi_end;
  int i = 0;
  for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
    put(vertex_index, g, *vi, i++);

  edge_iterator ei, ei_end;
  for (tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) {
    put(edge_weight, g, *ei, 1.0);
    std::cerr << "(" << (char)(get(vertex_index, g, source(*ei, g)) + 'A')
              << ", " << (char)(get(vertex_index, g, target(*ei, g)) + 'A')
              << ") ";
  }
  std::cerr << std::endl;

  circle_graph_layout(g, get(vertex_position, g), 25.0);

  bool ok = kamada_kawai_spring_layout(g,
                                       get(vertex_position, g),
                                       get(edge_weight, g),
                                       side_length(50.0),
                                       kamada_kawai_done());
  BOOST_CHECK(ok);

  std::cout << "Triangular layout (Kamada-Kawai).\n";
  print_graph_layout(g, get(vertex_position, g));

  dump_graph_layout("triangular-kk", g, get(vertex_position, g));

  minstd_rand gen;
  random_graph_layout(g, get(vertex_position, g), -25.0, 25.0, -25.0, 25.0,
                      gen);

  dump_graph_layout("random", g, get(vertex_position, g));

  std::vector<point> displacements(num_vertices(g));
  fruchterman_reingold_force_directed_layout
    (g,
     get(vertex_position, g),
     50.0,
     50.0,
     attractive_force(square_distance_attractive_force()).
     cooling(linear_cooling<double>(100)));

  std::cout << "Triangular layout (Fruchterman-Reingold).\n";
  print_graph_layout(g, get(vertex_position, g));

  dump_graph_layout("triangular-fr", g, get(vertex_position, g));
}

template<typename Graph>
void
test_disconnected(Graph*)
{
  enum {A, B, C, D, E, F, G, H};
  simple_edge triangular_edges[13] = {
    {A, B}, {B, C}, {C, A},
    {D, E}, {E, F}, {F, G}, {G, H}, {H, D},
    {D, F}, {F, H}, {H, E}, {E, G}, {G, D}
  };

  Graph g(&triangular_edges[0], &triangular_edges[13], 8);

  typedef typename graph_traits<Graph>::edge_iterator edge_iterator;
  typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator;

  vertex_iterator vi, vi_end;
  int i = 0;
  for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
    put(vertex_index, g, *vi, i++);

  edge_iterator ei, ei_end;
  for (tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) {
    put(edge_weight, g, *ei, 1.0);
    std::cerr << "(" << (char)(get(vertex_index, g, source(*ei, g)) + 'A')
              << ", " << (char)(get(vertex_index, g, target(*ei, g)) + 'A')
              << ") ";
  }
  std::cerr << std::endl;

  circle_graph_layout(g, get(vertex_position, g), 25.0);

  bool ok = kamada_kawai_spring_layout(g,
                                       get(vertex_position, g),
                                       get(edge_weight, g),
                                       side_length(50.0),
                                       kamada_kawai_done());
  BOOST_CHECK(!ok);

  minstd_rand gen;
  random_graph_layout(g, get(vertex_position, g), -25.0, 25.0, -25.0, 25.0,
                      gen);

  std::vector<point> displacements(num_vertices(g));
  fruchterman_reingold_force_directed_layout
    (g,
     get(vertex_position, g),
     50.0,
     50.0,
     attractive_force(square_distance_attractive_force()).
     cooling(linear_cooling<double>(50)));

  std::cout << "Disconnected layout (Fruchterman-Reingold).\n";
  print_graph_layout(g, get(vertex_position, g));

  dump_graph_layout("disconnected-fr", g, get(vertex_position, g));
}

int test_main(int, char*[])
{
  typedef adjacency_list<listS, listS, undirectedS,
                         // Vertex properties
                         property<vertex_index_t, int,
                         property<vertex_position_t, point> >,
                         // Edge properties
                         property<edge_weight_t, double> > Graph;

  test_circle_layout((Graph*)0, 5);
  test_cube((Graph*)0);
  test_triangular((Graph*)0);
  test_disconnected((Graph*)0);
  return 0;
}


#include "../lib_graphs/defs.h"

#include "DebugPrinter.h"

#include "AuctionDefs.h"

#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string.hpp>

#include <cmath>

std::string pathToString(Point path[], const size_t pathSize)
{
  std::stringstream ss;
  size_t i;

  // Cycle through all but last one
  for (i = 0; i < pathSize - 1; i++)
    ss << path[i].first << "," << path[i].second << ":";

  // Finish with last one
  ss << path[i].first << "," << path[i].second;

  return ss.str();
}

template<typename U, typename V>
std::string pairToString(std::pair<U,V> pair)
{
  std::stringstream ss;
  ss << pair.first << "," << pair.second;
  return ss.str();
}

std::string bidToString(Bid bid)
{
  return pairToString(bid);
}

Bid bidFromString(std::string str)
{
  Bid bid;
  std::vector<std::string> strs;
  boost::split(strs, str, boost::is_any_of(","));
  bid = std::make_pair(
      boost::lexical_cast<Vertex>(strs[0]),
      boost::lexical_cast<mbogo_weight_t>(strs[1]));
  return bid;
}

std::string winningBidToString(WinningBid bid)
{
  std::stringstream ss;
  ss << bid.winner << "," << bid.target << "," << bid.bid;
  return ss.str();
}

WinningBid winningBidFromString(std::string str)
{
  WinningBid bid;
  std::vector<std::string> strs;
  boost::split(strs, str, boost::is_any_of(","));
  bid.winner = boost::lexical_cast<int>(strs[0]);
  bid.target = boost::lexical_cast<Vertex>(strs[1]);
  bid.bid    = boost::lexical_cast<mbogo_weight_t>(strs[2]);
  return bid;
}

int getBidder(std::string bidHeader)
{
  int bidder;

  std::vector<std::string> strs;
  boost::split(strs, bidHeader, boost::is_any_of("_V"));
  bidder = boost::lexical_cast<int>(strs.back());

  return bidder;
}

std::string getVar(std::string header, const int id)
{
  std::stringstream ss;
  ss << header << id;
  return ss.str();
}

std::string getBidVar(const int id)
{
  return getVar(MVAR_BID_HEADER, id);
}

std::string getPathVar(int id)
{
  return getVar(MVAR_PATH_HEADER, id);
}

std::string getPathVarVal(std::string sPath)
{
  std::stringstream ss;
  ss << MVAR_PATH << "=" << sPath;
  return ss.str();
}

Point pointFromString(std::string str)
{
  std::vector<std::string> points;
  boost::split(points, str, boost::is_any_of(","));
  assert(points.size() == 2);
  return std::make_pair(
      boost::lexical_cast<double>(points.front()),
      boost::lexical_cast<double>(points.back()));
}

void pathFromString(std::string str, std::vector<Point> &path)
{
  std::vector<std::string> locs;
  boost::split(locs, str, boost::is_any_of(":"));
  path.reserve(locs.size());
  for (std::vector<std::string>::iterator it = locs.begin(); it != locs.end();
      it++)
  {
    path.push_back(pointFromString(*it));
  }
}

size_t getStringPathSize(std::string sPath)
{
  std::vector<std::string> locs;
  boost::split(locs, sPath, boost::is_any_of(":"));
  return locs.size();
}

double getDistance(const Point p1, const Point p2)
{
  return std::sqrt(
      std::pow(p2.first - p1.first, 2) + std::pow(p2.second - p1.second, 2));
}

int nthTriangularNumber(const int n)
{
  int sum = 0;
  for (int i = 1; i <= n; i++)
    sum += i;
  return sum;
}

void connectEdges(std::vector<Point> targets, std::vector<Edge> &edges,
    std::vector<mbogo_weight_t> &weights)
{
  size_t numTargets = targets.size();
  int numEdges = nthTriangularNumber(targets.size());
  Point *targs = targets.data();

  edges.reserve(numEdges);
  weights.reserve(numEdges);

  for (size_t i = 0; i < numTargets; i++)
  {
    for (size_t j = i + 1; j < numTargets; j++)
    {
      edges.push_back(std::make_pair(i, j));
      weights.push_back(getDistance(targs[i], targs[j]));
    }
  }
}


// Copyright (c) 2020 [Your Name]. All rights reserved.

#include <mylibrary/model.h>
#include <Eigen/Dense>
#include <fstream>
#include <iostream>
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/photo/photo.hpp"
#include "randomizedSVD.h"

namespace mylibrary {
    void computeDiagonalSigma(Vector <double, Dynamic> &sigma, MatrixXd &diagonal_sigma);

    bool IsValidFile(const std::string &kFileName) {
        std::ifstream infile(kFileName);
        if (!infile.good()) {
            return false;
        }
        return !(kFileName.substr(kFileName.length() - 4) != "jpeg" && kFileName.substr(kFileName.length() - 3) != "jpg"
                 && kFileName.substr(kFileName.length() - 3) != "png");
    }

    void SharpenImage(const std::string &kFileName, const double cons, const bool rewrite_images, const bool new_file) {

        Mat image_cv = imread(kFileName, IMREAD_GRAYSCALE);

        Mat original = imread(kFileName, IMREAD_GRAYSCALE);

        DenoiseImage(image_cv);

        Mat laplacian;

        Laplacian(image_cv, laplacian, CV_16S, 1, 1, 0, BORDER_DEFAULT);

        Mat dst;

        convertScaleAbs(laplacian, dst);

        Mat show = original - cons*dst;

        if (rewrite_images) {
            imwrite(kFileName, show);
        } else if (new_file) {
            imwrite(CopyFile(kFileName), show);
        }

        imshow("Sharpen", show);
    }

    void DenoiseImage(Mat &image_cv) {
        //blur(image_cv, image_cv, Size(3,3), Point(-1,-1), BORDER_DEFAULT);
       GaussianBlur( image_cv, image_cv, Size(3,3), 0, 0, BORDER_DEFAULT );
        //medianBlur(image_cv, image_cv, 5);
    }

    std::string CopyFile(const std::string &kFileName) {
        if (kFileName.substr(kFileName.length() - 5) == ".jpeg") {
            std::string add_to_string = "Copy.jpeg";
            return kFileName.substr(0, kFileName.size() - 5) + add_to_string;
        } else if (kFileName.substr(kFileName.length() - 4) == ".jpg") {
            std::string add_to_string = "Copy.jpg";
            return kFileName.substr(0, kFileName.size() - 4) + add_to_string;
        } else {
            std::string add_to_string = "Copy.png";
            return kFileName.substr(0, kFileName.size() - 4) + add_to_string;
        }
    }

    bool CompressImage(const std::string &kFileName, const double kCompression, const bool kRewriteImage, const bool kMakeNewFile) {

        Mat image_cv = imread(kFileName, IMREAD_GRAYSCALE);
        if (kCompression == 1.0) {
            imshow("Compression", image_cv);
            return true;
        } else if (kCompression < 0 || kCompression > 1) {
            return false;
        }

        MatrixXf image_eigen;
        cv2eigen(image_cv, image_eigen);

        //take svd of matrix
        BDCSVD<MatrixXf> svd(image_eigen, Eigen::ComputeFullU | Eigen::ComputeFullV);

        //separating svd into its components
        Eigen::Vector<double, Dynamic> sigma = svd.singularValues().cast<double>();

        MatrixXd diagonal_sigma(sigma.rows(), sigma.rows());

        //this function essentially creates a diagonal matrix from the singular values
        computeDiagonalSigma(sigma, diagonal_sigma);

        Matrix<double, Dynamic, Dynamic> U = svd.matrixU().cast<double>();
        Matrix<double, Dynamic, Dynamic> Vt = svd.matrixV().transpose().cast<double>();

        //sums all the singular values
        unsigned int i = 0;
        double sum = 0;
        while (i < sigma.size()) {
            sum += sigma[i];
            ++i;
        }

        //determines low rank by finding which singular values still results in temp_sum < kCompression * sum
        unsigned int rank = 0;
        double temp_sum = 0;

        while (temp_sum <= kCompression * sum) {
            temp_sum += sigma[rank];
            ++rank;
        }

        //creates low rank approximation by multiplying sigma[i] * the ith column of U * ith row of Vt
        Matrix<double, Dynamic, Dynamic> compressed_image = sigma[0] * U(all, 0) * Vt(0, all);
        for (int index = 1; index < rank; ++index) {
            compressed_image += sigma[index] * U(all, index) * Vt(index, all);
        }

        //essentially converts matrix to something opencv can convert to an image
       Matrix<int, Dynamic, Dynamic> int_compressed = compressed_image.cast<int>();
       eigen2cv(int_compressed, image_cv);
       Mat final;
       convertScaleAbs(image_cv, final);

        if (kRewriteImage) {
            imwrite(kFileName, final);
        } else if (kMakeNewFile) {
            imwrite(CopyFile(kFileName), final);
        }

       imshow("Compression", final);
       return true;
    }
    void computeDiagonalSigma(Vector <double, Dynamic> &sigma, MatrixXd &diagonal_sigma) {
        diagonal_sigma.setZero();
        for (unsigned int i = 0; i < sigma.rows(); ++i) {
            diagonal_sigma(i,i) = sigma(i);
        }

    }

}  // namespace mylibrary


// Copyright (c) 2005 - 2015 Marc de Kamps
// All rights reserved.
//
// 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.
//    * 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 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
// USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#define BOOST_TEST_DYN_LINK
#include <boost/test/unit_test.hpp>
#include <TwoDLib.hpp>
#include <vector>
#include <iostream>

using namespace std;
using namespace TwoDLib;

BOOST_AUTO_TEST_CASE(TriangleCreationTest)
{
	vector<double> vec_v(3);
	vector<double> vec_w(3);

	vec_v[0] = 0.;
	vec_v[1] = 1.;
	vec_v[2] = 0.;

	vec_w[0] = 0.;
	vec_w[1] = 0.;
	vec_w[2] = 1.;

	Triangle tri(vec_v, vec_w);

	BOOST_REQUIRE( tri.SignedArea()  ==  0.5);
	BOOST_REQUIRE( tri.IsClockwise() == -1);
}

BOOST_AUTO_TEST_CASE(TriangleInsideTest)
{
	vector<double> vec_v(3);
	vector<double> vec_w(3);

	vec_v[0] = 0.;
	vec_v[1] = 1.;
	vec_v[2] = 0.;

	vec_w[0] = 0.;
	vec_w[1] = 0.;
	vec_w[2] = 1.;

	Triangle tri(vec_v, vec_w);

	Point p1(0.1,0.1);
	BOOST_REQUIRE( tri.IsInside(p1) == 1);
	Point p2(1.0,1.0);
	BOOST_REQUIRE( tri.IsInside(p2) == 0);
}


#include <boost/test/unit_test.hpp>
#include "algorithms/math/sum_of_multiples.hpp"

BOOST_AUTO_TEST_SUITE(TestSumOfMultiples)

BOOST_AUTO_TEST_CASE(test)
{
    SumOfMultiples::Solution solution;
    BOOST_CHECK(solution.SumOfMultiples(3, 5, 1000) == 233168);
}

BOOST_AUTO_TEST_SUITE_END()


/*    Copyright (c) 2010-2015, Delft University of Technology
 *    All rights reserved.
 *
 *    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.
 *      - Neither the name of the Delft University of Technology 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.
 *
 *    Changelog
 *      YYMMDD    Author            Comment
 *      140219    E. Brandon        File copied from Newton-Raphson unit test.
 *      150417    D. Dirkx          Made modifications for templated root finding.
 *
 *    References
 *
 *    Notes
 *      This unit test does not include testing with the function
 *      testFunctionWithLargeRootDifferences, because this test function does not provide a second
 *      derivative.
 *
 */

#include <boost/bind.hpp>
#include <boost/make_shared.hpp>
#include <boost/test/floating_point_comparison.hpp>
#include <boost/test/unit_test.hpp>

#include "Tudat/Mathematics/RootFinders/halleyRootFinder.h"
#include "Tudat/Mathematics/RootFinders/UnitTests/testFunction1.h"
#include "Tudat/Mathematics/RootFinders/UnitTests/testFunction2.h"
#include "Tudat/Mathematics/RootFinders/UnitTests/testFunction3.h"
#include "Tudat/Mathematics/RootFinders/UnitTests/testFunctionWithZeroRoot.h"

namespace tudat
{
namespace unit_tests
{

BOOST_AUTO_TEST_SUITE( testsuite_rootfinders )

using namespace tudat;
using namespace root_finders;
using namespace root_finders::termination_conditions;

//! Check if Halley method converges on test function #1 (TestFunction1).
BOOST_AUTO_TEST_CASE( test_halleyRootFinder_testFunction1 )
{
    // Create object containing the test functions.
    boost::shared_ptr< TestFunction1 > testFunction = boost::make_shared< TestFunction1 >( 2 );

    // The termination condition.
    HalleyRootFinder::TerminationFunction terminationConditionFunction =
            boost::bind( &RootAbsoluteToleranceTerminationCondition< double >::checkTerminationCondition,
                         boost::make_shared< RootAbsoluteToleranceTerminationCondition< double > >(
                             testFunction->getTrueRootAccuracy( ) ), _1, _2, _3, _4, _5 );

    // Test Halley object.
    HalleyRootFinder halleyRootFinder( terminationConditionFunction );

    // Let the Halley method search for the root.
    const double root = halleyRootFinder.execute( testFunction, testFunction->getInitialGuess( ) );

    // Check if the result is within the requested accuracy.
    BOOST_CHECK_CLOSE_FRACTION( root, testFunction->getTrueRootLocation( ), 1.0e-15 );
    BOOST_CHECK_LT( testFunction->evaluate( root ), testFunction->getTrueRootAccuracy( ) );
}

//! Check if Halley method converges on test function #2 (TestFunction2).
BOOST_AUTO_TEST_CASE( test_halleyRootFinder_testFunction2 )
{
    // Create object containing the test functions.
    boost::shared_ptr< TestFunction2 > testFunction = boost::make_shared< TestFunction2 >( 2 );

    // The termination condition.
    HalleyRootFinder::TerminationFunction terminationConditionFunction =
            boost::bind( &RootAbsoluteToleranceTerminationCondition< double >::checkTerminationCondition,
                         boost::make_shared< RootAbsoluteToleranceTerminationCondition< double > >(
                             testFunction->getTrueRootAccuracy( ) ), _1, _2, _3, _4, _5 );

    // Test Halley object.
    HalleyRootFinder halleyRootFinder( terminationConditionFunction );

    // Let the Halley method search for the root.
    const double root = halleyRootFinder.execute( testFunction, testFunction->getInitialGuess( ) );

    // Check if the result is within the requested accuracy.
    BOOST_CHECK_CLOSE_FRACTION( root, testFunction->getTrueRootLocation( ), 1.0e-15 );
    BOOST_CHECK_LT( testFunction->evaluate( root ), testFunction->getTrueRootAccuracy( ) );
}

//! Check if Halley method converges on test function #3 (TestFunction3).
BOOST_AUTO_TEST_CASE( test_halleyRootFinder_testFunction3 )
{
    // Create object containing the test functions.
    boost::shared_ptr< TestFunction3 > testFunction = boost::make_shared< TestFunction3 >( 2 );

    // The termination condition.
    HalleyRootFinder::TerminationFunction terminationConditionFunction =
            boost::bind( &RootAbsoluteToleranceTerminationCondition< double >::checkTerminationCondition,
                         boost::make_shared< RootAbsoluteToleranceTerminationCondition< double > >(
                             testFunction->getTrueRootAccuracy( ) ), _1, _2, _3, _4, _5 );

    // Test Halley object.
    HalleyRootFinder halleyRootFinder( terminationConditionFunction );

    // Let the Halley method search for the root.
    const double root = halleyRootFinder.execute( testFunction, testFunction->getInitialGuess( ) );

    // Check if the result is within the requested accuracy.
    BOOST_CHECK_CLOSE_FRACTION( root, testFunction->getTrueRootLocation( ), 1.0e-15 );
    BOOST_CHECK_LT( testFunction->evaluate( root ), testFunction->getTrueRootAccuracy( ) );
}

//! Check if Halley method converges on function with zero root (testFunctionWithZeroRoot).
// Not the best test case. Inheritance from old code. Not really relevant anymore. The basic
// idea is that Halley's method should work for both a function that becomes zero, as well as for a
// function that does not become zero. A better case should be written.
BOOST_AUTO_TEST_CASE( test_halleyRootFinder_testFunctionWithZeroRoot )
{
    // Create object containing the test functions.
    boost::shared_ptr< TestFunctionWithZeroRoot > testFunction =
            boost::make_shared< TestFunctionWithZeroRoot >( 2 );

    // The termination condition.
    HalleyRootFinder::TerminationFunction terminationConditionFunction
            = boost::bind( &RootAbsoluteToleranceTerminationCondition< double >::
                           checkTerminationCondition,
                           boost::make_shared< RootAbsoluteToleranceTerminationCondition< double > >(
                               1.0e-150 ), _1, _2, _3, _4, _5 );

    // Test Halley object.
    HalleyRootFinder halleyRootFinder( terminationConditionFunction );

    // Let the Halley method search for the root.
    const double root = halleyRootFinder.execute( testFunction, testFunction->getInitialGuess( ) );

    // Check if the result is within the requested accuracy.
    BOOST_CHECK_SMALL( root, 1.0e-100 );
    BOOST_CHECK_SMALL( testFunction->evaluate( root ), 1.0e-200 );
}

BOOST_AUTO_TEST_SUITE_END( ) // testsuite_rootfinders

} // namespace unit_tests
} // namespace tudat


//==============================================================================
//         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::make_real"

#include <boost/mpl/placeholders.hpp>
#include <boost/simd/sdk/config/types.hpp>
#include <boost/dispatch/meta/make_floating.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/add_pointer.hpp>
#include <nt2/sdk/unit/module.hpp>
#include <nt2/sdk/unit/tests/basic.hpp>

////////////////////////////////////////////////////////////////////////////////
// Test make_floating output
////////////////////////////////////////////////////////////////////////////////
NT2_TEST_CASE(make_floating)
{
  using boost::dispatch::meta::make_floating;
  using boost::is_same;
  using namespace boost::simd;

  NT2_TEST( (is_same<float  , make_floating<4>::type >::value)  );
  NT2_TEST( (is_same<double , make_floating<8>::type >::value)  );
}

////////////////////////////////////////////////////////////////////////////////
// Test make_floating transformed output
////////////////////////////////////////////////////////////////////////////////
NT2_TEST_CASE(make_real_transform)
{
  using boost::dispatch::meta::make_floating;
  using boost::add_pointer;
  using boost::is_same;
  using boost::mpl::_;
  using namespace boost::simd;

  NT2_TEST( (is_same<float*  , make_floating<4, add_pointer<_> >::type >::value)  );
  NT2_TEST( (is_same<double* , make_floating<8, add_pointer<_> >::type >::value)  );
}


// graph-tool -- a general graph modification and manipulation thingy
//
// Copyright (C) 2006-2018 Tiago de Paula Peixoto <tiago@skewed.de>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

#ifndef GRAPH_CLOSENESS_HH
#define GRAPH_CLOSENESS_HH

#include <boost/graph/breadth_first_search.hpp>
#include <boost/graph/dijkstra_shortest_paths.hpp>

#include <boost/python/object.hpp>
#include <boost/python/list.hpp>
#include <boost/python/extract.hpp>

#include "histogram.hh"
#include "hash_map_wrap.hh"

namespace graph_tool
{
using namespace std;

struct no_weightS {};

template <class Map>
struct get_val_type
{
    typedef typename boost::property_traits<Map>::value_type type;
};

template <>
struct get_val_type<no_weightS>
{
    typedef size_t type;
};

struct get_closeness
{
    typedef void result_type;
    template <class Graph, class VertexIndex, class WeightMap, class Closeness>
    void operator()(const Graph& g, VertexIndex vertex_index, WeightMap weights,
                    Closeness closeness, bool harmonic, bool norm)
        const
    {
        using namespace boost;

        // select get_vertex_dists based on the existence of weights
        typedef typename mpl::if_<std::is_same<WeightMap, no_weightS>,
                                  get_dists_bfs,
                                  get_dists_djk>::type get_vertex_dists_t;

        // distance type
        typedef typename get_val_type<WeightMap>::type val_type;

        get_vertex_dists_t get_vertex_dists;
        size_t HN = HardNumVertices()(g);
        parallel_vertex_loop
            (g,
             [&](auto v)
             {
                 unchecked_vector_property_map<val_type,VertexIndex>
                     dist_map(vertex_index, num_vertices(g));

                 for (auto u : vertices_range(g))
                     dist_map[u] = numeric_limits<val_type>::max();

                 dist_map[v] = 0;

                 size_t comp_size = 0;
                 get_vertex_dists(g, v, vertex_index, dist_map, weights, comp_size);

                 closeness[v] = 0;
                 for (auto v2 : vertices_range(g))
                 {
                     if (v2 != v && dist_map[v2] != numeric_limits<val_type>::max())
                     {
                         if (!harmonic)
                             closeness[v] += dist_map[v2];
                         else
                             closeness[v] += 1. / dist_map[v2];
                     }
                 }

                 if (!harmonic)
                     closeness[v] = 1 / closeness[v];

                 if (norm)
                 {
                     if (harmonic)
                         closeness[v] /= HN - 1;
                     else
                         closeness[v] *= comp_size - 1;
                 }
             });
    }

    class component_djk_visitor: public boost::dijkstra_visitor<>
    {
    public:
        //component_visitor() { }
        component_djk_visitor(size_t& comp_size)
            : _comp_size(comp_size) { }

        template <class Vertex, class Graph>
        void discover_vertex(Vertex, const Graph&)
        {
            ++_comp_size;
        }

    private:
        size_t& _comp_size;
    };

    // weighted version. Use dijkstra_shortest_paths()
    struct get_dists_djk
    {
        template <class Graph, class Vertex, class VertexIndex,
                  class DistanceMap, class WeightMap>
        void operator()(const Graph& g, Vertex s, VertexIndex vertex_index,
                        DistanceMap dist_map, WeightMap weights,
                        size_t& comp_size) const
        {
            using namespace boost;
            component_djk_visitor vis(comp_size);
            dijkstra_shortest_paths(g, s, vertex_index_map(vertex_index).
                                    weight_map(weights).distance_map(dist_map).visitor(vis));
        }
    };

    template <class DistMap>
    class component_bfs_visitor: public boost::bfs_visitor<>
    {
    public:
        //component_visitor() { }
        component_bfs_visitor(DistMap dist_map, size_t& comp_size)
            : _dist_map(dist_map), _comp_size(comp_size) { }

        template <class Vertex, class Graph>
        void discover_vertex(Vertex, const Graph&)
        {
            ++_comp_size;
        }

        template <class Edge, class Graph>
        void tree_edge(Edge e, const Graph& g)
        {
            _dist_map[target(e, g)] = _dist_map[source(e, g)] + 1;
        }

    private:
        DistMap _dist_map;
        size_t& _comp_size;
    };

    // unweighted version. Use BFS.
    struct get_dists_bfs
    {
        template <class Graph, class Vertex, class VertexIndex,
                  class DistanceMap>
        void operator()(const Graph& g, Vertex s, VertexIndex vertex_index,
                        DistanceMap dist_map, no_weightS, size_t& comp_size) const
        {
            using namespace boost;
            typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
            typedef gt_hash_map<vertex_t,default_color_type,
                                DescriptorHash<VertexIndex> > cmap_t;
            cmap_t cmap(0, DescriptorHash<VertexIndex>(vertex_index));
            InitializedPropertyMap<cmap_t>
                color_map(cmap, color_traits<default_color_type>::white());
            component_bfs_visitor<DistanceMap> vis(dist_map, comp_size);
            breadth_first_visit(g, s, visitor(vis).
                                color_map(color_map));
        }
    };
};

} // boost namespace

#endif // GRAPH_CLOSENESS_HH