// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2021 Kolja Brix <kolja.brix@rwth-aachen.de>
//
// 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/SVD>


template<typename MatrixType>
void check_generateRandomUnitaryMatrix(const Index dim)
{
    const MatrixType Q = generateRandomUnitaryMatrix<MatrixType>(dim);

    // validate dimensions
    VERIFY_IS_EQUAL(Q.rows(), dim);
    VERIFY_IS_EQUAL(Q.cols(), dim);

    VERIFY_IS_UNITARY(Q);
}

template<typename VectorType, typename RealScalarType>
void check_setupRandomSvs(const Index dim, const RealScalarType max)
{
    const VectorType v = setupRandomSvs<VectorType, RealScalarType>(dim, max);

    // validate dimensions
    VERIFY_IS_EQUAL(v.size(), dim);

    // check entries
    for(Index i = 0; i < v.size(); ++i)
        VERIFY_GE(v(i), 0);
    for(Index i = 0; i < v.size()-1; ++i)
        VERIFY_GE(v(i), v(i+1));
}

template<typename VectorType, typename RealScalarType>
void check_setupRangeSvs(const Index dim, const RealScalarType min, const RealScalarType max)
{
    const VectorType v = setupRangeSvs<VectorType, RealScalarType>(dim, min, max);

    // validate dimensions
    VERIFY_IS_EQUAL(v.size(), dim);

    // check entries
    if(dim == 1) {
        VERIFY_IS_APPROX(v(0), min);
    } else {
        VERIFY_IS_APPROX(v(0), max);
        VERIFY_IS_APPROX(v(dim-1), min);
    }
    for(Index i = 0; i < v.size()-1; ++i)
        VERIFY_GE(v(i), v(i+1));
}

template<typename MatrixType, typename RealScalar, typename RealVectorType>
void check_generateRandomMatrixSvs(const Index rows, const Index cols, const Index diag_size,
                                   const RealScalar min_svs, const RealScalar max_svs)
{
    RealVectorType svs = setupRangeSvs<RealVectorType, RealScalar>(diag_size, min_svs, max_svs);

    MatrixType M;
    generateRandomMatrixSvs(svs, rows, cols, M);

    // validate dimensions
    VERIFY_IS_EQUAL(M.rows(), rows);
    VERIFY_IS_EQUAL(M.cols(), cols);
    VERIFY_IS_EQUAL(svs.size(), diag_size);

    // validate singular values
    Eigen::JacobiSVD<MatrixType> SVD(M);
    VERIFY_IS_APPROX(svs, SVD.singularValues());
}

template<typename MatrixType>
void check_random_matrix(const MatrixType &m)
{
    enum {
        Rows = MatrixType::RowsAtCompileTime,
        Cols = MatrixType::ColsAtCompileTime,
        DiagSize = internal::min_size_prefer_dynamic(Rows, Cols)
    };
    typedef typename MatrixType::Scalar Scalar;
    typedef typename NumTraits<Scalar>::Real RealScalar;
    typedef Matrix<RealScalar, DiagSize, 1> RealVectorType;

    const Index rows = m.rows(), cols = m.cols();
    const Index diag_size = (std::min)(rows, cols);
    const RealScalar min_svs = 1.0, max_svs = 1000.0;

    // check generation of unitary random matrices
    typedef Matrix<Scalar, Rows, Rows> MatrixAType;
    typedef Matrix<Scalar, Cols, Cols> MatrixBType;
    check_generateRandomUnitaryMatrix<MatrixAType>(rows);
    check_generateRandomUnitaryMatrix<MatrixBType>(cols);

    // test generators for singular values
    check_setupRandomSvs<RealVectorType, RealScalar>(diag_size, max_svs);
    check_setupRangeSvs<RealVectorType, RealScalar>(diag_size, min_svs, max_svs);

    // check generation of random matrices
    check_generateRandomMatrixSvs<MatrixType, RealScalar, RealVectorType>(rows, cols, diag_size, min_svs, max_svs);
}

EIGEN_DECLARE_TEST(random_matrix)
{
  for(int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_1(check_random_matrix(Matrix<float, 1, 1>()));
    CALL_SUBTEST_2(check_random_matrix(Matrix<float, 4, 4>()));
    CALL_SUBTEST_3(check_random_matrix(Matrix<float, 2, 3>()));
    CALL_SUBTEST_4(check_random_matrix(Matrix<float, 7, 4>()));

    CALL_SUBTEST_5(check_random_matrix(Matrix<double, 1, 1>()));
    CALL_SUBTEST_6(check_random_matrix(Matrix<double, 6, 6>()));
    CALL_SUBTEST_7(check_random_matrix(Matrix<double, 5, 3>()));
    CALL_SUBTEST_8(check_random_matrix(Matrix<double, 4, 9>()));

    CALL_SUBTEST_9(check_random_matrix(Matrix<std::complex<float>, 12, 12>()));
    CALL_SUBTEST_10(check_random_matrix(Matrix<std::complex<float>, 7, 14>()));
    CALL_SUBTEST_11(check_random_matrix(Matrix<std::complex<double>, 15, 11>()));
    CALL_SUBTEST_12(check_random_matrix(Matrix<std::complex<double>, 6, 9>()));

    CALL_SUBTEST_13(check_random_matrix(
        MatrixXf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
    CALL_SUBTEST_14(check_random_matrix(
        MatrixXd(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
    CALL_SUBTEST_15(check_random_matrix(
        MatrixXcf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
    CALL_SUBTEST_16(check_random_matrix(
        MatrixXcd(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
  }
}
