// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Jitse Niesen <jitse@maths.leeds.ac.uk>
//
// 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"
#include <Eigen/StdVector>
#include <unsupported/Eigen/MatrixFunctions>

double binom(int n, int k) 
{
  double res = 1;
  for (int i=0; i<k; i++)
    res = res * (n-k+i+1) / (i+1);
  return res;
}

void test2dRotation()
{
  Matrix2d A, B, C;
  double angle;

  for (int i=0; i<=20; i++) 
  {
    angle = pow(10, i / 5. - 2);
    A << 0, angle, -angle, 0;
    B << cos(angle), sin(angle), -sin(angle), cos(angle);
    ei_matrix_exponential(A, &C);
    VERIFY(C.isApprox(B, 1e-14));
  }
}

void testPascal()
{
  for (int size=1; size<20; size++)
  {
    MatrixXd A(size,size), B(size,size), C(size,size);
    A.setZero();
    for (int i=0; i<size-1; i++)
      A(i+1,i) = i+1;
    B.setZero();
    for (int i=0; i<size; i++)
      for (int j=0; j<=i; j++)
	B(i,j) = binom(i,j);
    ei_matrix_exponential(A, &C);
    VERIFY(C.isApprox(B, 1e-14));
  }
}

template<typename MatrixType> void randomTest(const MatrixType& m)
{
  /* this test covers the following files:
     Inverse.h
  */
  int rows = m.rows();
  int cols = m.cols();
  MatrixType m1(rows, cols), m2(rows, cols), m3(rows, cols),
             identity = MatrixType::Identity(rows, rows);

  for(int i = 0; i < g_repeat; i++) {
    m1 = MatrixType::Random(rows, cols);
    ei_matrix_exponential(m1, &m2);
    ei_matrix_exponential(-m1, &m3);
    VERIFY(identity.isApprox(m2 * m3, 1e-13));
  }
}

void test_matrixExponential()
{
  CALL_SUBTEST(test2dRotation());
  CALL_SUBTEST(testPascal());
  CALL_SUBTEST(randomTest(Matrix2d()));
  CALL_SUBTEST(randomTest(Matrix3d()));
  CALL_SUBTEST(randomTest(Matrix4d()));
  CALL_SUBTEST(randomTest(MatrixXd(8,8)));
}
