#ifndef linalg2_hpp
#define linalg2_hpp

#include <cmath>
#include <complex>
#include <algorithm>
#include <Eigen/Core>
#include <Eigen/SVD>
#include <Eigen/Eigenvalues>

/**
 * Singular value decomposition of M-by-N matrix m such that
 *
 *     m == u * s.matrix().asDiagonal() * vh    // LAPACK convention
 *
 * and `(s >= 0).all()`.  Elements of s are in descending order.
 *
 * @tparam     Scalar type of elements of m, u, and vh
 * @tparam     M      number of rows in m
 * @tparam     N      number of columns in m
 * @param[in]  m      M-by-N matrix to be decomposed
 * @param[out] s      array of length min(M,N) to contain singular values
 * @param[out] u      M-by-M unitary matrix
 * @param[out] vh     N-by-N unitary matrix
 */
template<class Scalar, int M, int N>
void svd
(const Eigen::Matrix<Scalar, M, N>& m,
 Eigen::Array<double, (M < N ? M : N), 1>& s,
 Eigen::Matrix<Scalar, M, M>& u,
 Eigen::Matrix<Scalar, N, N>& vh)
{
    svd_lapack(m, s, u, vh);
}

#endif // linalg2_hpp
