diff --git a/stan/math/prim/fun/value_of.hpp b/stan/math/prim/fun/value_of.hpp index 7cc37ac9b2c..64286bbe0c3 100644 --- a/stan/math/prim/fun/value_of.hpp +++ b/stan/math/prim/fun/value_of.hpp @@ -67,7 +67,7 @@ inline auto value_of(const T& x) { * @param[in] M Matrix to be converted * @return Matrix of values **/ -template * = nullptr, +template * = nullptr, require_not_st_arithmetic* = nullptr> inline auto value_of(EigMat&& M) { return make_holder( @@ -77,6 +77,28 @@ inline auto value_of(EigMat&& M) { std::forward(M)); } +template * = nullptr, + require_not_st_arithmetic* = nullptr> +inline auto value_of(EigMat&& M) { + auto&& M_ref = to_ref(M); + using scalar_t = decltype(value_of(std::declval>())); + promote_scalar_t> ret(M_ref.rows(), + M_ref.cols()); + ret.reserve(M_ref.nonZeros()); + for (int k = 0; k < M_ref.outerSize(); ++k) { + for (typename std::decay_t::InnerIterator it(M_ref, k); it; ++it) { + ret.insert(it.row(), it.col()) = value_of(it.valueRef()); + } + } + ret.makeCompressed(); + return ret; +} +template * = nullptr, + require_st_arithmetic* = nullptr> +inline auto value_of(EigMat&& M) { + return std::forward(M); +} + } // namespace math } // namespace stan diff --git a/stan/math/prim/meta/is_eigen_dense_base.hpp b/stan/math/prim/meta/is_eigen_dense_base.hpp index 7b1ebc6cd1e..940f65bb2ef 100644 --- a/stan/math/prim/meta/is_eigen_dense_base.hpp +++ b/stan/math/prim/meta/is_eigen_dense_base.hpp @@ -33,6 +33,22 @@ using require_eigen_dense_base_t = require_t>>; /*! @} */ +/*! \ingroup require_eigens_types */ +/*! \defgroup eigen_dense_base_types eigen_dense_base_types */ +/*! \addtogroup eigen_dense_base_types */ +/*! @{ */ + +/*! \brief Require type satisfies @ref is_eigen_dense_base */ +/*! and value type satisfies `TypeCheck` */ +/*! @tparam TypeCheck The type trait to check the value type against */ +/*! @tparam Check The type to test @ref is_eigen_dense_base for and whose + * @ref value_type is checked with `TypeCheck` */ +template