// 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 = MatrixType::Zero(rows, cols);
    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))));
  }
}
