|
| 1 | +#ifndef STAN_MATH_PRIM_FUN_EIGENDECOMPOSE_HPP |
| 2 | +#define STAN_MATH_PRIM_FUN_EIGENDECOMPOSE_HPP |
| 3 | + |
| 4 | +#include <stan/math/prim/fun/Eigen.hpp> |
| 5 | +#include <stan/math/prim/err.hpp> |
| 6 | + |
| 7 | +namespace stan { |
| 8 | +namespace math { |
| 9 | + |
| 10 | +/** |
| 11 | + * Return the eigendecomposition of a (real-valued) matrix |
| 12 | + * |
| 13 | + * @tparam EigMat type of real matrix argument |
| 14 | + * @param[in] m matrix to find the eigendecomposition of. Must be square and |
| 15 | + * have a non-zero size. |
| 16 | + * @return A tuple V,D where V is a matrix where the columns are the |
| 17 | + * complex-valued eigenvectors of `m` and D is a complex-valued column vector |
| 18 | + * with entries the eigenvectors of `m` |
| 19 | + */ |
| 20 | +template <typename EigMat, require_eigen_matrix_dynamic_t<EigMat>* = nullptr, |
| 21 | + require_not_vt_complex<EigMat>* = nullptr> |
| 22 | +inline std::tuple<Eigen::Matrix<complex_return_t<value_type_t<EigMat>>, -1, -1>, |
| 23 | + Eigen::Matrix<complex_return_t<value_type_t<EigMat>>, -1, 1>> |
| 24 | +eigendecompose(const EigMat& m) { |
| 25 | + if (unlikely(m.size() == 0)) { |
| 26 | + return std::make_tuple( |
| 27 | + Eigen::Matrix<complex_return_t<value_type_t<EigMat>>, -1, -1>(0, 0), |
| 28 | + Eigen::Matrix<complex_return_t<value_type_t<EigMat>>, -1, 1>(0, 1)); |
| 29 | + } |
| 30 | + check_square("eigendecompose", "m", m); |
| 31 | + |
| 32 | + using PlainMat = plain_type_t<EigMat>; |
| 33 | + const PlainMat& m_eval = m; |
| 34 | + |
| 35 | + Eigen::EigenSolver<PlainMat> solver(m_eval); |
| 36 | + return std::make_tuple(std::move(solver.eigenvectors()), |
| 37 | + std::move(solver.eigenvalues())); |
| 38 | +} |
| 39 | + |
| 40 | +/** |
| 41 | + * Return the eigendecomposition of a (complex-valued) matrix |
| 42 | + * |
| 43 | + * @tparam EigCplxMat type of complex matrix argument |
| 44 | + * @param[in] m matrix to find the eigendecomposition of. Must be square and |
| 45 | + * have a non-zero size. |
| 46 | + * @return A tuple V,D where V is a matrix where the columns are the |
| 47 | + * complex-valued eigenvectors of `m` and D is a complex-valued column vector |
| 48 | + * with entries the eigenvectors of `m` |
| 49 | + */ |
| 50 | +template <typename EigCplxMat, |
| 51 | + require_eigen_matrix_dynamic_vt<is_complex, EigCplxMat>* = nullptr> |
| 52 | +inline std::tuple< |
| 53 | + Eigen::Matrix<complex_return_t<value_type_t<EigCplxMat>>, -1, -1>, |
| 54 | + Eigen::Matrix<complex_return_t<value_type_t<EigCplxMat>>, -1, 1>> |
| 55 | +eigendecompose(const EigCplxMat& m) { |
| 56 | + if (unlikely(m.size() == 0)) { |
| 57 | + return std::make_tuple( |
| 58 | + Eigen::Matrix<complex_return_t<value_type_t<EigCplxMat>>, -1, -1>(0, 0), |
| 59 | + Eigen::Matrix<complex_return_t<value_type_t<EigCplxMat>>, -1, 1>(0, 1)); |
| 60 | + } |
| 61 | + check_square("eigendecompose", "m", m); |
| 62 | + |
| 63 | + using PlainMat = Eigen::Matrix<scalar_type_t<EigCplxMat>, -1, -1>; |
| 64 | + const PlainMat& m_eval = m; |
| 65 | + |
| 66 | + Eigen::ComplexEigenSolver<PlainMat> solver(m_eval); |
| 67 | + |
| 68 | + return std::make_tuple(std::move(solver.eigenvectors()), |
| 69 | + std::move(solver.eigenvalues())); |
| 70 | +} |
| 71 | + |
| 72 | +} // namespace math |
| 73 | +} // namespace stan |
| 74 | +#endif |
0 commit comments