// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Hauke Heibel <hauke.heibel@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/.
// SPDX-License-Identifier: MPL-2.0

#include "main.h"

#include <Eigen/Core>
#include <Eigen/Geometry>

#include <Eigen/LU>   // required for MatrixBase::determinant
#include <Eigen/QR>   // required for HouseholderQR
#include <Eigen/SVD>  // required for SVD

using namespace Eigen;

//  Constructs a random matrix from the unitary group U(size).
template <typename T>
Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> randMatrixUnitary(int size) {
  typedef T Scalar;
  typedef Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> MatrixType;

  // The Q factor of the QR decomposition of a random matrix is a random unitary matrix.
  // HouseholderQR is numerically stable and always succeeds, unlike Gram-Schmidt.
  MatrixType Q = MatrixType::Random(size, size).householderQr().householderQ();
  return Q;
}

//  Constructs a random matrix from the special unitary group SU(size).
template <typename T>
Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> randMatrixSpecialUnitary(int size) {
  typedef T Scalar;

  typedef Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> MatrixType;

  // initialize unitary matrix
  MatrixType Q = randMatrixUnitary<Scalar>(size);

  // tweak the first column to make the determinant be 1
  Q.col(0) *= numext::conj(Q.determinant());

  return Q;
}

template <typename MatrixType>
void run_test(unsigned dim, int num_elements) {
  using std::abs;
  typedef typename internal::traits<MatrixType>::Scalar Scalar;
  typedef Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> MatrixX;
  typedef Matrix<Scalar, Eigen::Dynamic, 1> VectorX;

  // MUST be positive because in any other case det(cR_t) may become negative for
  // odd dimensions!
  const Scalar c = abs(internal::random<Scalar>());

  MatrixX R = randMatrixSpecialUnitary<Scalar>(dim);
  VectorX t = Scalar(50) * VectorX::Random(dim, 1);

  MatrixX cR_t = MatrixX::Identity(dim + 1, dim + 1);
  cR_t.block(0, 0, dim, dim) = c * R;
  cR_t.block(0, dim, dim, 1) = t;

  MatrixX src = MatrixX::Random(dim + 1, num_elements);
  src.row(dim) = Matrix<Scalar, 1, Dynamic>::Constant(num_elements, Scalar(1));

  MatrixX dst = cR_t * src;

  MatrixX cR_t_umeyama = umeyama(src.block(0, 0, dim, num_elements), dst.block(0, 0, dim, num_elements));

  const Scalar error = (cR_t_umeyama * src - dst).norm() / dst.norm();
  VERIFY(error < Scalar(40) * std::numeric_limits<Scalar>::epsilon());
}

template <typename Scalar, int Dimension>
void run_fixed_size_test(int num_elements) {
  using std::abs;
  typedef Matrix<Scalar, Dimension + 1, Dynamic> MatrixX;
  typedef Matrix<Scalar, Dimension + 1, Dimension + 1> HomMatrix;
  typedef Matrix<Scalar, Dimension, Dimension> FixedMatrix;
  typedef Matrix<Scalar, Dimension, 1> FixedVector;

  const int dim = Dimension;

  // MUST be positive because in any other case det(cR_t) may become negative for
  // odd dimensions!
  // Also if c is to small compared to t.norm(), problem is ill-posed (cf. Bug 744)
  const Scalar c = internal::random<Scalar>(0.5, 2.0);

  FixedMatrix R = randMatrixSpecialUnitary<Scalar>(dim);
  FixedVector t = Scalar(32) * FixedVector::Random(dim, 1);

  HomMatrix cR_t = HomMatrix::Identity(dim + 1, dim + 1);
  cR_t.block(0, 0, dim, dim) = c * R;
  cR_t.block(0, dim, dim, 1) = t;

  MatrixX src = MatrixX::Random(dim + 1, num_elements);
  src.row(dim) = Matrix<Scalar, 1, Dynamic>::Constant(num_elements, Scalar(1));

  MatrixX dst = cR_t * src;

  Block<MatrixX, Dimension, Dynamic> src_block(src, 0, 0, dim, num_elements);
  Block<MatrixX, Dimension, Dynamic> dst_block(dst, 0, 0, dim, num_elements);

  HomMatrix cR_t_umeyama = umeyama(src_block, dst_block);

  const Scalar error = (cR_t_umeyama * src - dst).squaredNorm();

  VERIFY(error < Scalar(16) * std::numeric_limits<Scalar>::epsilon());
}

EIGEN_DECLARE_TEST(umeyama) {
  for (int i = 0; i < g_repeat; ++i) {
    const int num_elements = internal::random<int>(40, 500);

    // works also for dimensions bigger than 3...
    for (unsigned dim = 2; dim < 8; ++dim) {
      CALL_SUBTEST_1(run_test<MatrixXd>(dim, num_elements));
      CALL_SUBTEST_2(run_test<MatrixXf>(dim, num_elements));
    }

    CALL_SUBTEST_3((run_fixed_size_test<float, 2>(num_elements)));
    CALL_SUBTEST_4((run_fixed_size_test<float, 3>(num_elements)));
    CALL_SUBTEST_5((run_fixed_size_test<float, 4>(num_elements)));

    CALL_SUBTEST_6((run_fixed_size_test<double, 2>(num_elements)));
    CALL_SUBTEST_7((run_fixed_size_test<double, 3>(num_elements)));
    CALL_SUBTEST_8((run_fixed_size_test<double, 4>(num_elements)));
  }

  // Those two calls don't compile and result in meaningful error messages!
  // umeyama(MatrixXcf(),MatrixXcf());
  // umeyama(MatrixXcd(),MatrixXcd());
}
