// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
// 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/.

#ifndef EIGEN_RANDOM_MATRIX_HELPER
#define EIGEN_RANDOM_MATRIX_HELPER

#include <typeinfo>
#include <Eigen/QR> // required for createRandomPIMatrixOfRank and generateRandomMatrixSvs


// Forward declarations to avoid ICC warnings
#if EIGEN_COMP_ICC

namespace Eigen {

template<typename MatrixType>
void createRandomPIMatrixOfRank(Index desired_rank, Index rows, Index cols, MatrixType& m);

template<typename PermutationVectorType>
void randomPermutationVector(PermutationVectorType& v, Index size);

template<typename MatrixType>
MatrixType generateRandomUnitaryMatrix(const Index dim);

template<typename MatrixType, typename RealScalarVectorType>
void generateRandomMatrixSvs(const RealScalarVectorType &svs, const Index rows, const Index cols, MatrixType& M);

template<typename VectorType, typename RealScalar>
VectorType setupRandomSvs(const Index dim, const RealScalar max);

template<typename VectorType, typename RealScalar>
VectorType setupRangeSvs(const Index dim, const RealScalar min, const RealScalar max);

} // end namespace Eigen

#endif  // EIGEN_COMP_ICC



namespace Eigen {

/**
 * Creates a random partial isometry matrix of given rank.
 *
 * A partial isometry is a matrix all of whose singular values are either 0 or 1.
 * This is very useful to test rank-revealing algorithms.
 *
 * @tparam MatrixType type of random partial isometry matrix
 * @param desired_rank rank requested for the random partial isometry matrix
 * @param rows row dimension of requested random partial isometry matrix
 * @param cols column dimension of requested random partial isometry matrix
 * @param m random partial isometry matrix
 */
template<typename MatrixType>
void createRandomPIMatrixOfRank(Index desired_rank, Index rows, Index cols, MatrixType& m)
{
  typedef typename internal::traits<MatrixType>::Scalar Scalar;
  enum { Rows = MatrixType::RowsAtCompileTime, Cols = MatrixType::ColsAtCompileTime };

  typedef Matrix<Scalar, Dynamic, 1> VectorType;
  typedef Matrix<Scalar, Rows, Rows> MatrixAType;
  typedef Matrix<Scalar, Cols, Cols> MatrixBType;

  if(desired_rank == 0)
  {
    m.setZero(rows,cols);
    return;
  }

  if(desired_rank == 1)
  {
    // here we normalize the vectors to get a partial isometry
    m = VectorType::Random(rows).normalized() * VectorType::Random(cols).normalized().transpose();
    return;
  }

  MatrixAType a = MatrixAType::Random(rows,rows);
  MatrixType d = MatrixType::Identity(rows,cols);
  MatrixBType  b = MatrixBType::Random(cols,cols);

  // set the diagonal such that only desired_rank non-zero entries remain
  const Index diag_size = (std::min)(d.rows(),d.cols());
  if(diag_size != desired_rank)
    d.diagonal().segment(desired_rank, diag_size-desired_rank) = VectorType::Zero(diag_size-desired_rank);

  HouseholderQR<MatrixAType> qra(a);
  HouseholderQR<MatrixBType> qrb(b);
  m = qra.householderQ() * d * qrb.householderQ();
}

/**
 * Generate random permutation vector.
 *
 * @tparam PermutationVectorType type of vector used to store permutation
 * @param v permutation vector
 * @param size length of permutation vector
 */
template<typename PermutationVectorType>
void randomPermutationVector(PermutationVectorType& v, Index size)
{
  typedef typename PermutationVectorType::Scalar Scalar;
  v.resize(size);
  for(Index i = 0; i < size; ++i) v(i) = Scalar(i);
  if(size == 1) return;
  for(Index n = 0; n < 3 * size; ++n)
  {
    Index i = internal::random<Index>(0, size-1);
    Index j;
    do j = internal::random<Index>(0, size-1); while(j==i);
    std::swap(v(i), v(j));
  }
}

/**
 * Generate a random unitary matrix of prescribed dimension.
 *
 * The algorithm is using a random Householder sequence to produce
 * a random unitary matrix.
 *
 * @tparam MatrixType type of matrix to generate
 * @param dim row and column dimension of the requested square matrix
 * @return random unitary matrix
 */
template<typename MatrixType>
MatrixType generateRandomUnitaryMatrix(const Index dim)
{
  typedef typename internal::traits<MatrixType>::Scalar Scalar;
  typedef Matrix<Scalar, Dynamic, 1> VectorType;

  MatrixType v = MatrixType::Identity(dim, dim);
  VectorType h = VectorType::Zero(dim);
  for (Index i = 0; i < dim; ++i)
  {
    v.col(i).tail(dim - i - 1) = VectorType::Random(dim - i - 1);
    h(i) = 2 / v.col(i).tail(dim - i).squaredNorm();
  }

  const Eigen::HouseholderSequence<MatrixType, VectorType> HSeq(v, h);
  return MatrixType(HSeq);
}

/**
 * Generation of random matrix with prescribed singular values.
 *
 * We generate random matrices with given singular values by setting up
 * a singular value decomposition. By choosing the number of zeros as
 * singular values we can specify the rank of the matrix.
 * Moreover, we also control its spectral norm, which is the largest
 * singular value, as well as its condition number with respect to the
 * l2-norm, which is the quotient of the largest and smallest singular
 * value.
 *
 * Reference: For details on the method see e.g. Section 8.1 (pp. 62 f) in
 *
 *   C. C. Paige, M. A. Saunders,
 *   LSQR: An algorithm for sparse linear equations and sparse least squares.
 *   ACM Transactions on Mathematical Software 8(1), pp. 43-71, 1982.
 *   https://web.stanford.edu/group/SOL/software/lsqr/lsqr-toms82a.pdf
 *
 * and also the LSQR webpage https://web.stanford.edu/group/SOL/software/lsqr/.
 *
 * @tparam MatrixType matrix type to generate
 * @tparam RealScalarVectorType vector type with real entries used for singular values
 * @param svs vector of desired singular values
 * @param rows row dimension of requested random matrix
 * @param cols column dimension of requested random matrix
 * @param M generated matrix with prescribed singular values
 */
template<typename MatrixType, typename RealScalarVectorType>
void generateRandomMatrixSvs(const RealScalarVectorType &svs, const Index rows, const Index cols, MatrixType& M)
{
  enum { Rows = MatrixType::RowsAtCompileTime, Cols = MatrixType::ColsAtCompileTime };
  typedef typename internal::traits<MatrixType>::Scalar Scalar;
  typedef Matrix<Scalar, Rows, Rows> MatrixAType;
  typedef Matrix<Scalar, Cols, Cols> MatrixBType;

  const Index min_dim = (std::min)(rows, cols);

  const MatrixAType U = generateRandomUnitaryMatrix<MatrixAType>(rows);
  const MatrixBType V = generateRandomUnitaryMatrix<MatrixBType>(cols);

  M = U.block(0, 0, rows, min_dim) * svs.asDiagonal() * V.block(0, 0, cols, min_dim).transpose();
}

/**
 * Setup a vector of random singular values with prescribed upper limit.
 * For use with generateRandomMatrixSvs().
 *
 * Singular values are non-negative real values. By convention (to be consistent with
 * singular value decomposition) we sort them in decreasing order.
 *
 * This strategy produces random singular values in the range [0, max], in particular
 * the singular values can be zero or arbitrarily close to zero.
 *
 * @tparam VectorType vector type with real entries used for singular values
 * @tparam RealScalar data type used for real entry
 * @param dim number of singular values to generate
 * @param max upper bound for singular values
 * @return vector of singular values
 */
template<typename VectorType, typename RealScalar>
VectorType setupRandomSvs(const Index dim, const RealScalar max)
{
  VectorType svs = max / RealScalar(2) * (VectorType::Random(dim) + VectorType::Ones(dim));
  std::sort(svs.begin(), svs.end(), std::greater<RealScalar>());
  return svs;
}

/**
 * Setup a vector of random singular values with prescribed range.
 * For use with generateRandomMatrixSvs().
 *
 * Singular values are non-negative real values. By convention (to be consistent with
 * singular value decomposition) we sort them in decreasing order.
 *
 * For dim > 1 this strategy generates a vector with largest entry max, smallest entry
 * min, and remaining entries in the range [min, max]. For dim == 1 the only entry is
 * min.
 *
 * @tparam VectorType vector type with real entries used for singular values
 * @tparam RealScalar data type used for real entry
 * @param dim number of singular values to generate
 * @param min smallest singular value to use
 * @param max largest singular value to use
 * @return vector of singular values
 */
template<typename VectorType, typename RealScalar>
VectorType setupRangeSvs(const Index dim, const RealScalar min, const RealScalar max)
{
  VectorType svs = VectorType::Random(dim);
  if(dim == 0)
    return svs;
  if(dim == 1)
  {
    svs(0) = min;
    return svs;
  }
  std::sort(svs.begin(), svs.end(), std::greater<RealScalar>());

  // scale to range [min, max]
  const RealScalar c_min = svs(dim - 1), c_max = svs(0);
  svs = (svs - VectorType::Constant(dim, c_min)) / (c_max - c_min);
  return min * (VectorType::Ones(dim) - svs) + max * svs;
}

} // end namespace Eigen

#endif // EIGEN_RANDOM_MATRIX_HELPER
