// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
//
// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include "main.h"
#include <Eigen/LeastSquares>

template<typename VectorType,
         typename HyperplaneType>
void makeNoisyCohyperplanarPoints(int numPoints,
                                  VectorType **points,
                                  HyperplaneType *hyperplane,
                                  typename VectorType::Scalar noiseAmplitude)
{
  typedef typename VectorType::Scalar Scalar;
  const int size = points[0]->size();
  // pick a random hyperplane, store the coefficients of its equation
  hyperplane->coeffs().resize(size + 1);
  for(int j = 0; j < size + 1; j++)
  {
    do {
      hyperplane->coeffs().coeffRef(j) = ei_random<Scalar>();
    } while(ei_abs(hyperplane->coeffs().coeff(j)) < 0.5);
  }

  // now pick numPoints random points on this hyperplane
  for(int i = 0; i < numPoints; i++)
  {
    VectorType& cur_point = *(points[i]);
    do
    {
      cur_point = VectorType::Random(size)/*.normalized()*/;
      // project cur_point onto the hyperplane
      Scalar x = - (hyperplane->coeffs().start(size).cwise()*cur_point).sum();
      cur_point *= hyperplane->coeffs().coeff(size) / x;
    } while( cur_point.norm() < 0.5
          || cur_point.norm() > 2.0 );
  }

  // add some noise to these points
  for(int i = 0; i < numPoints; i++ )
    *(points[i]) += noiseAmplitude * VectorType::Random(size);
}

template<typename VectorType>
void check_linearRegression(int numPoints,
                            VectorType **points,
                            const VectorType& original,
                            typename VectorType::Scalar tolerance)
{
  int size = points[0]->size();
  assert(size==2);
  VectorType result(size);
  linearRegression(numPoints, points, &result, 1);
  typename VectorType::Scalar error = (result - original).norm() / original.norm();
  VERIFY(ei_abs(error) < ei_abs(tolerance));
}

template<typename VectorType,
         typename HyperplaneType>
void check_fitHyperplane(int numPoints,
                         VectorType **points,
                         const HyperplaneType& original,
                         typename VectorType::Scalar tolerance)
{
  int size = points[0]->size();
  HyperplaneType result(size);
  fitHyperplane(numPoints, points, &result);
  result.coeffs() *= original.coeffs().coeff(size)/result.coeffs().coeff(size);
  typename VectorType::Scalar error = (result.coeffs() - original.coeffs()).norm() / original.coeffs().norm();
  std::cout << ei_abs(error) << "  xxx   " << ei_abs(tolerance) << std::endl;
  VERIFY(ei_abs(error) < ei_abs(tolerance));
}

void test_eigen2_regression()
{
  for(int i = 0; i < g_repeat; i++)
  {
#ifdef EIGEN_TEST_PART_1
    {
      Vector2f points2f [1000];
      Vector2f *points2f_ptrs [1000];
      for(int i = 0; i < 1000; i++) points2f_ptrs[i] = &(points2f[i]);
      Vector2f coeffs2f;
      Hyperplane<float,2> coeffs3f;
      makeNoisyCohyperplanarPoints(1000, points2f_ptrs, &coeffs3f, 0.01f);
      coeffs2f[0] = -coeffs3f.coeffs()[0]/coeffs3f.coeffs()[1];
      coeffs2f[1] = -coeffs3f.coeffs()[2]/coeffs3f.coeffs()[1];
      CALL_SUBTEST(check_linearRegression(10, points2f_ptrs, coeffs2f, 0.05f));
      CALL_SUBTEST(check_linearRegression(100, points2f_ptrs, coeffs2f, 0.01f));
      CALL_SUBTEST(check_linearRegression(1000, points2f_ptrs, coeffs2f, 0.002f));
    }
#endif
#ifdef EIGEN_TEST_PART_2
    {
      Vector2f points2f [1000];
      Vector2f *points2f_ptrs [1000];
      for(int i = 0; i < 1000; i++) points2f_ptrs[i] = &(points2f[i]);
      Hyperplane<float,2> coeffs3f;
      makeNoisyCohyperplanarPoints(1000, points2f_ptrs, &coeffs3f, 0.01f);
      CALL_SUBTEST(check_fitHyperplane(10, points2f_ptrs, coeffs3f, 0.05f));
      CALL_SUBTEST(check_fitHyperplane(100, points2f_ptrs, coeffs3f, 0.01f));
      CALL_SUBTEST(check_fitHyperplane(1000, points2f_ptrs, coeffs3f, 0.002f));
    }
#endif
#ifdef EIGEN_TEST_PART_3
    {
      Vector4d points4d [1000];
      Vector4d *points4d_ptrs [1000];
      for(int i = 0; i < 1000; i++) points4d_ptrs[i] = &(points4d[i]);
      Hyperplane<double,4> coeffs5d;
      makeNoisyCohyperplanarPoints(1000, points4d_ptrs, &coeffs5d, 0.01);
      CALL_SUBTEST(check_fitHyperplane(10, points4d_ptrs, coeffs5d, 0.05));
      CALL_SUBTEST(check_fitHyperplane(100, points4d_ptrs, coeffs5d, 0.01));
      CALL_SUBTEST(check_fitHyperplane(1000, points4d_ptrs, coeffs5d, 0.002));
    }
#endif
#ifdef EIGEN_TEST_PART_4
    {
      VectorXcd *points11cd_ptrs[1000];
      for(int i = 0; i < 1000; i++) points11cd_ptrs[i] = new VectorXcd(11);
      Hyperplane<std::complex<double>,Dynamic> *coeffs12cd = new Hyperplane<std::complex<double>,Dynamic>(11);
      makeNoisyCohyperplanarPoints(1000, points11cd_ptrs, coeffs12cd, 0.01);
      CALL_SUBTEST(check_fitHyperplane(100, points11cd_ptrs, *coeffs12cd, 0.025));
      CALL_SUBTEST(check_fitHyperplane(1000, points11cd_ptrs, *coeffs12cd, 0.006));
      delete coeffs12cd;
      for(int i = 0; i < 1000; i++) delete points11cd_ptrs[i];
    }
#endif
  }
}
