-
-
Notifications
You must be signed in to change notification settings - Fork 191
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2931 from stan-dev/feature/2845-tuple-fns
Add tuple-returning special functions
- Loading branch information
Showing
53 changed files
with
1,194 additions
and
71 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
#ifndef STAN_MATH_PRIM_FUN_CSR_EXTRACT_HPP | ||
#define STAN_MATH_PRIM_FUN_CSR_EXTRACT_HPP | ||
|
||
#include <stan/math/prim/fun/Eigen.hpp> | ||
#include <stan/math/prim/fun/to_ref.hpp> | ||
|
||
namespace stan { | ||
namespace math { | ||
|
||
/** \addtogroup csr_format | ||
* @{ | ||
*/ | ||
|
||
/** | ||
* Extract the non-zero values, column indexes for non-zero values, and | ||
* the NZE index for each entry from a sparse matrix. | ||
* | ||
* @tparam T type of elements in the matrix | ||
* @param[in] A sparse matrix. | ||
* @return a tuple W,V,U. | ||
*/ | ||
template <typename T> | ||
const std::tuple<Eigen::Matrix<T, Eigen::Dynamic, 1>, std::vector<int>, | ||
std::vector<int>> | ||
csr_extract(const Eigen::SparseMatrix<T, Eigen::RowMajor>& A) { | ||
auto a_nonzeros = A.nonZeros(); | ||
Eigen::Matrix<T, Eigen::Dynamic, 1> w | ||
= Eigen::Matrix<T, Eigen::Dynamic, 1>::Zero(a_nonzeros); | ||
std::vector<int> v(a_nonzeros); | ||
for (int nze = 0; nze < a_nonzeros; ++nze) { | ||
w[nze] = *(A.valuePtr() + nze); | ||
v[nze] = *(A.innerIndexPtr() + nze) + stan::error_index::value; | ||
} | ||
std::vector<int> u(A.outerSize() + 1); // last entry is garbage. | ||
for (int nze = 0; nze <= A.outerSize(); ++nze) { | ||
u[nze] = *(A.outerIndexPtr() + nze) + stan::error_index::value; | ||
} | ||
return std::make_tuple(std::move(w), std::move(v), std::move(u)); | ||
} | ||
|
||
/* Extract the non-zero values from a dense matrix by converting | ||
* to sparse and calling the sparse matrix extractor. | ||
* | ||
* @tparam T type of elements in the matrix | ||
* @tparam R number of rows, can be Eigen::Dynamic | ||
* @tparam C number of columns, can be Eigen::Dynamic | ||
* | ||
* @param[in] A dense matrix. | ||
* @return a tuple W,V,U. | ||
*/ | ||
template <typename T, require_eigen_dense_base_t<T>* = nullptr> | ||
const std::tuple<Eigen::Matrix<scalar_type_t<T>, Eigen::Dynamic, 1>, | ||
std::vector<int>, std::vector<int>> | ||
csr_extract(const T& A) { | ||
// conversion to sparse seems to touch data twice, so we need to call to_ref | ||
Eigen::SparseMatrix<scalar_type_t<T>, Eigen::RowMajor> B | ||
= to_ref(A).sparseView(); | ||
return csr_extract(B); | ||
} | ||
|
||
/** @} */ // end of csr_format group | ||
|
||
} // namespace math | ||
} // namespace stan | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
#ifndef STAN_MATH_PRIM_FUN_EIGENDECOMPOSE_HPP | ||
#define STAN_MATH_PRIM_FUN_EIGENDECOMPOSE_HPP | ||
|
||
#include <stan/math/prim/fun/Eigen.hpp> | ||
#include <stan/math/prim/err.hpp> | ||
|
||
namespace stan { | ||
namespace math { | ||
|
||
/** | ||
* Return the eigendecomposition of a (real-valued) matrix | ||
* | ||
* @tparam EigMat type of real matrix argument | ||
* @param[in] m matrix to find the eigendecomposition of. Must be square and | ||
* have a non-zero size. | ||
* @return A tuple V,D where V is a matrix where the columns are the | ||
* complex-valued eigenvectors of `m` and D is a complex-valued column vector | ||
* with entries the eigenvectors of `m` | ||
*/ | ||
template <typename EigMat, require_eigen_matrix_dynamic_t<EigMat>* = nullptr, | ||
require_not_vt_complex<EigMat>* = nullptr> | ||
inline std::tuple<Eigen::Matrix<complex_return_t<value_type_t<EigMat>>, -1, -1>, | ||
Eigen::Matrix<complex_return_t<value_type_t<EigMat>>, -1, 1>> | ||
eigendecompose(const EigMat& m) { | ||
if (unlikely(m.size() == 0)) { | ||
return std::make_tuple( | ||
Eigen::Matrix<complex_return_t<value_type_t<EigMat>>, -1, -1>(0, 0), | ||
Eigen::Matrix<complex_return_t<value_type_t<EigMat>>, -1, 1>(0, 1)); | ||
} | ||
check_square("eigendecompose", "m", m); | ||
|
||
using PlainMat = plain_type_t<EigMat>; | ||
const PlainMat& m_eval = m; | ||
|
||
Eigen::EigenSolver<PlainMat> solver(m_eval); | ||
return std::make_tuple(std::move(solver.eigenvectors()), | ||
std::move(solver.eigenvalues())); | ||
} | ||
|
||
/** | ||
* Return the eigendecomposition of a (complex-valued) matrix | ||
* | ||
* @tparam EigCplxMat type of complex matrix argument | ||
* @param[in] m matrix to find the eigendecomposition of. Must be square and | ||
* have a non-zero size. | ||
* @return A tuple V,D where V is a matrix where the columns are the | ||
* complex-valued eigenvectors of `m` and D is a complex-valued column vector | ||
* with entries the eigenvectors of `m` | ||
*/ | ||
template <typename EigCplxMat, | ||
require_eigen_matrix_dynamic_vt<is_complex, EigCplxMat>* = nullptr> | ||
inline std::tuple< | ||
Eigen::Matrix<complex_return_t<value_type_t<EigCplxMat>>, -1, -1>, | ||
Eigen::Matrix<complex_return_t<value_type_t<EigCplxMat>>, -1, 1>> | ||
eigendecompose(const EigCplxMat& m) { | ||
if (unlikely(m.size() == 0)) { | ||
return std::make_tuple( | ||
Eigen::Matrix<complex_return_t<value_type_t<EigCplxMat>>, -1, -1>(0, 0), | ||
Eigen::Matrix<complex_return_t<value_type_t<EigCplxMat>>, -1, 1>(0, 1)); | ||
} | ||
check_square("eigendecompose", "m", m); | ||
|
||
using PlainMat = Eigen::Matrix<scalar_type_t<EigCplxMat>, -1, -1>; | ||
const PlainMat& m_eval = m; | ||
|
||
Eigen::ComplexEigenSolver<PlainMat> solver(m_eval); | ||
|
||
return std::make_tuple(std::move(solver.eigenvectors()), | ||
std::move(solver.eigenvalues())); | ||
} | ||
|
||
} // namespace math | ||
} // namespace stan | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
#ifndef STAN_MATH_PRIM_FUN_EIGENDECOMPOSE_SYM_HPP | ||
#define STAN_MATH_PRIM_FUN_EIGENDECOMPOSE_SYM_HPP | ||
|
||
#include <stan/math/prim/meta.hpp> | ||
#include <stan/math/prim/err.hpp> | ||
#include <stan/math/prim/fun/Eigen.hpp> | ||
|
||
namespace stan { | ||
namespace math { | ||
|
||
/** | ||
* Return the eigendecomposition of the specified symmetric matrix. | ||
* | ||
* @tparam EigMat type of the matrix | ||
* @param m Specified matrix. | ||
* @return A tuple V,D where V is a matrix where the columns are the | ||
* eigenvectors of m, and D is a column vector of the eigenvalues of m. | ||
* The eigenvalues are in ascending order of magnitude, with the eigenvectors | ||
* provided in the same order. | ||
*/ | ||
template <typename EigMat, require_eigen_t<EigMat>* = nullptr, | ||
require_not_st_var<EigMat>* = nullptr> | ||
std::tuple<Eigen::Matrix<value_type_t<EigMat>, -1, -1>, | ||
Eigen::Matrix<value_type_t<EigMat>, -1, 1>> | ||
eigendecompose_sym(const EigMat& m) { | ||
if (unlikely(m.size() == 0)) { | ||
return std::make_tuple(Eigen::Matrix<value_type_t<EigMat>, -1, -1>(0, 0), | ||
Eigen::Matrix<value_type_t<EigMat>, -1, 1>(0, 1)); | ||
} | ||
using PlainMat = plain_type_t<EigMat>; | ||
const PlainMat& m_eval = m; | ||
check_symmetric("eigendecompose_sym", "m", m_eval); | ||
|
||
Eigen::SelfAdjointEigenSolver<PlainMat> solver(m_eval); | ||
return std::make_tuple(std::move(solver.eigenvectors()), | ||
std::move(solver.eigenvalues())); | ||
} | ||
|
||
} // namespace math | ||
} // namespace stan | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.