// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Hauke Heibel <hauke.heibel@gmail.com>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, 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 2 of
// the License, or (at your option) any later version.
//
// Eigen 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 Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.

#include "main.h"

#define EIGEN_OLD_NESTED

#include "Eigen/Core"
#include "Eigen/Array"
#include "Eigen/Geometry"

#include "bench/BenchTimer.h"

using namespace Eigen;

struct Transform2D
{
  static void run(int num_runs)
  {
    const Matrix2d T = Matrix2d::Random();
    const Vector2d t = Vector2d::Random();
    const Matrix2Xd pts = Matrix2Xd::Random(2,100);

    Matrix2Xd res;
    for (int i=0; i<num_runs; ++i)
    {
      run(res, T, pts, t);
    }
  }

  EIGEN_DONT_INLINE static void run(Matrix2Xd& res, const Matrix2d& T, const Matrix2Xd& pts, const Vector2d& t)
  {
    res = T * pts + Replicate<Vector2d,1,100>(t);
  }
};

struct ColwiseTransform2D
{
  static void run(int num_runs)
  {
    const Matrix2d T = Matrix2d::Random();
    const Vector2d t = Vector2d::Random();
    const Matrix2Xd pts = Matrix2Xd::Random(2,100);

    Matrix2Xd res;
    for (int i=0; i<num_runs; ++i)
    {
      run(res, T, pts, t);
    }
  }

  EIGEN_DONT_INLINE static void run(Matrix2Xd& res, const Matrix2d& T, const Matrix2Xd& pts, const Vector2d& t)
  {
    res = T * pts + Replicate<Vector2d,1,100>(t);
  }
};

struct LinearCombination
{
  typedef Eigen::Matrix<double,2,4> Matrix2x4d;

  static void run(int num_runs)
  {
    const Matrix2Xd pts = Matrix2Xd::Random(2,100);
    const Matrix2x4d coefs = Matrix2x4d::Random();

    Matrix2x4d linear_combined = Matrix2x4d::Zero();
    for (int i=0; i<num_runs; ++i)
    {
      for (int r=0; r<coefs.rows(); ++r)
      {
        for (int c=0; c<pts.cols()-coefs.cols()+1; ++c)
        {
          run(linear_combined, pts, coefs, r, c);
        }
      }
    }
  }

  EIGEN_DONT_INLINE static void run(Matrix2x4d& res, const Matrix2Xd& pts, const Matrix2x4d& coefs, int r, int c)
  {
    res += pts.block(0,c,2,coefs.cols()).cwise() * Replicate<Matrix2x4d::RowXpr,2,1>(coefs.row(r));
  }
};

template <typename VectorType>
struct VectorAddition
{
  typedef VectorType ReturnType;
  EIGEN_DONT_INLINE static VectorType run(int)
  {
    VectorType a,b,c,d;
    return a+b+c+d;
  }
};

template <typename MatrixType>
struct MatrixProduct
{
  typedef MatrixType ReturnType;
  EIGEN_DONT_INLINE static MatrixType run(int num_runs)
  {
    MatrixType a,b;
    return a*b;
  }
};

template <typename MatrixType>
struct MatrixScaling
{
  typedef MatrixType ReturnType;
  EIGEN_DONT_INLINE static MatrixType run(int num_runs)
  {
      typename ei_traits<MatrixType>::Scalar s;
      MatrixType a,b;
      return s*a;
  }
};

template<typename TestFunction>
EIGEN_DONT_INLINE void run(int num_runs)
{
  for (int outer_runs=0; outer_runs<30; ++outer_runs)
  {
    //BenchTimer timer;
    //const double start = timer.getTime();
    {
      TestFunction::run(num_runs);
    }
    //const double stop = timer.getTime();
    //std::cout << (stop-start)*1000.0 << " ms" << std::endl;
  }
}

template<typename TestFunction>
EIGEN_DONT_INLINE void run_direct(int num_runs = 1)
{
  for (int outer_runs=0; outer_runs<30; ++outer_runs)
  {
    // required to prevent that the compiler replaces the run-call by nop
    typename TestFunction::ReturnType return_type;
    for (int i=0; i<num_runs; ++i)
    {
      return_type += TestFunction::run(num_runs);
    }
  }
}

void test_nesting_profiling()
{
  const int num_runs = 10000;

  BenchTimer timer;
  const double start = timer.getTime();
  {
    // leads to better run-time
    run<Transform2D>(num_runs);
    run<ColwiseTransform2D>(num_runs);
    run<LinearCombination>(num_runs);
  }
  const double stop = timer.getTime();
  std::cout << (stop-start)*1000.0 << " ms" << std::endl;

  // leads to identical assembly
  run_direct< MatrixProduct<Matrix2d> >();
  run_direct< MatrixProduct<Matrix3d> >();
  run_direct< MatrixProduct<Matrix4d> >();

  // leads to identical assembly
  run_direct< MatrixScaling<Matrix2d> >();
  run_direct< MatrixScaling<Matrix3d> >();
  run_direct< MatrixScaling<Matrix4d> >();

  // leads to better assembly
  run_direct< VectorAddition<Vector4f> >();
  run_direct< VectorAddition<Vector4d> >();
  run_direct< VectorAddition<Vector4i> >();
}
