From 414e086974b17fa6b6d5f1d47a523866ca08faa6 Mon Sep 17 00:00:00 2001 From: Steve Bronder Date: Wed, 10 Feb 2021 21:28:55 -0500 Subject: [PATCH 01/29] update reader with template for Jacobian --- src/stan/io/reader.hpp | 1053 +++++++++++++++++--- src/test/unit/io/reader2_test.cpp | 1551 +++++++++++++++++++++++++++++ src/test/unit/io/reader_test.cpp | 14 + 3 files changed, 2489 insertions(+), 129 deletions(-) create mode 100644 src/test/unit/io/reader2_test.cpp diff --git a/src/stan/io/reader.hpp b/src/stan/io/reader.hpp index 05931c61589..dcfc8fd0d2f 100644 --- a/src/stan/io/reader.hpp +++ b/src/stan/io/reader.hpp @@ -34,8 +34,8 @@ namespace io { template class reader { private: - Eigen::Map> data_r_; - Eigen::Map> data_i_; + Eigen::Map> data_r_; + Eigen::Map> data_i_; size_t pos_{0}; size_t int_pos_{0}; @@ -161,6 +161,7 @@ class reader { * log_prob Reference to log probability variable to increment. * @return Next scalar. */ + template inline T scalar_constrain(T & /*log_prob*/) { return scalar(); } /** @@ -226,9 +227,7 @@ class reader { * @return Column vector made up of the next scalars. */ inline auto vector_constrain(size_t m) { - if (m == 0) - return map_vector_t(nullptr, m); - return map_vector_t(&scalar_ptr_increment(m), m); + return this->vector(m); } /** * Return a column vector of specified dimensionality made up of @@ -238,10 +237,35 @@ class reader { * lp Log probability to increment. * @return Column vector made up of the next scalars. */ + template inline auto vector_constrain(size_t m, T & /*lp*/) { - if (m == 0) - return map_vector_t(nullptr, m); - return map_vector_t(&scalar_ptr_increment(m), m); + return this->vector(m); + } + + /** + * Return a column vector of specified dimensionality made up of + * the next scalars. The constraint and hence Jacobian are no-ops. + * + * @param m Number of rows in the vector to read. + * lp Log probability to increment. + * @return Column vector made up of the next scalars. + */ + template * = nullptr> + inline auto var_vector_constrain(size_t m, T & /*lp*/) { + return this->vector(m); + } + + /** + * Return a column vector of specified dimensionality made up of + * the next scalars. The constraint and hence Jacobian are no-ops. + * + * @param m Number of rows in the vector to read. + * lp Log probability to increment. + * @return Column vector made up of the next scalars. + */ + template * = nullptr> + inline auto var_vector_constrain(size_t m, T & /*lp*/) { + return this->var_vector(m); } /** @@ -292,9 +316,7 @@ class reader { * @return Column vector made up of the next scalars. */ inline auto row_vector_constrain(size_t m) { - if (m == 0) - return map_row_vector_t(nullptr, m); - return map_row_vector_t(&scalar_ptr_increment(m), m); + return this->row_vector(m); } /** @@ -306,10 +328,37 @@ class reader { * lp Log probability to increment. * @return Column vector made up of the next scalars. */ + template inline auto row_vector_constrain(size_t m, T & /*lp*/) { - if (m == 0) - return map_row_vector_t(nullptr, m); - return map_row_vector_t(&scalar_ptr_increment(m), m); + return this->row_vector(m); + } + + /** + * Return a row vector of specified dimensionality made up of + * the next scalars. The constraint is a no-op, so the log + * probability is not incremented. + * + * @param m Number of rows in the vector to read. + * lp Log probability to increment. + * @return Column vector made up of the next scalars. + */ + template * = nullptr> + inline auto var_row_vector_constrain(size_t m, T & /*lp*/) { + return this->var_row_vector(m); + } + + /** + * Return a row vector of specified dimensionality made up of + * the next scalars. The constraint is a no-op, so the log + * probability is not incremented. + * + * @param m Number of rows in the vector to read. + * lp Log probability to increment. + * @return Column vector made up of the next scalars. + */ + template * = nullptr> + inline auto var_row_vector_constrain(size_t m, T & /*lp*/) { + return this->var_row_vector(m); } /** @@ -330,9 +379,11 @@ class reader { * @return Eigen::Matrix made up of the next scalars. */ inline auto matrix(size_t m, size_t n) { - if (m == 0 || n == 0) + if (m == 0 || n == 0) { return map_matrix_t(nullptr, m, n); - return map_matrix_t(&scalar_ptr_increment(m * n), m, n); + } else { + return map_matrix_t(&scalar_ptr_increment(m * n), m, n); + } } /** @@ -354,10 +405,12 @@ class reader { */ template * = nullptr> inline var_matrix_t var_matrix(size_t m, size_t n) { - if (m == 0 || n == 0) + if (m == 0 || n == 0) { return var_matrix_t(Eigen::MatrixXd(0, 0)); - return stan::math::to_var_value( - map_matrix_t(&scalar_ptr_increment(m * n), m, n)); + } else { + return stan::math::to_var_value( + map_matrix_t(&scalar_ptr_increment(m * n), m, n)); + } } /** @@ -393,9 +446,7 @@ class reader { * @return Matrix made up of the next scalars. */ inline auto matrix_constrain(size_t m, size_t n) { - if (m == 0 || n == 0) - return map_matrix_t(nullptr, m, n); - return map_matrix_t(&scalar_ptr_increment(m * n), m, n); + return this->matrix(m, n); } /** @@ -410,10 +461,43 @@ class reader { * lp Log probability to increment. * @return Matrix made up of the next scalars. */ + template inline auto matrix_constrain(size_t m, size_t n, T & /*lp*/) { - if (m == 0 || n == 0) - return map_matrix_t(nullptr, m, n); - return map_matrix_t(&scalar_ptr_increment(m * n), m, n); + return this->matrix(m, n); + } + + /** + * Return a matrix of the specified dimensionality made up of + * the next scalars arranged in column-major order. The + * constraint is a no-op, hence the log probability is not + * incremented. See matrix(size_t, size_t) + * for more information. + * + * @param m Number of rows. + * @param n Number of columns. + * lp Log probability to increment. + * @return Matrix made up of the next scalars. + */ + template * = nullptr> + inline auto var_matrix_constrain(size_t m, size_t n, T & /*lp*/) { + return this->matrix(m, n); + } + + /** + * Return a matrix of the specified dimensionality made up of + * the next scalars arranged in column-major order. The + * constraint is a no-op, hence the log probability is not + * incremented. See matrix(size_t, size_t) + * for more information. + * + * @param m Number of rows. + * @param n Number of columns. + * lp Log probability to increment. + * @return Matrix made up of the next scalars. + */ + template * = nullptr> + inline auto var_matrix_constrain(size_t m, size_t n, T & /*lp*/) { + return this->var_matrix(m, n); } /** @@ -452,6 +536,7 @@ class reader { * @throw std::runtime_error If the next integer read is not * greater than or equal to the lower bound. */ + template inline int integer_lb_constrain(int lb, T & /*lp*/) { return integer_lb(lb); } /** @@ -490,6 +575,7 @@ class reader { * @throw std::runtime_error If the next integer read is not * less than or equal to the upper bound. */ + template inline int integer_ub_constrain(int ub, T & /*lp*/) { return integer_ub(ub); } /** @@ -542,6 +628,7 @@ class reader { * @throw std::runtime_error If the next integer read is not * less than or equal to the upper bound. */ + template inline int integer_lub_constrain(int lb, int ub, T & /*lp*/) { return integer_lub(lb, ub); } @@ -582,8 +669,13 @@ class reader { * @param lp Reference to log probability variable to increment. * @return The next scalar transformed to be positive. */ + template inline T scalar_pos_constrain(T &lp) { - return stan::math::positive_constrain(scalar(), lp); + if (Jacobian) { + return stan::math::positive_constrain(scalar(), lp); + } else { + return stan::math::positive_constrain(scalar()); + } } /** @@ -633,9 +725,13 @@ class reader { * @param lb Lower bound on result. * @param lp Reference to log probability variable to increment. */ - template + template inline T scalar_lb_constrain(const TL lb, T &lp) { - return stan::math::lb_constrain(scalar(), lb, lp); + if (Jacobian) { + return stan::math::lb_constrain(scalar(), lb, lp); + } else { + return stan::math::lb_constrain(scalar(), lb); + } } /** @@ -685,9 +781,13 @@ class reader { * @param ub Upper bound on result. * @param lp Reference to log probability variable to increment. */ - template + template inline T scalar_ub_constrain(const TU ub, T &lp) { - return stan::math::ub_constrain(scalar(), ub, lp); + if (Jacobian) { + return stan::math::ub_constrain(scalar(), ub, lp); + } else { + return stan::math::ub_constrain(scalar(), ub); + } } /** @@ -743,9 +843,13 @@ class reader { * @tparam TL Type of lower bound. * @tparam TU Type of upper bound. */ - template + template inline T scalar_lub_constrain(TL lb, TU ub, T &lp) { - return stan::math::lub_constrain(scalar(), lb, ub, lp); + if (Jacobian) { + return stan::math::lub_constrain(scalar(), lb, ub, lp); + } else { + return stan::math::lub_constrain(scalar(), lb, ub); + } } /** @@ -759,8 +863,7 @@ class reader { */ template inline T scalar_offset_multiplier(const TL offset, const TS multiplier) { - T x(scalar()); - return x; + return scalar(); } /** @@ -798,10 +901,14 @@ class reader { * @tparam TL Type of offset. * @tparam TS Type of multiplier. */ - template + template inline T scalar_offset_multiplier_constrain(TL offset, TS multiplier, T &lp) { - return stan::math::offset_multiplier_constrain(scalar(), offset, multiplier, - lp); + if (Jacobian) { + return stan::math::offset_multiplier_constrain(scalar(), offset, multiplier, + lp); + } else { + return stan::math::offset_multiplier_constrain(scalar(), offset, multiplier); + } } /** @@ -839,8 +946,13 @@ class reader { * @param lp Reference to log probability variable to increment. * @return The next scalar transformed to a probability. */ + template inline T prob_constrain(T &lp) { - return stan::math::prob_constrain(scalar(), lp); + if (Jacobian) { + return stan::math::prob_constrain(scalar(), lp); + } else { + return stan::math::prob_constrain(scalar()); + } } /** @@ -882,8 +994,13 @@ class reader { * probability to increment. * @return The next scalar transformed to a correlation. */ + template inline T corr_constrain(T &lp) { - return stan::math::corr_constrain(scalar(), lp); + if (Jacobian) { + return stan::math::corr_constrain(scalar(), lp); + } else { + return stan::math::corr_constrain(scalar()); + } } /** @@ -908,6 +1025,29 @@ class reader { return theta; } + /** + * Return a unit_vector of the specified size made up of the + * next scalars. + * + *

See stan::math::check_unit_vector. + * + * @param k Size of returned unit_vector + * @return unit_vector read from the specified size number of scalars + * @throw std::runtime_error if the next k values is not a unit_vector + * @throw std::invalid_argument if k is zero + */ + inline var_vector_t var_unit_vector(size_t k) { + using stan::math::value_of; + if (k == 0) { + std::string msg = "io::unit_vector: unit vectors cannot be size 0."; + throw std::invalid_argument(msg); + } + var_vector_t theta(var_vector(k)); + stan::math::check_unit_vector("stan::io::unit_vector", "Constrained vector", + value_of(theta)); + return theta; + } + /** * Return the next unit_vector transformed vector of the specified * length. This operation consumes one less than the specified @@ -942,14 +1082,47 @@ class reader { * @return The next unit_vector of the specified size. * @throw std::invalid_argument if k is zero */ - inline auto unit_vector_constrain(size_t k, T &lp) { + template + inline vector_t unit_vector_constrain(size_t k, T &lp) { + if (k == 0) { + std::string msg + = "io::unit_vector_constrain:" + " unit vectors cannot be size 0."; + throw std::invalid_argument(msg); + } + if (Jacobian) { + return stan::math::unit_vector_constrain(vector(k), lp); + } else { + return stan::math::unit_vector_constrain(vector(k)); + } + } + + /** + * Return the next unit_vector of the specified size (using one fewer + * unconstrained scalars), incrementing the specified reference with the + * log absolute Jacobian determinant. + * + *

See stan::math::unit_vector_constrain(Eigen::Matrix,T&). + * + * @param k Size of unit_vector. + * @param lp Log probability to increment with log absolute + * Jacobian determinant. + * @return The next unit_vector of the specified size. + * @throw std::invalid_argument if k is zero + */ + template + inline var_vector_t var_unit_vector_constrain(size_t k, T &lp) { if (k == 0) { std::string msg = "io::unit_vector_constrain:" " unit vectors cannot be size 0."; throw std::invalid_argument(msg); } - return stan::math::unit_vector_constrain(vector(k), lp); + if (Jacobian) { + return stan::math::unit_vector_constrain(var_vector(k), lp); + } else { + return stan::math::unit_vector_constrain(var_vector(k)); + } } /** @@ -973,6 +1146,28 @@ class reader { return theta; } + /** + * Return a simplex of the specified size made up of the + * next scalars. + * + *

See stan::math::check_simplex. + * + * @param k Size of returned simplex. + * @return Simplex read from the specified size number of scalars. + * @throw std::runtime_error if the k values is not a simplex. + * @throw std::invalid_argument if k is zero + */ + inline var_vector_t var_simplex(size_t k) { + using stan::math::value_of; + if (k == 0) { + std::string msg = "io::simplex: simplexes cannot be size 0."; + throw std::invalid_argument(msg); + } + var_vector_t theta(var_vector(k)); + stan::math::check_simplex("stan::io::simplex", "Constrained vector", value_of(theta)); + return theta; + } + /** * Return the next simplex transformed vector of the specified * length. This operation consumes one less than the specified @@ -1005,12 +1200,43 @@ class reader { * @return The next simplex of the specified size. * @throws std::invalid_argument if number of dimensions (`k`) is zero */ - inline auto simplex_constrain(size_t k, T &lp) { + template + inline vector_t simplex_constrain(size_t k, T &lp) { + if (k == 0) { + std::string msg = "io::simplex_constrain: simplexes cannot be size 0."; + throw std::invalid_argument(msg); + } + if (Jacobian) { + return stan::math::simplex_constrain(vector(k - 1), lp); + } else { + return stan::math::simplex_constrain(vector(k - 1)); + } + } + + /** + * Return the next simplex of the specified size (using one fewer + * unconstrained scalars), incrementing the specified reference with the + * log absolute Jacobian determinant. + * + *

See stan::math::simplex_constrain(Eigen::Matrix,T&). + * + * @param k Size of simplex. + * @param lp Log probability to increment with log absolute + * Jacobian determinant. + * @return The next simplex of the specified size. + * @throws std::invalid_argument if number of dimensions (`k`) is zero + */ + template + inline var_vector_t var_simplex_constrain(size_t k, T &lp) { if (k == 0) { std::string msg = "io::simplex_constrain: simplexes cannot be size 0."; throw std::invalid_argument(msg); } - return stan::math::simplex_constrain(vector(k - 1), lp); + if (Jacobian) { + return stan::math::simplex_constrain(var_vector(k - 1), lp); + } else { + return stan::math::simplex_constrain(var_vector(k - 1)); + } } /** @@ -1029,6 +1255,23 @@ class reader { return x; } + /** + * Return the next vector of specified size containing + * values in ascending order. + * + *

See stan::math::check_ordered(T) for + * behavior on failure. + * + * @param k Size of returned vector. + * @return Vector of positive values in ascending order. + */ + inline var_vector_t var_ordered(size_t k) { + using stan::math::value_of; + var_vector_t x(var_vector(k)); + stan::math::check_ordered("stan::io::ordered", "Constrained vector", value_of(x)); + return x; + } + /** * Return the next ordered vector of the specified length. * @@ -1053,8 +1296,33 @@ class reader { * @param lp Log probability reference to increment. * @return Next ordered vector of the specified size. */ - inline auto ordered_constrain(size_t k, T &lp) { - return stan::math::ordered_constrain(vector(k), lp); + template + inline vector_t ordered_constrain(size_t k, T &lp) { + if (Jacobian) { + return stan::math::ordered_constrain(vector(k), lp); + } else { + return stan::math::ordered_constrain(vector(k)); + } + } + + /** + * Return the next ordered vector of the specified + * size, incrementing the specified reference with the log + * absolute Jacobian of the determinant. + * + *

See stan::math::ordered_constrain(Matrix,T&). + * + * @param k Size of vector. + * @param lp Log probability reference to increment. + * @return Next ordered vector of the specified size. + */ + template + inline var_vector_t var_ordered_constrain(size_t k, T &lp) { + if (Jacobian) { + return stan::math::ordered_constrain(var_vector(k), lp); + } else { + return stan::math::ordered_constrain(var_vector(k)); + } } /** @@ -1074,6 +1342,25 @@ class reader { return x; } + /** + * Return the next vector of specified size containing + * positive values in ascending order. + * + *

See stan::math::check_positive_ordered(T) for + * behavior on failure. + * + * @param k Size of returned vector. + * @return Vector of positive values in ascending order. + */ + inline var_vector_t var_positive_ordered(size_t k) { + using stan::math::value_of; + var_vector_t x(var_vector(k)); + stan::math::check_positive_ordered("stan::io::positive_ordered", + "Constrained vector", value_of(x)); + return x; + } + + /** * Return the next positive ordered vector of the specified length. * @@ -1087,6 +1374,20 @@ class reader { return stan::math::positive_ordered_constrain(vector(k)); } + + /** + * Return the next positive ordered vector of the specified length. + * + *

See stan::math::positive_ordered_constrain(Matrix). + * + * @param k Length of returned vector. + * @return Next positive_ordered vector of the specified + * length. + */ + inline auto var_positive_ordered_constrain(size_t k) { + return stan::math::positive_ordered_constrain(var_vector(k)); + } + /** * Return the next positive_ordered vector of the specified * size, incrementing the specified reference with the log @@ -1098,20 +1399,45 @@ class reader { * @param lp Log probability reference to increment. * @return Next positive_ordered vector of the specified size. */ - inline auto positive_ordered_constrain(size_t k, T &lp) { - return stan::math::positive_ordered_constrain(vector(k), lp); + template + inline vector_t positive_ordered_constrain(size_t k, T &lp) { + if (Jacobian) { + return stan::math::positive_ordered_constrain(vector(k), lp); + } else { + return stan::math::positive_ordered_constrain(vector(k)); + } } /** - * Return the next Cholesky factor with the specified - * dimensionality, reading it directly without transforms. + * Return the next positive_ordered vector of the specified + * size, incrementing the specified reference with the log + * absolute Jacobian of the determinant. * - * @param M Rows of Cholesky factor - * @param N Columns of Cholesky factor - * @return Next Cholesky factor. - * @throw std::domain_error if the matrix is not a valid - * Cholesky factor. - */ + *

See stan::math::positive_ordered_constrain(Matrix,T&). + * + * @param k Size of vector. + * @param lp Log probability reference to increment. + * @return Next positive_ordered vector of the specified size. + */ + template + inline var_vector_t var_positive_ordered_constrain(size_t k, T &lp) { + if (Jacobian) { + return stan::math::positive_ordered_constrain(var_vector(k), lp); + } else { + return stan::math::positive_ordered_constrain(var_vector(k)); + } + } + + /** + * Return the next Cholesky factor with the specified + * dimensionality, reading it directly without transforms. + * + * @param M Rows of Cholesky factor + * @param N Columns of Cholesky factor + * @return Next Cholesky factor. + * @throw std::domain_error if the matrix is not a valid + * Cholesky factor. + */ inline map_matrix_t cholesky_factor_cov(size_t M, size_t N) { map_matrix_t y(matrix(M, N)); stan::math::check_cholesky_factor("stan::io::cholesky_factor_cov", @@ -1119,6 +1445,23 @@ class reader { return y; } + /** + * Return the next Cholesky factor with the specified + * dimensionality, reading it directly without transforms. + * + * @param M Rows of Cholesky factor + * @param N Columns of Cholesky factor + * @return Next Cholesky factor. + * @throw std::domain_error if the matrix is not a valid + * Cholesky factor. + */ + inline var_matrix_t var_cholesky_factor_cov(size_t M, size_t N) { + var_matrix_t y(var_matrix(M, N)); + stan::math::check_cholesky_factor("stan::io::cholesky_factor_cov", + "Constrained matrix", value_of(y)); + return y; + } + /** * Return the next Cholesky factor with the specified * dimensionality, reading from an unconstrained vector of the @@ -1148,9 +1491,39 @@ class reader { * @throw std::domain_error if the matrix is not a valid * Cholesky factor. */ - inline auto cholesky_factor_cov_constrain(size_t M, size_t N, T &lp) { - return stan::math::cholesky_factor_constrain( - vector((N * (N + 1)) / 2 + (M - N) * N), M, N, lp); + template + inline matrix_t cholesky_factor_cov_constrain(size_t M, size_t N, T &lp) { + if (Jacobian) { + return stan::math::cholesky_factor_constrain( + vector((N * (N + 1)) / 2 + (M - N) * N), M, N, lp); + } else { + return stan::math::cholesky_factor_constrain( + vector((N * (N + 1)) / 2 + (M - N) * N), M, N); + } + } + + /** + * Return the next Cholesky factor with the specified + * dimensionality, reading from an unconstrained vector of the + * appropriate size, and increment the log probability reference + * with the log Jacobian adjustment for the transform. + * + * @param M Rows of Cholesky factor + * @param N Columns of Cholesky factor + * @param[in,out] lp log probability + * @return Next Cholesky factor. + * @throw std::domain_error if the matrix is not a valid + * Cholesky factor. + */ + template + inline var_matrix_t var_cholesky_factor_cov_constrain(size_t M, size_t N, T &lp) { + if (Jacobian) { + return stan::math::cholesky_factor_constrain( + var_vector((N * (N + 1)) / 2 + (M - N) * N), M, N, lp); + } else { + return stan::math::cholesky_factor_constrain( + var_vector((N * (N + 1)) / 2 + (M - N) * N), M, N); + } } /** @@ -1171,6 +1544,24 @@ class reader { return y; } + /** + * Return the next Cholesky factor for a correlation matrix with + * the specified dimensionality, reading it directly without + * transforms. + * + * @param K Rows and columns of Cholesky factor + * @return Next Cholesky factor for a correlation matrix. + * @throw std::domain_error if the matrix is not a valid + * Cholesky factor for a correlation matrix. + */ + inline var_matrix_t var_cholesky_factor_corr(size_t K) { + using stan::math::check_cholesky_factor_corr; + var_matrix_t y(var_matrix(K, K)); + check_cholesky_factor_corr("stan::io::cholesky_factor_corr", + "Constrained matrix", value_of(y)); + return y; + } + /** * Return the next Cholesky factor for a correlation matrix with * the specified dimensionality, reading from an unconstrained @@ -1185,6 +1576,43 @@ class reader { return stan::math::cholesky_corr_constrain(vector((K * (K - 1)) / 2), K); } + /** + * Return the next Cholesky factor for a correlation matrix with + * the specified dimensionality, reading from an unconstrained + * vector of the appropriate size. + * + * @param K Rows and columns of Cholesky factor. + * @return Next Cholesky factor for a correlation matrix. + * @throw std::domain_error if the matrix is not a valid + * Cholesky factor for a correlation matrix. + */ + inline auto var_cholesky_factor_corr_constrain(size_t K) { + return stan::math::cholesky_corr_constrain(var_vector((K * (K - 1)) / 2), K); + } + /** + * Return the next Cholesky factor for a correlation matrix with + * the specified dimensionality, reading from an unconstrained + * vector of the appropriate size, and increment the log + * probability reference with the log Jacobian adjustment for + * the transform. + * + * @param K Rows and columns of Cholesky factor + * @param lp Log probability reference to increment. + * @return Next Cholesky factor for a correlation matrix. + * @throw std::domain_error if the matrix is not a valid + * Cholesky factor for a correlation matrix. + */ + template + inline matrix_t cholesky_factor_corr_constrain(size_t K, T &lp) { + if (Jacobian) { + return stan::math::cholesky_corr_constrain(vector((K * (K - 1)) / 2), K, + lp); + } else { + return stan::math::cholesky_corr_constrain(vector((K * (K - 1)) / 2), K, + lp); + } + } + /** * Return the next Cholesky factor for a correlation matrix with * the specified dimensionality, reading from an unconstrained @@ -1198,9 +1626,15 @@ class reader { * @throw std::domain_error if the matrix is not a valid * Cholesky factor for a correlation matrix. */ - inline auto cholesky_factor_corr_constrain(size_t K, T &lp) { - return stan::math::cholesky_corr_constrain(vector((K * (K - 1)) / 2), K, - lp); + template + inline var_matrix_t var_cholesky_factor_corr_constrain(size_t K, T &lp) { + if (Jacobian) { + return stan::math::cholesky_corr_constrain(var_vector((K * (K - 1)) / 2), K, + lp); + } else { + return stan::math::cholesky_corr_constrain(var_vector((K * (K - 1)) / 2), K, + lp); + } } /** @@ -1215,9 +1649,10 @@ class reader { * covariance matrix */ inline map_matrix_t cov_matrix(size_t k) { + using stan::math::value_of; map_matrix_t y(matrix(k, k)); stan::math::check_cov_matrix("stan::io::cov_matrix", "Constrained matrix", - y); + value_of(y)); return y; } @@ -1244,9 +1679,35 @@ class reader { * @param lp Log probability reference to increment. * @return The next covariance matrix of the specified dimensionality. */ - inline auto cov_matrix_constrain(size_t k, T &lp) { - return stan::math::cov_matrix_constrain(vector(k + (k * (k - 1)) / 2), k, - lp); + template + inline matrix_t cov_matrix_constrain(size_t k, T &lp) { + if (Jacobian) { + return stan::math::cov_matrix_constrain(vector(k + (k * (k - 1)) / 2), k, + lp); + } else { + return stan::math::cov_matrix_constrain(vector(k + (k * (k - 1)) / 2), k); + } + } + + /** + * Return the next covariance matrix of the specified dimensionality, + * incrementing the specified reference with the log absolute Jacobian + * determinant. + * + *

See stan::math::cov_matrix_constrain(Matrix,T&). + * + * @param k Dimensionality of the (square) covariance matrix. + * @param lp Log probability reference to increment. + * @return The next covariance matrix of the specified dimensionality. + */ + template + inline var_matrix_t var_cov_matrix_constrain(size_t k, T &lp) { + if (Jacobian) { + return stan::math::cov_matrix_constrain(var_vector(k + (k * (k - 1)) / 2), k, + lp); + } else { + return stan::math::cov_matrix_constrain(var_vector(k + (k * (k - 1)) / 2), k); + } } /** @@ -1265,6 +1726,23 @@ class reader { return x; } + /** + * Returns the next correlation matrix of the specified dimensionality. + * + *

See stan::math::check_corr_matrix(Matrix). + * + * @param k Dimensionality of correlation matrix. + * @return Next correlation matrix of the specified dimensionality. + * @throw std::runtime_error if the matrix is not a correlation matrix + */ + inline var_matrix_t var_corr_matrix(size_t k) { + using stan::math::value_of; + var_matrix_t x(var_matrix(k, k)); + stan::math::check_corr_matrix("stan::math::corr_matrix", + "Constrained matrix", value_of(x)); + return x; + } + /** * Return the next correlation matrix of the specified dimensionality. * @@ -1277,6 +1755,18 @@ class reader { return stan::math::corr_matrix_constrain(vector((k * (k - 1)) / 2), k); } + /** + * Return the next correlation matrix of the specified dimensionality. + * + *

See stan::math::corr_matrix_constrain(Matrix). + * + * @param k Dimensionality of correlation matrix. + * @return Next correlation matrix of the specified dimensionality. + */ + inline auto var_corr_matrix_constrain(size_t k) { + return stan::math::corr_matrix_constrain(var_vector((k * (k - 1)) / 2), k); + } + /** * Return the next correlation matrix of the specified dimensionality, * incrementing the specified reference with the log absolute Jacobian @@ -1288,8 +1778,33 @@ class reader { * @param lp Log probability reference to increment. * @return The next correlation matrix of the specified dimensionality. */ - inline auto corr_matrix_constrain(size_t k, T &lp) { - return stan::math::corr_matrix_constrain(vector((k * (k - 1)) / 2), k, lp); + template + inline matrix_t corr_matrix_constrain(size_t k, T &lp) { + if (Jacobian) { + return stan::math::corr_matrix_constrain(vector((k * (k - 1)) / 2), k, lp); + } else { + return stan::math::corr_matrix_constrain(vector((k * (k - 1)) / 2), k); + } + } + + /** + * Return the next correlation matrix of the specified dimensionality, + * incrementing the specified reference with the log absolute Jacobian + * determinant. + * + *

See stan::math::corr_matrix_constrain(Matrix,T&). + * + * @param k Dimensionality of the (square) correlation matrix. + * @param lp Log probability reference to increment. + * @return The next correlation matrix of the specified dimensionality. + */ + template + inline var_matrix_t var_corr_matrix_constrain(size_t k, T &lp) { + if (Jacobian) { + return stan::math::corr_matrix_constrain(var_vector((k * (k - 1)) / 2), k, lp); + } else { + return stan::math::corr_matrix_constrain(var_vector((k * (k - 1)) / 2), k); + } } template @@ -1300,14 +1815,41 @@ class reader { return v; } + template + inline var_vector_t vector_lb(const TL lb, size_t m) { + using stan::math::value_of; + var_vector_t v(var_vector(m)); + stan::math::check_greater_or_equal("stan::io::vector_lb", + "Constrained vector", value_of(v), lb); + return v; + } + template inline auto vector_lb_constrain(const TL lb, size_t m) { return stan::math::lb_constrain(vector(m), lb); } template - inline auto vector_lb_constrain(const TL lb, size_t m, T &lp) { - return stan::math::lb_constrain(vector(m), lb, lp); + inline auto var_vector_lb_constrain(const TL lb, size_t m) { + return stan::math::lb_constrain(var_vector(m), lb); + } + + template + inline vector_t vector_lb_constrain(const TL lb, size_t m, T &lp) { + if (Jacobian) { + return stan::math::lb_constrain(vector(m), lb, lp); + } else { + return stan::math::lb_constrain(vector(m), lb); + } + } + + template + inline var_vector_t var_vector_lb_constrain(const TL lb, size_t m, T &lp) { + if (Jacobian) { + return stan::math::lb_constrain(var_vector(m), lb, lp); + } else { + return stan::math::lb_constrain(var_vector(m), lb); + } } template @@ -1318,14 +1860,41 @@ class reader { return v; } + template + inline var_row_vector_t var_row_vector_lb(const TL lb, size_t m) { + using stan::math::value_of; + var_row_vector_t v(var_row_vector(m)); + stan::math::check_greater_or_equal("stan::io::row_vector_lb", + "Constrained row vector", value_of(v), lb); + return v; + } + template inline auto row_vector_lb_constrain(const TL lb, size_t m) { return stan::math::lb_constrain(row_vector(m), lb); } template - inline auto row_vector_lb_constrain(const TL lb, size_t m, T &lp) { - return stan::math::lb_constrain(row_vector(m), lb, lp); + inline auto var_row_vector_lb_constrain(const TL lb, size_t m) { + return stan::math::lb_constrain(var_row_vector(m), lb); + } + + template + inline row_vector_t row_vector_lb_constrain(const TL lb, size_t m, T &lp) { + if (Jacobian) { + return stan::math::lb_constrain(row_vector(m), lb, lp); + } else { + return stan::math::lb_constrain(row_vector(m), lb); + } + } + + template + inline var_row_vector_t var_row_vector_lb_constrain(const TL lb, size_t m, T &lp) { + if (Jacobian) { + return stan::math::lb_constrain(var_row_vector(m), lb, lp); + } else { + return stan::math::lb_constrain(var_row_vector(m), lb); + } } template @@ -1336,19 +1905,41 @@ class reader { return mat; } + template + inline var_matrix_t var_matrix_lb(const TL lb, const size_t m, size_t n) { + using stan::math::value_of; + var_matrix_t mat(var_matrix(m, n)); + stan::math::check_greater_or_equal("stan::io::matrix_lb", + "Constrained matrix", value_of(mat), lb); + return mat; + } + template inline auto matrix_lb_constrain(const TL lb, size_t m, size_t n) { - return matrix(m, n) - .unaryExpr([&](auto &&x) { return stan::math::lb_constrain(x, lb); }) - .eval(); + return stan::math::lb_constrain(matrix(m, n), lb); } template - inline auto matrix_lb_constrain(const TL lb, size_t m, size_t n, T &lp) { - return matrix(m, n) - .unaryExpr( - [&](auto &&x) { return stan::math::lb_constrain(x, lb, lp); }) - .eval(); + inline auto var_matrix_lb_constrain(const TL lb, size_t m, size_t n) { + return stan::math::lb_constrain(var_matrix(m, n), lb); + } + + template + inline matrix_t matrix_lb_constrain(const TL lb, size_t m, size_t n, T &lp) { + if (Jacobian) { + return stan::math::lb_constrain(matrix(m, n), lb, lp).eval(); + } else { + return stan::math::lb_constrain(matrix(m, n), lb).eval(); + } + } + + template + inline var_matrix_t var_matrix_lb_constrain(const TL lb, size_t m, size_t n, T &lp) { + if (Jacobian) { + return stan::math::lb_constrain(var_matrix(m, n), lb, lp).eval(); + } else { + return stan::math::lb_constrain(var_matrix(m, n), lb).eval(); + } } template @@ -1359,14 +1950,41 @@ class reader { return v; } + template + inline var_vector_t var_vector_ub(const TU ub, size_t m) { + using stan::math::value_of; + var_vector_t v(vector(m)); + stan::math::check_less_or_equal("stan::io::vector_ub", "Constrained vector", + value_of(v), ub); + return v; + } + template inline auto vector_ub_constrain(const TU ub, size_t m) { return stan::math::ub_constrain(vector(m), ub); } template - inline auto vector_ub_constrain(const TU ub, size_t m, T &lp) { - return stan::math::ub_constrain(vector(m), ub, lp); + inline auto var_vector_ub_constrain(const TU ub, size_t m) { + return stan::math::ub_constrain(var_vector(m), ub); + } + + template + inline vector_t vector_ub_constrain(const TU ub, size_t m, T &lp) { + if (Jacobian) { + return stan::math::ub_constrain(vector(m), ub, lp); + } else { + return stan::math::ub_constrain(vector(m), ub); + } + } + + template + inline var_vector_t var_vector_ub_constrain(const TU ub, size_t m, T &lp) { + if (Jacobian) { + return stan::math::ub_constrain(var_vector(m), ub, lp); + } else { + return stan::math::ub_constrain(var_vector(m), ub); + } } template @@ -1377,14 +1995,41 @@ class reader { return v; } + template + inline var_row_vector_t var_row_vector_ub(const TU ub, size_t m) { + using stan::math::value_of; + var_row_vector_t v(var_row_vector(m)); + stan::math::check_less_or_equal("stan::io::row_vector_ub", + "Constrained row vector", value_of(v), ub); + return v; + } + template inline auto row_vector_ub_constrain(const TU ub, size_t m) { return stan::math::ub_constrain(row_vector(m), ub); } template - inline auto row_vector_ub_constrain(const TU ub, size_t m, T &lp) { - return stan::math::ub_constrain(row_vector(m), ub, lp); + inline auto var_row_vector_ub_constrain(const TU ub, size_t m) { + return stan::math::ub_constrain(var_row_vector(m), ub); + } + + template + inline row_vector_t row_vector_ub_constrain(const TU ub, size_t m, T &lp) { + if (Jacobian) { + return stan::math::ub_constrain(row_vector(m), ub, lp); + } else { + return stan::math::ub_constrain(row_vector(m), ub); + } + } + + template + inline var_row_vector_t var_row_vector_ub_constrain(const TU ub, size_t m, T &lp) { + if (Jacobian) { + return stan::math::ub_constrain(var_row_vector(m), ub, lp); + } else { + return stan::math::ub_constrain(var_row_vector(m), ub); + } } template @@ -1395,20 +2040,43 @@ class reader { return mat; } + template + inline var_matrix_t var_matrix_ub(const TU ub, size_t m, size_t n) { + using stan::math::value_of; + var_matrix_t mat(var_matrix(m, n)); + stan::math::check_less_or_equal("stan::io::matrix_ub", "Constrained matrix", + value_of(mat), ub); + return mat; + } + template inline auto matrix_ub_constrain(const TU ub, const size_t m, size_t n) { - return matrix(m, n) - .unaryExpr([&](auto &&x) { return stan::math::ub_constrain(x, ub); }) - .eval(); + return stan::math::ub_constrain(matrix(m, n), ub); } template - inline auto matrix_ub_constrain(const TU ub, const size_t m, size_t n, + inline auto var_matrix_ub_constrain(const TU ub, const size_t m, size_t n) { + return stan::math::ub_constrain(var_matrix(m, n), ub); + } + + template + inline matrix_t matrix_ub_constrain(const TU ub, const size_t m, size_t n, T &lp) { - return matrix(m, n) - .unaryExpr( - [&](auto &&x) { return stan::math::ub_constrain(x, ub, lp); }) - .eval(); + if (Jacobian) { + return stan::math::ub_constrain(matrix(m, n), ub, lp); + } else { + return stan::math::ub_constrain(matrix(m, n), ub); + } + } + + template + inline var_matrix_t var_matrix_ub_constrain(const TU ub, const size_t m, size_t n, + T &lp) { + if (Jacobian) { + return stan::math::ub_constrain(var_matrix(m, n), ub, lp); + } else { + return stan::math::ub_constrain(var_matrix(m, n), ub); + } } template @@ -1419,14 +2087,41 @@ class reader { return v; } + template + inline var_vector_t var_vector_lub(const TL lb, const TU ub, size_t m) { + using stan::math::value_of; + var_vector_t v(var_vector(m)); + stan::math::check_bounded( + "stan::io::vector_lub", "Constrained vector", value_of(v), lb, ub); + return v; + } + template inline auto vector_lub_constrain(const TL lb, const TU ub, size_t m) { return stan::math::lub_constrain(vector(m), lb, ub); } template - inline auto vector_lub_constrain(const TL lb, const TU ub, size_t m, T &lp) { - return stan::math::lub_constrain(vector(m), lb, ub, lp); + inline auto var_vector_lub_constrain(const TL lb, const TU ub, size_t m) { + return stan::math::lub_constrain(var_vector(m), lb, ub); + } + + template + inline vector_t vector_lub_constrain(const TL lb, const TU ub, size_t m, T &lp) { + if (Jacobian) { + return stan::math::lub_constrain(vector(m), lb, ub, lp); + } else { + return stan::math::lub_constrain(vector(m), lb, ub); + } + } + + template + inline var_vector_t var_vector_lub_constrain(const TL lb, const TU ub, size_t m, T &lp) { + if (Jacobian) { + return stan::math::lub_constrain(var_vector(m), lb, ub, lp); + } else { + return stan::math::lub_constrain(var_vector(m), lb, ub); + } } template @@ -1436,6 +2131,16 @@ class reader { "stan::io::row_vector_lub", "Constrained row vector", v, lb, ub); return v; } + + template + inline var_row_vector_t var_row_vector_lub(const TL lb, const TU ub, size_t m) { + using stan::math::value_of; + var_row_vector_t v(var_row_vector(m)); + stan::math::check_bounded( + "stan::io::row_vector_lub", "Constrained row vector", value_of(v), lb, ub); + return v; + } + template inline row_vector_t row_vector_lub_constrain(const TL lb, const TU ub, size_t m) { @@ -1443,35 +2148,71 @@ class reader { } template + inline var_row_vector_t var_row_vector_lub_constrain(const TL lb, const TU ub, + size_t m) { + return stan::math::lub_constrain(var_row_vector(m), lb, ub); + } + + template inline row_vector_t row_vector_lub_constrain(const TL lb, const TU ub, size_t m, T &lp) { - return stan::math::lub_constrain(row_vector(m), lb, ub, lp); + if (Jacobian) { + return stan::math::lub_constrain(row_vector(m), lb, ub, lp); + } else { + return stan::math::lub_constrain(row_vector(m), lb, ub); + } + } + + template + inline var_row_vector_t var_row_vector_lub_constrain(const TL lb, const TU ub, + size_t m, T &lp) { + if (Jacobian) { + return stan::math::lub_constrain(var_row_vector(m), lb, ub, lp); + } else { + return stan::math::lub_constrain(var_row_vector(m), lb, ub); + } } template inline map_matrix_t matrix_lub(const TL lb, const TU ub, size_t m, size_t n) { + using stan::math::value_of; map_matrix_t mat(matrix(m, n)); stan::math::check_bounded( - "stan::io::row_vector_lub", "Constrained row vector", mat, lb, ub); + "stan::io::row_vector_lub", "Constrained row vector", value_of(mat), lb, ub); + return mat; + } + + template + inline var_matrix_t var_matrix_lub(const TL lb, const TU ub, size_t m, size_t n) { + using stan::math::value_of; + var_matrix_t mat(var_matrix(m, n)); + stan::math::check_bounded( + "stan::io::row_vector_lub", "Constrained row vector", value_of(mat), lb, ub); return mat; } template inline auto matrix_lub_constrain(const TL lb, const TU ub, size_t m, size_t n) { - return matrix(m, n) - .unaryExpr( - [&](auto &&x) { return stan::math::lub_constrain(x, lb, ub); }) - .eval(); + return stan::math::lub_constrain(matrix(m, n), lb, ub); } template + inline auto var_matrix_lub_constrain(const TL lb, const TU ub, size_t m, + size_t n) { + return stan::math::lub_constrain(var_matrix(m, n), lb, ub); + } + + template inline auto matrix_lub_constrain(const TL lb, const TU ub, size_t m, size_t n, T &lp) { - return matrix(m, n) - .unaryExpr( - [&](auto &&x) { return stan::math::lub_constrain(x, lb, ub, lp); }) - .eval(); + return stan::math::lub_constrain(matrix(m, n), lb, ub, lp); + } + + template + inline auto var_matrix_lub_constrain(const TL lb, const TU ub, size_t m, size_t n, + T &lp) { + return stan::math::lub_constrain(var_matrix(m, n), lb, ub, lp); } template @@ -1480,6 +2221,12 @@ class reader { return vector(m); } + template + inline auto var_vector_offset_multiplier(const TL offset, + const TS multiplier, size_t m) { + return var_vector(m); + } + template inline auto vector_offset_multiplier_constrain(const TL offset, const TS multiplier, @@ -1489,11 +2236,33 @@ class reader { } template - inline auto vector_offset_multiplier_constrain(const TL offset, + inline auto var_vector_offset_multiplier_constrain(const TL offset, + const TS multiplier, + size_t m) { + return stan::math::offset_multiplier_constrain(var_vector(m), offset, + multiplier); + } + + template + inline vector_t vector_offset_multiplier_constrain(const TL offset, const TS multiplier, size_t m, T &lp) { - return stan::math::offset_multiplier_constrain(vector(m), offset, - multiplier, lp); + if (Jacobian) { + return stan::math::offset_multiplier_constrain(vector(m), offset, multiplier, lp); + } else { + return stan::math::offset_multiplier_constrain(vector(m), offset, multiplier); + } + } + + template + inline var_vector_t var_vector_offset_multiplier_constrain(const TL offset, + const TS multiplier, size_t m, + T &lp) { + if (Jacobian) { + return stan::math::offset_multiplier_constrain(var_vector(m), offset, multiplier, lp); + } else { + return stan::math::offset_multiplier_constrain(var_vector(m), offset, multiplier); + } } template @@ -1504,42 +2273,68 @@ class reader { } template - inline auto row_vector_offset_multiplier_constrain(const TL offset, - const TS multiplier, - size_t m) { - return stan::math::offset_multiplier_constrain(row_vector(m), offset, - multiplier); + inline var_row_vector_t var_row_vector_offset_multiplier(const TL offset, + const TS multiplier, + size_t m) { + return var_row_vector(m); + } + + template + inline auto row_vector_offset_multiplier_constrain(const TL offset, const TS multiplier, size_t m) { + return stan::math::offset_multiplier_constrain(row_vector(m), offset, multiplier); } template - inline auto row_vector_offset_multiplier_constrain(const TL offset, - const TS multiplier, - size_t m, T &lp) { - return stan::math::offset_multiplier_constrain(row_vector(m), offset, - multiplier, lp); + inline auto var_row_vector_offset_multiplier_constrain(const TL offset, const TS multiplier, size_t m) { + return stan::math::offset_multiplier_constrain(var_row_vector(m), offset, multiplier); + } + + template + inline row_vector_t row_vector_offset_multiplier_constrain(const TL offset, const TS multiplier, size_t m, T &lp) { + return stan::math::offset_multiplier_constrain(row_vector(m), offset, multiplier, lp); + } + + template + inline var_row_vector_t var_row_vector_offset_multiplier_constrain(const TL offset, const TS multiplier, size_t m, T &lp) { + return stan::math::offset_multiplier_constrain(var_row_vector(m), offset, multiplier, lp); } template - inline map_matrix_t matrix_offset_multiplier(const TL offset, - const TS multiplier, size_t m, - size_t n) { + inline map_matrix_t matrix_offset_multiplier(const TL offset, const TS multiplier, size_t m, size_t n) { return matrix(m, n); } template - inline auto matrix_offset_multiplier_constrain(const TL offset, - const TS multiplier, size_t m, - size_t n) { - return stan::math::offset_multiplier_constrain(matrix(m, n), offset, - multiplier); + inline var_matrix_t var_matrix_offset_multiplier(const TL offset, const TS multiplier, size_t m, size_t n) { + return var_matrix(m, n); } template - inline auto matrix_offset_multiplier_constrain(const TL offset, - const TS multiplier, size_t m, - size_t n, T &lp) { - return stan::math::offset_multiplier_constrain(matrix(m, n), offset, - multiplier, lp); + inline auto matrix_offset_multiplier_constrain(const TL offset, const TS multiplier, size_t m, size_t n) { + return stan::math::offset_multiplier_constrain(matrix(m, n), offset, multiplier); + } + + template + inline auto var_matrix_offset_multiplier_constrain(const TL offset, const TS multiplier, size_t m, size_t n) { + return stan::math::offset_multiplier_constrain(var_matrix(m, n), offset, multiplier); + } + + template + inline matrix_t matrix_offset_multiplier_constrain(const TL offset, const TS multiplier, size_t m, size_t n, T &lp) { + if (Jacobian) { + return stan::math::offset_multiplier_constrain(matrix(m, n), offset, multiplier, lp); + } else { + return stan::math::offset_multiplier_constrain(matrix(m, n), offset, multiplier); + } + } + + template + inline var_matrix_t var_matrix_offset_multiplier_constrain(const TL offset, const TS multiplier, size_t m, size_t n, T &lp) { + if (Jacobian) { + return stan::math::offset_multiplier_constrain(var_matrix(m, n), offset, multiplier, lp); + } else { + return stan::math::offset_multiplier_constrain(var_matrix(m, n), offset, multiplier); + } } }; diff --git a/src/test/unit/io/reader2_test.cpp b/src/test/unit/io/reader2_test.cpp new file mode 100644 index 00000000000..995f9c0104a --- /dev/null +++ b/src/test/unit/io/reader2_test.cpp @@ -0,0 +1,1551 @@ +#include +#include + +TEST(io_reader, eigen_input) { + Eigen::Matrix theta_i(1); + Eigen::VectorXd theta(2); + theta[0] = 1.0; + theta[1] = 2.0; + theta_i[0] = 1; + stan::io::reader reader(theta, theta_i); + double x = reader.scalar(); + EXPECT_FLOAT_EQ(1.0, x); + double y = reader.scalar(); + EXPECT_FLOAT_EQ(2.0, y); + int z = reader.integer(); + EXPECT_EQ(1, z); + EXPECT_EQ(0U, reader.available()); +} + +TEST(io_reader, zeroSizeVecs) { + std::vector theta_i; + std::vector theta; + theta.push_back(1.0); + stan::io::reader reader(theta, theta_i); + + EXPECT_FLOAT_EQ(1.0, reader.scalar()); // finish available + + // these all fail in 2.6.3 + EXPECT_EQ(0, reader.std_vector(0).size()); + EXPECT_EQ(0, reader.vector(0).size()); + EXPECT_EQ(0, reader.row_vector(0).size()); + EXPECT_EQ(0, reader.matrix(0, 3).size()); + EXPECT_EQ(0, reader.matrix(3, 0).size()); +} + +TEST(io_reader, scalar) { + std::vector theta_i; + std::vector theta; + theta.push_back(1.0); + theta.push_back(2.0); + stan::io::reader reader(theta, theta_i); + double x = reader.scalar(); + EXPECT_FLOAT_EQ(1.0, x); + double y = reader.scalar(); + EXPECT_FLOAT_EQ(2.0, y); + EXPECT_EQ(0U, reader.available()); +} +TEST(io_reader, scalar_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(1.0); + theta.push_back(2.0); + stan::io::reader reader(theta, theta_i); + double x = reader.scalar_constrain(); + EXPECT_FLOAT_EQ(1.0, x); + double y = reader.scalar_constrain(); + EXPECT_FLOAT_EQ(2.0, y); + EXPECT_EQ(0U, reader.available()); +} +TEST(io_reader, scalar_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(1.0); + theta.push_back(2.0); + stan::io::reader reader(theta, theta_i); + double lp = -1.2; + double x = reader.scalar_constrain(lp); + EXPECT_FLOAT_EQ(1.0, x); + EXPECT_FLOAT_EQ(-1.2, lp); + double y = reader.scalar_constrain(lp); + EXPECT_FLOAT_EQ(2.0, y); + EXPECT_FLOAT_EQ(-1.2, lp); + EXPECT_EQ(0U, reader.available()); +} + +TEST(io_reader, scalar_pos) { + std::vector theta_i; + std::vector theta; + theta.push_back(1.0); + theta.push_back(2.0); + stan::io::reader reader(theta, theta_i); + double x = reader.scalar_pos(); + EXPECT_FLOAT_EQ(1.0, x); + double y = reader.scalar_pos(); + EXPECT_FLOAT_EQ(2.0, y); + EXPECT_EQ(0U, reader.available()); +} +TEST(io_reader, scalar_pos_exception) { + std::vector theta_i; + std::vector theta; + theta.push_back(1.0); + theta.push_back(-1.0); + stan::io::reader reader(theta, theta_i); + EXPECT_NO_THROW(reader.scalar_pos()); + EXPECT_THROW(reader.scalar_pos(), std::domain_error); +} +TEST(io_reader, scalar_pos_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::reader reader(theta, theta_i); + EXPECT_FLOAT_EQ(exp(-2.0), reader.scalar_pos_constrain()); + EXPECT_FLOAT_EQ(exp(3.0), reader.scalar_pos_constrain()); + EXPECT_FLOAT_EQ(exp(-1.0), reader.scalar_pos_constrain()); + EXPECT_FLOAT_EQ(exp(0.0), reader.scalar_pos_constrain()); +} +TEST(io_reader, scalar_pos_constrain_falselp) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::reader reader(theta, theta_i); + double lp = -1.2; + EXPECT_FLOAT_EQ(exp(-2.0), reader.scalar_pos_constrain(lp)); + EXPECT_FLOAT_EQ(exp(3.0), reader.scalar_pos_constrain(lp)); + EXPECT_FLOAT_EQ(exp(-1.0), reader.scalar_pos_constrain(lp)); + EXPECT_FLOAT_EQ(exp(0.0), reader.scalar_pos_constrain(lp)); +} +TEST(io_reader, scalar_pos_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::reader reader(theta, theta_i); + double lp = -1.2; + EXPECT_FLOAT_EQ(exp(-2.0), reader.scalar_pos_constrain(lp)); + EXPECT_FLOAT_EQ(exp(3.0), reader.scalar_pos_constrain(lp)); + EXPECT_FLOAT_EQ(exp(-1.0), reader.scalar_pos_constrain(lp)); + EXPECT_FLOAT_EQ(exp(0.0), reader.scalar_pos_constrain(lp)); + EXPECT_FLOAT_EQ(-1.2 + -2.0 + 3.0 - 1.0, lp); +} + +TEST(io_reader, scalar_lb) { + std::vector theta_i; + std::vector theta; + theta.push_back(-1.0); + theta.push_back(2.0); + stan::io::reader reader(theta, theta_i); + double x = reader.scalar_lb(-2.0); + EXPECT_FLOAT_EQ(-1.0, x); + double y = reader.scalar_lb(1.0); + EXPECT_FLOAT_EQ(2.0, y); + EXPECT_EQ(0U, reader.available()); +} +TEST(io_reader, scalar_lb_exception) { + std::vector theta_i; + std::vector theta; + theta.push_back(-1.0); + theta.push_back(2.0); + stan::io::reader reader(theta, theta_i); + EXPECT_NO_THROW(reader.scalar_lb(-1.0)); + EXPECT_THROW(reader.scalar_lb(3.0), std::domain_error); +} +TEST(io_reader, scalar_lb_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::reader reader(theta, theta_i); + EXPECT_FLOAT_EQ(1.0 + exp(-2.0), reader.scalar_lb_constrain(1.0)); + EXPECT_FLOAT_EQ(5.0 + exp(3.0), reader.scalar_lb_constrain(5.0)); + EXPECT_FLOAT_EQ(-2.0 + exp(-1.0), reader.scalar_lb_constrain(-2.0)); + EXPECT_FLOAT_EQ(15.0 + exp(0.0), reader.scalar_lb_constrain(15.0)); +} +TEST(io_reader, scalar_lb_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::reader reader(theta, theta_i); + double lp = -1.5; + EXPECT_FLOAT_EQ(1.0 + exp(-2.0), reader.scalar_lb_constrain(1.0, lp)); + EXPECT_FLOAT_EQ(5.0 + exp(3.0), reader.scalar_lb_constrain(5.0, lp)); + EXPECT_FLOAT_EQ(-2.0 + exp(-1.0), reader.scalar_lb_constrain(-2.0, lp)); + EXPECT_FLOAT_EQ(15.0 + exp(0.0), reader.scalar_lb_constrain(15.0, lp)); + EXPECT_FLOAT_EQ(-1.5 - 2.0 + 3.0 - 1.0, lp); +} + +TEST(io_reader, scalar_ub) { + std::vector theta_i; + std::vector theta; + theta.push_back(-1.0); + theta.push_back(2.0); + stan::io::reader reader(theta, theta_i); + double x = reader.scalar_ub(-0.5); + EXPECT_FLOAT_EQ(-1.0, x); + double y = reader.scalar_ub(5.0); + EXPECT_FLOAT_EQ(2.0, y); + + EXPECT_EQ(0U, reader.available()); +} +TEST(io_reader, scalar_ub_exception) { + std::vector theta_i; + std::vector theta; + theta.push_back(-1.0); + theta.push_back(2.0); + stan::io::reader reader(theta, theta_i); + EXPECT_NO_THROW(reader.scalar_ub(-1.0)); + EXPECT_THROW(reader.scalar_ub(1.0), std::domain_error); +} +TEST(io_reader, scalar_ub_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::reader reader(theta, theta_i); + EXPECT_FLOAT_EQ(1.0 - exp(-2.0), reader.scalar_ub_constrain(1.0)); + EXPECT_FLOAT_EQ(5.0 - exp(3.0), reader.scalar_ub_constrain(5.0)); + EXPECT_FLOAT_EQ(-2.0 - exp(-1.0), reader.scalar_ub_constrain(-2.0)); + EXPECT_FLOAT_EQ(15.0 - exp(0.0), reader.scalar_ub_constrain(15.0)); +} +TEST(io_reader, scalar_ub_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::reader reader(theta, theta_i); + double lp = -12.9; + EXPECT_FLOAT_EQ(1.0 - exp(-2.0), reader.scalar_ub_constrain(1.0, lp)); + EXPECT_FLOAT_EQ(5.0 - exp(3.0), reader.scalar_ub_constrain(5.0, lp)); + EXPECT_FLOAT_EQ(-2.0 - exp(-1.0), reader.scalar_ub_constrain(-2.0, lp)); + EXPECT_FLOAT_EQ(15.0 - exp(0.0), reader.scalar_ub_constrain(15.0, lp)); + EXPECT_FLOAT_EQ(-12.9 - 2.0 + 3.0 - 1.0, lp); +} + +TEST(io_reader, scalar_lub) { + std::vector theta_i; + std::vector theta; + theta.push_back(-1.0); + theta.push_back(2.0); + stan::io::reader reader(theta, theta_i); + double x = reader.scalar_lub(-3.0, 3.0); + EXPECT_FLOAT_EQ(-1.0, x); + double y = reader.scalar_lub(-3.0, 3.0); + EXPECT_FLOAT_EQ(2.0, y); + + EXPECT_EQ(0U, reader.available()); +} +TEST(io_reader, scalar_lub_exception) { + std::vector theta_i; + std::vector theta; + theta.push_back(-1.0); + theta.push_back(2.0); + stan::io::reader reader(theta, theta_i); + EXPECT_NO_THROW(reader.scalar_lub(-2.0, 2.0)); + EXPECT_THROW(reader.scalar_lub(-1.0, 1.0), std::domain_error); +} +const double inv_logit_m2 = 0.1192029; // stan::math::inv_logit(-2.0) +const double inv_logit_m1 = 0.2689414; // stan::math::inv_logit(-1.0) +const double inv_logit_0 = 0.5; // stan::math::inv_logit(0) +const double inv_logit_3 = 0.9525741; // stan::math::inv_logit(3.0) + +TEST(io_reader, scalar_lub_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::reader reader(theta, theta_i); + EXPECT_FLOAT_EQ(inv_logit_m2, reader.scalar_lub_constrain(0.0, 1.0)); + EXPECT_FLOAT_EQ(3.0 + 2.0 * inv_logit_3, + reader.scalar_lub_constrain(3.0, 5.0)); + EXPECT_FLOAT_EQ(-3.0 + 5.0 * inv_logit_m1, + reader.scalar_lub_constrain(-3.0, 2.0)); + EXPECT_FLOAT_EQ(-15.0 + 30.0 * inv_logit_0, + reader.scalar_lub_constrain(-15.0, 15.0)); +} +TEST(io_reader, scalar_lub_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::reader reader(theta, theta_i); + double lp = -7.2; + EXPECT_FLOAT_EQ(0.0 + 1.0 * inv_logit_m2, + reader.scalar_lub_constrain(0.0, 1.0, lp)); + EXPECT_FLOAT_EQ(3.0 + 2.0 * inv_logit_3, + reader.scalar_lub_constrain(3.0, 5.0, lp)); + EXPECT_FLOAT_EQ(-3.0 + 5.0 * inv_logit_m1, + reader.scalar_lub_constrain(-3.0, 2.0, lp)); + EXPECT_FLOAT_EQ(-15.0 + 30.0 * inv_logit_0, + reader.scalar_lub_constrain(-15.0, 15.0, lp)); + double expected_lp = -7.2 + + log((1.0 - 0.0) * inv_logit_m2 * (1 - inv_logit_m2)) + + log((5.0 - 3.0) * inv_logit_3 * (1 - inv_logit_3)) + + log((2.0 - -3.0) * inv_logit_m1 * (1 - inv_logit_m1)) + + log((15.0 - -15.0) * inv_logit_0 * (1 - inv_logit_0)); + EXPECT_FLOAT_EQ(expected_lp, lp); +} + +TEST(io_reader, scalar_offset_multiplier) { + std::vector theta_i; + std::vector theta; + theta.push_back(-1.0); + theta.push_back(2.0); + stan::io::reader reader(theta, theta_i); + double x = reader.scalar_offset_multiplier(-3.0, 3.0); + EXPECT_FLOAT_EQ(-1.0, x); + double y = reader.scalar_offset_multiplier(-3.0, 3.0); + EXPECT_FLOAT_EQ(2.0, y); + + EXPECT_EQ(0U, reader.available()); +} +TEST(io_reader, scalar_offset_multiplier_exception) { + std::vector theta_i; + std::vector theta; + theta.push_back(-1.0); + theta.push_back(2.0); + stan::io::reader reader(theta, theta_i); + EXPECT_NO_THROW(reader.scalar_offset_multiplier(-2.0, -2.0)); + EXPECT_THROW(reader.scalar_offset_multiplier_constrain(-2.0, -2.0), + std::domain_error); +} + +TEST(io_reader, scalar_offset_multiplier_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::reader reader(theta, theta_i); + EXPECT_FLOAT_EQ(-2.0, reader.scalar_offset_multiplier_constrain(0.0, 1.0)); + EXPECT_FLOAT_EQ(3.0 + 5.0 * 3.0, + reader.scalar_offset_multiplier_constrain(3.0, 5.0)); + EXPECT_FLOAT_EQ(-3.0 + 2.0 * -1.0, + reader.scalar_offset_multiplier_constrain(-3.0, 2.0)); + EXPECT_FLOAT_EQ(-15.0, + reader.scalar_offset_multiplier_constrain(-15.0, 15.0)); +} +TEST(io_reader, scalar_offset_multiplier_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::reader reader(theta, theta_i); + double lp = -7.2; + EXPECT_FLOAT_EQ(-2.0, + reader.scalar_offset_multiplier_constrain(0.0, 1.0, lp)); + EXPECT_FLOAT_EQ(3.0 + 5.0 * 3.0, + reader.scalar_offset_multiplier_constrain(3.0, 5.0, lp)); + EXPECT_FLOAT_EQ(-3.0 + 2.0 * -1.0, + reader.scalar_offset_multiplier_constrain(-3.0, 2.0, lp)); + EXPECT_FLOAT_EQ(-15.0, + reader.scalar_offset_multiplier_constrain(-15.0, 15.0, lp)); + double expected_lp = -7.2 + log(1.0) + log(5.0) + log(2.0) + log(15.0); + EXPECT_FLOAT_EQ(expected_lp, lp); +} + +TEST(io_reader, prob) { + std::vector theta_i; + std::vector theta; + theta.push_back(0.9); + theta.push_back(0.1); + theta.push_back(0.0); + stan::io::reader reader(theta, theta_i); + double p1 = reader.prob(); + EXPECT_FLOAT_EQ(0.9, p1); + double p2 = reader.prob(); + EXPECT_FLOAT_EQ(0.1, p2); + double p3 = reader.prob(); + EXPECT_FLOAT_EQ(0.0, p3); + + EXPECT_EQ(0U, reader.available()); +} +TEST(io_reader, prob_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::reader reader(theta, theta_i); + EXPECT_FLOAT_EQ(inv_logit_m2, reader.prob_constrain()); + EXPECT_FLOAT_EQ(inv_logit_3, reader.prob_constrain()); + EXPECT_FLOAT_EQ(inv_logit_m1, reader.prob_constrain()); + EXPECT_FLOAT_EQ(inv_logit_0, reader.prob_constrain()); +} +TEST(io_reader, prob_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::reader reader(theta, theta_i); + double lp = -0.88; + EXPECT_FLOAT_EQ(inv_logit_m2, reader.prob_constrain(lp)); + EXPECT_FLOAT_EQ(inv_logit_3, reader.prob_constrain(lp)); + EXPECT_FLOAT_EQ(inv_logit_m1, reader.prob_constrain(lp)); + EXPECT_FLOAT_EQ(inv_logit_0, reader.prob_constrain(lp)); + double expected_lp = -0.88 + log(inv_logit_m2 * (1.0 - inv_logit_m2)) + + log(inv_logit_3 * (1.0 - inv_logit_3)) + + log(inv_logit_m1 * (1.0 - inv_logit_m1)) + + log(inv_logit_0 * (1.0 - inv_logit_0)); + EXPECT_FLOAT_EQ(expected_lp, lp); +} + +TEST(io_reader, corr) { + std::vector theta_i; + std::vector theta; + theta.push_back(-0.9); + theta.push_back(0.1); + theta.push_back(0.0); + stan::io::reader reader(theta, theta_i); + double rho1 = reader.corr(); + EXPECT_FLOAT_EQ(-0.9, rho1); + double rho2 = reader.corr(); + EXPECT_FLOAT_EQ(0.1, rho2); + double rho3 = reader.corr(); + EXPECT_FLOAT_EQ(0.0, rho3); + + EXPECT_EQ(0U, reader.available()); +} +TEST(io_reader, corr_exception) { + std::vector theta_i; + std::vector theta; + theta.push_back(-0.9); + theta.push_back(-1.1); + theta.push_back(1.1); + stan::io::reader reader(theta, theta_i); + EXPECT_NO_THROW(reader.corr()); + EXPECT_THROW(reader.corr(), std::domain_error); + EXPECT_THROW(reader.corr(), std::domain_error); +} +TEST(io_reader, corr_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::reader reader(theta, theta_i); + EXPECT_FLOAT_EQ(tanh(-2.0), reader.corr_constrain()); + EXPECT_FLOAT_EQ(tanh(3.0), reader.corr_constrain()); + EXPECT_FLOAT_EQ(tanh(-1.0), reader.corr_constrain()); + EXPECT_FLOAT_EQ(tanh(0.0), reader.corr_constrain()); +} +TEST(io_reader, corr_constrain_jacobian) { + using std::tanh; + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::reader reader(theta, theta_i); + double lp = -10.0; + EXPECT_FLOAT_EQ(tanh(-2.0), reader.corr_constrain(lp)); + EXPECT_FLOAT_EQ(tanh(3.0), reader.corr_constrain(lp)); + EXPECT_FLOAT_EQ(tanh(-1.0), reader.corr_constrain(lp)); + EXPECT_FLOAT_EQ(tanh(0.0), reader.corr_constrain(lp)); + double expected_lp = -10.0 + log(1.0 - tanh(-2.0) * tanh(-2.0)) + + log(1.0 - tanh(3.0) * tanh(3.0)) + + log(1.0 - tanh(-1.0) * tanh(-1.0)) + + log(1.0 - tanh(0.0) * tanh(0.0)); + EXPECT_FLOAT_EQ(expected_lp, lp); +} + +TEST(io_reader, std_vector) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100U; ++i) + theta.push_back(static_cast(i)); + stan::io::reader reader(theta, theta_i); + for (size_t i = 0; i < 10U; ++i) { + double x = reader.scalar(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + std::vector y = reader.std_vector(3); + EXPECT_EQ(3U, y.size()); + EXPECT_FLOAT_EQ(10.0, y[0]); + EXPECT_FLOAT_EQ(11.0, y[1]); + EXPECT_FLOAT_EQ(12.0, y[2]); + + std::vector z = reader.std_vector(17); + EXPECT_EQ(17U, z.size()); + + double a = reader.scalar(); + EXPECT_FLOAT_EQ(30.0, a); +} + +TEST(io_reader, vector) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100U; ++i) + theta.push_back(static_cast(i)); + stan::io::reader reader(theta, theta_i); + for (size_t i = 0; i < 7U; ++i) { + double x = reader.scalar(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + Eigen::Matrix y = reader.vector(4); + EXPECT_EQ(4, y.rows()); + EXPECT_EQ(1, y.cols()); + EXPECT_EQ(4, y.size()); + EXPECT_FLOAT_EQ(7.0, y[0]); + EXPECT_FLOAT_EQ(8.0, y[1]); + EXPECT_FLOAT_EQ(9.0, y[2]); + EXPECT_FLOAT_EQ(10.0, y[3]); + + double z = reader.scalar(); + EXPECT_FLOAT_EQ(11.0, z); +} + +TEST(io_reader, row_vector) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100U; ++i) + theta.push_back(static_cast(i)); + stan::io::reader reader(theta, theta_i); + for (size_t i = 0; i < 7U; ++i) { + double x = reader.scalar(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + Eigen::Matrix y = reader.row_vector(4); + EXPECT_EQ(4, y.cols()); + EXPECT_EQ(1, y.rows()); + EXPECT_EQ(4, y.size()); + EXPECT_FLOAT_EQ(7.0, y[0]); + EXPECT_FLOAT_EQ(8.0, y[1]); + EXPECT_FLOAT_EQ(9.0, y[2]); + EXPECT_FLOAT_EQ(10.0, y[3]); + + double z = reader.scalar(); + EXPECT_FLOAT_EQ(11.0, z); +} + +TEST(io_reader, matrix) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::reader reader(theta, theta_i); + for (int i = 0; i < 7; ++i) { + double x = reader.scalar(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + Eigen::Matrix y = reader.matrix(3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(7.0, y(0, 0)); + EXPECT_FLOAT_EQ(8.0, y(1, 0)); + EXPECT_FLOAT_EQ(9.0, y(2, 0)); + EXPECT_FLOAT_EQ(10.0, y(0, 1)); + EXPECT_FLOAT_EQ(11.0, y(1, 1)); + EXPECT_FLOAT_EQ(12.0, y(2, 1)); + + double a = reader.scalar(); + EXPECT_FLOAT_EQ(13.0, a); +} + +TEST(io_reader, matrix_constrain) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::reader reader(theta, theta_i); + for (int i = 0; i < 7; ++i) { + double x = reader.scalar(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + Eigen::Matrix y + = reader.matrix_constrain(3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(7.0, y(0, 0)); + EXPECT_FLOAT_EQ(8.0, y(1, 0)); + EXPECT_FLOAT_EQ(9.0, y(2, 0)); + EXPECT_FLOAT_EQ(10.0, y(0, 1)); + EXPECT_FLOAT_EQ(11.0, y(1, 1)); + EXPECT_FLOAT_EQ(12.0, y(2, 1)); + + double a = reader.scalar(); + EXPECT_FLOAT_EQ(13.0, a); +} + +TEST(io_reader, unit_vector) { + std::vector theta_i(0); + std::vector theta(4, sqrt(0.25)); + stan::io::reader reader(theta, theta_i); + Eigen::Matrix y = reader.unit_vector(4); + EXPECT_EQ(4, y.size()); + EXPECT_FLOAT_EQ(sqrt(0.25), y[0]); + EXPECT_FLOAT_EQ(sqrt(0.25), y[1]); + EXPECT_FLOAT_EQ(sqrt(0.25), y[2]); + EXPECT_FLOAT_EQ(sqrt(0.25), y[3]); +} +TEST(io_reader, unit_vector_exception) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100; ++i) + theta.push_back(static_cast(i)); + stan::io::reader reader(theta, theta_i); + theta[0] = 0.00; + theta[1] = -sqrt(0.29); + theta[2] = sqrt(0.70); + theta[3] = -sqrt(0.01); + theta[4] = sqrt(1.0); + theta[5] = sqrt(1.0); + EXPECT_NO_THROW(reader.unit_vector(4)); + EXPECT_THROW(reader.unit_vector(2), std::domain_error); + EXPECT_THROW(reader.unit_vector(0), std::invalid_argument); +} + +TEST(io_reader, simplex) { + std::vector theta_i(0); + std::vector theta(4, 0.25); + stan::io::reader reader(theta, theta_i); + Eigen::Matrix y = reader.simplex(4); + EXPECT_EQ(4, y.size()); + EXPECT_FLOAT_EQ(0.25, y[0]); + EXPECT_FLOAT_EQ(0.25, y[1]); + EXPECT_FLOAT_EQ(0.25, y[2]); + EXPECT_FLOAT_EQ(0.25, y[3]); +} +TEST(io_reader, simplex_exception) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100; ++i) + theta.push_back(static_cast(i)); + stan::io::reader reader(theta, theta_i); + theta[0] = 0.00; + theta[1] = 0.29; + theta[2] = 0.70; + theta[3] = 0.01; + theta[4] = 1.0; + theta[5] = 1.0; + EXPECT_NO_THROW(reader.simplex(4)); + EXPECT_THROW(reader.simplex(2), std::domain_error); + EXPECT_THROW(reader.simplex(0), std::invalid_argument); +} + +TEST(io_reader, ordered) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::reader reader(theta, theta_i); + EXPECT_FLOAT_EQ(0.0, reader.scalar()); // throw away theta[0] + Eigen::Matrix y = reader.ordered(5); + EXPECT_EQ(5, y.size()); + EXPECT_FLOAT_EQ(1.0, y[0]); + EXPECT_FLOAT_EQ(2.0, y[1]); + EXPECT_FLOAT_EQ(5.0, y[4]); + EXPECT_FLOAT_EQ(6.0, reader.scalar()); +} +TEST(io_reader, ordered_exception) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::reader reader(theta, theta_i); + EXPECT_FLOAT_EQ(0.0, reader.scalar()); // throw away theta[0] + Eigen::Matrix y = reader.ordered(5); + EXPECT_EQ(5, y.size()); + EXPECT_FLOAT_EQ(1.0, y[0]); + EXPECT_FLOAT_EQ(2.0, y[1]); + EXPECT_FLOAT_EQ(5.0, y[4]); + EXPECT_FLOAT_EQ(6.0, reader.scalar()); +} +TEST(io_reader, ordered_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + double v0 = 3.0; + double v1 = v0 + exp(-1.0); + double v2 = v1 + exp(-2.0); + double v3 = v2 + exp(0.0); + stan::io::reader reader(theta, theta_i); + Eigen::Matrix phi(reader.ordered_constrain(4)); + EXPECT_FLOAT_EQ(v0, phi[0]); + EXPECT_FLOAT_EQ(v1, phi[1]); + EXPECT_FLOAT_EQ(v2, phi[2]); + EXPECT_FLOAT_EQ(v3, phi[3]); +} +TEST(io_reader, ordered_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + double v0 = 3.0; + double v1 = v0 + exp(-1.0); + double v2 = v1 + exp(-2.0); + double v3 = v2 + exp(0.0); + stan::io::reader reader(theta, theta_i); + double lp = -101.1; + double expected_lp = lp - 1.0 - 2.0 + 0.0; + Eigen::Matrix phi(reader.ordered_constrain(4, lp)); + EXPECT_FLOAT_EQ(v0, phi[0]); + EXPECT_FLOAT_EQ(v1, phi[1]); + EXPECT_FLOAT_EQ(v2, phi[2]); + EXPECT_FLOAT_EQ(v3, phi[3]); + EXPECT_FLOAT_EQ(expected_lp, lp); +} + +TEST(io_reader, positive_ordered) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::reader reader(theta, theta_i); + EXPECT_FLOAT_EQ(0.0, reader.scalar()); // throw away theta[0] + Eigen::Matrix y = reader.positive_ordered(5); + EXPECT_EQ(5, y.size()); + EXPECT_FLOAT_EQ(1.0, y[0]); + EXPECT_FLOAT_EQ(2.0, y[1]); + EXPECT_FLOAT_EQ(5.0, y[4]); + EXPECT_FLOAT_EQ(6.0, reader.scalar()); +} + +TEST(io_reader, positive_ordered_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + double v0 = exp(3.0); + double v1 = v0 + exp(-1.0); + double v2 = v1 + exp(-2.0); + double v3 = v2 + exp(0.0); + stan::io::reader reader(theta, theta_i); + Eigen::Matrix phi( + reader.positive_ordered_constrain(4)); + EXPECT_FLOAT_EQ(v0, phi[0]); + EXPECT_FLOAT_EQ(v1, phi[1]); + EXPECT_FLOAT_EQ(v2, phi[2]); + EXPECT_FLOAT_EQ(v3, phi[3]); +} +TEST(io_reader, positive_ordered_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + double v0 = exp(3.0); + double v1 = v0 + exp(-1.0); + double v2 = v1 + exp(-2.0); + double v3 = v2 + exp(0.0); + stan::io::reader reader(theta, theta_i); + double lp = -101.1; + double expected_lp = lp + 3.0 - 1.0 - 2.0 + 0.0; + Eigen::Matrix phi( + reader.positive_ordered_constrain(4, lp)); + EXPECT_FLOAT_EQ(v0, phi[0]); + EXPECT_FLOAT_EQ(v1, phi[1]); + EXPECT_FLOAT_EQ(v2, phi[2]); + EXPECT_FLOAT_EQ(v3, phi[3]); + EXPECT_FLOAT_EQ(expected_lp, lp); +} + +TEST(io_reader, corr_matrix) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + theta[0] = 1.0000000000000000; + theta[1] = 0.1817621852191252; + theta[2] = 0.8620926037637362; + theta[3] = 0.1817621852191252; + theta[4] = 1.0000000000000000; + theta[5] = 0.2248293054822660; + theta[6] = 0.8620926037637362; + theta[7] = 0.2248293054822660; + theta[8] = 1.0000000000000001; // allow some tolerance + stan::io::reader reader(theta, theta_i); + Eigen::Matrix S + = reader.corr_matrix(3); + EXPECT_FLOAT_EQ(theta[0], S(0, 0)); +} +TEST(io_reader, corr_matrix_exception) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + theta[0] = 1.5; + theta[1] = 1.0; + theta[2] = 2.0; + theta[3] = 0.0; + theta[4] = 1.0; + stan::io::reader reader(theta, theta_i); + EXPECT_THROW(reader.corr_matrix(1), std::domain_error); + EXPECT_THROW(reader.corr_matrix(2), std::domain_error); +} +TEST(io_reader, corr_matrix_constrain) { + using Eigen::Dynamic; + using Eigen::Matrix; + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(-1.0); + theta.push_back(0.0); + theta.push_back(0.5); + theta.push_back(1.0); + theta.push_back(2.0); + theta.push_back(1.0); + stan::io::reader reader(theta, theta_i); + Matrix R(reader.corr_matrix_constrain(3U)); + EXPECT_EQ(3, R.rows()); + EXPECT_EQ(3, R.cols()); + EXPECT_EQ(9, R.size()); + EXPECT_EQ(4U, reader.available()); + for (size_t i = 0; i < 3U; ++i) { + EXPECT_FLOAT_EQ(1.0, R(i, i)); + for (size_t j = i + 1; j < 3U; ++j) + EXPECT_FLOAT_EQ(R(i, j), R(j, i)); + } + Eigen::SelfAdjointEigenSolver< + Eigen::Matrix> + solver(R, Eigen::EigenvaluesOnly); + assert(solver.eigenvalues()[0] > 1E-10); +} +TEST(io_reader, corr_matrix_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(-1.0); + theta.push_back(0.0); + theta.push_back(0.5); + theta.push_back(1.0); + theta.push_back(2.0); + theta.push_back(1.0); + stan::io::reader reader(theta, theta_i); + double lp = -9.2; + Eigen::Matrix R( + reader.corr_matrix_constrain(3U, lp)); + EXPECT_EQ(3, R.rows()); + EXPECT_EQ(3, R.cols()); + EXPECT_EQ(9, R.size()); + EXPECT_EQ(4U, reader.available()); + for (size_t i = 0; i < 3U; ++i) { + EXPECT_FLOAT_EQ(1.0, R(i, i)); + for (size_t j = i + 1; j < 3U; ++j) + EXPECT_FLOAT_EQ(R(i, j), R(j, i)); + } + Eigen::SelfAdjointEigenSolver< + Eigen::Matrix> + solver(R, Eigen::EigenvaluesOnly); + assert(solver.eigenvalues()[0] > 1E-10); + // FIXME: test jacobian +} + +TEST(io_reader, cov_matrix) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + theta[0] = 6.3295234356180128; + theta[1] = 0.6351775806192667; + theta[2] = 3.8081029582054304; + theta[3] = 0.6351775806192667; + theta[4] = 1.9293554162496527; + theta[5] = 0.5483126868366485; + theta[6] = 3.8081029582054304; + theta[7] = 0.5483126868366485; + theta[8] = 3.0827514661973088; + stan::io::reader reader(theta, theta_i); + Eigen::Matrix S + = reader.cov_matrix(3); + EXPECT_FLOAT_EQ(theta[0], S(0, 0)); + EXPECT_FLOAT_EQ(theta[1], S(1, 0)); + EXPECT_FLOAT_EQ(theta[7], S(2, 1)); + EXPECT_FLOAT_EQ(theta[8], S(2, 2)); +} +TEST(io_reader, cov_matrix_exception) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + theta[0] = 6.3; + theta[1] = 0.7; + theta[2] = 0.6; + theta[3] = 1.9; + stan::io::reader reader(theta, theta_i); + EXPECT_THROW(reader.cov_matrix(2), std::domain_error); + EXPECT_THROW(reader.cov_matrix(0), std::invalid_argument); +} +TEST(io_reader, cov_matrix_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(-1.0); + theta.push_back(0.0); + theta.push_back(0.5); + theta.push_back(1.0); + theta.push_back(2.0); + theta.push_back(1.0); + stan::io::reader reader(theta, theta_i); + Eigen::Matrix S( + reader.cov_matrix_constrain(3U)); + EXPECT_EQ(3, S.rows()); + EXPECT_EQ(3, S.cols()); + EXPECT_EQ(9, S.size()); + EXPECT_EQ(1U, reader.available()); + for (size_t i = 0; i < 3U; ++i) + for (size_t j = i + 1; j < 3U; ++j) + EXPECT_FLOAT_EQ(S(i, j), S(j, i)); + Eigen::SelfAdjointEigenSolver< + Eigen::Matrix> + solver(S, Eigen::EigenvaluesOnly); + assert(solver.eigenvalues()[0] + > 1E-10); // check positive definite with smallest eigenvalue > 0 +} +TEST(io_reader, cov_matrix_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(-1.0); + theta.push_back(0.0); + theta.push_back(0.5); + theta.push_back(1.0); + theta.push_back(2.0); + theta.push_back(1.0); + stan::io::reader reader(theta, theta_i); + double lp = -3.1; + + Eigen::Matrix S( + reader.cov_matrix_constrain(3U, lp)); + + EXPECT_EQ(3, S.rows()); + EXPECT_EQ(3, S.cols()); + EXPECT_EQ(9, S.size()); + EXPECT_EQ(1U, reader.available()); + for (size_t i = 0; i < 3U; ++i) + for (size_t j = i + 1; j < 3U; ++j) + EXPECT_FLOAT_EQ(S(i, j), S(j, i)); + Eigen::SelfAdjointEigenSolver< + Eigen::Matrix> + solver(S, Eigen::EigenvaluesOnly); + assert(solver.eigenvalues()[0] + > 1E-10); // check positive definite with smallest eigenvalue > 0 + // FIXME: test Jacobian +} + +TEST(io_reader, cholesky_factor_cov) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + // column major + theta[0] = 1; + theta[1] = 2; + theta[2] = 3; + + theta[3] = 0; + theta[4] = 4; + theta[5] = 5; + + theta[6] = 0; + theta[7] = 0; + theta[8] = 6; + stan::io::reader reader(theta, theta_i); + Eigen::Matrix S + = reader.cholesky_factor_cov(3, 3); + EXPECT_FLOAT_EQ(theta[0], S(0, 0)); + EXPECT_FLOAT_EQ(theta[1], S(1, 0)); + EXPECT_FLOAT_EQ(theta[7], S(1, 2)); + EXPECT_FLOAT_EQ(theta[8], S(2, 2)); +} +TEST(io_reader, cholesky_factor_cov_asymmetric) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + // column major + theta[0] = 1; + theta[1] = 2; + theta[2] = 3; + + theta[3] = 0; + theta[4] = 4; + theta[5] = 5; + + stan::io::reader reader(theta, theta_i); + Eigen::Matrix S + = reader.cholesky_factor_cov(3, 2); + EXPECT_FLOAT_EQ(theta[0], S(0, 0)); + EXPECT_FLOAT_EQ(theta[1], S(1, 0)); + EXPECT_FLOAT_EQ(theta[2], S(2, 0)); + + EXPECT_FLOAT_EQ(theta[3], S(0, 1)); + EXPECT_FLOAT_EQ(theta[4], S(1, 1)); + EXPECT_FLOAT_EQ(theta[5], S(2, 1)); +} + +TEST(io_reader, cholesky_factor_cov_exception) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + theta[0] = -6.3; + stan::io::reader reader(theta, theta_i); + EXPECT_THROW(reader.cholesky_factor_cov(2, 2), std::domain_error); + EXPECT_THROW(reader.cholesky_factor_cov(0, 0), std::domain_error); + + theta[0] = 1; + EXPECT_THROW(reader.cholesky_factor_cov(2, 3), std::domain_error); +} +TEST(io_reader, cholesky_factor_cov_constrain) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 8; ++i) + theta.push_back(-static_cast(i)); + stan::io::reader reader(theta, theta_i); + Eigen::Matrix L( + reader.cholesky_factor_cov_constrain(3U, 3U)); + EXPECT_NO_THROW(stan::math::check_cholesky_factor( + "test_cholesky_factor_constrain", "L", L)); + EXPECT_EQ(3, L.rows()); + EXPECT_EQ(3, L.cols()); + EXPECT_EQ(9, L.size()); + EXPECT_EQ(2U, reader.available()); +} +TEST(io_reader, cholesky_factor_cov_constrain_asymmetric) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 8; ++i) + theta.push_back(-static_cast(i)); + stan::io::reader reader(theta, theta_i); + Eigen::Matrix L( + reader.cholesky_factor_cov_constrain(3U, 2U)); + EXPECT_NO_THROW(stan::math::check_cholesky_factor( + "test_cholesky_factor_constrain", "L", L)); + EXPECT_EQ(3, L.rows()); + EXPECT_EQ(2, L.cols()); + EXPECT_EQ(6, L.size()); + EXPECT_EQ(3U, reader.available()); +} +TEST(io_reader, cholesky_factor_cov_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 8; ++i) + theta.push_back(-static_cast(i)); + stan::io::reader reader(theta, theta_i); + double lp = 1.9; + Eigen::Matrix L( + reader.cholesky_factor_cov_constrain(3U, 3U, lp)); + EXPECT_NO_THROW(stan::math::check_cholesky_factor( + "test_cholesky_factor_constrain", "L", L)); + EXPECT_EQ(3, L.rows()); + EXPECT_EQ(3, L.cols()); + EXPECT_EQ(9, L.size()); + EXPECT_EQ(2U, reader.available()); + EXPECT_EQ(1.9 + log(L(0, 0)) + log(L(1, 1)) + log(L(2, 2)), lp); +} +TEST(io_reader, cholesky_factor_cov_constrain_jacobian_asymmetric) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 12; ++i) + theta.push_back(-static_cast(i)); + stan::io::reader reader(theta, theta_i); + double lp = 1.9; + Eigen::Matrix L( + reader.cholesky_factor_cov_constrain(4U, 3U, lp)); + EXPECT_NO_THROW(stan::math::check_cholesky_factor( + "test_cholesky_factor_constrain", "L", L)); + EXPECT_EQ(4, L.rows()); + EXPECT_EQ(3, L.cols()); + EXPECT_EQ(12, L.size()); + EXPECT_EQ(3U, reader.available()); + EXPECT_EQ(1.9 + log(L(0, 0)) + log(L(1, 1)) + log(L(2, 2)), lp); +} + +TEST(io_reader, cholesky_factor_corr) { + std::vector theta_i; + std::vector theta(9); + // column major + theta[0] = 1; + theta[1] = 0; + theta[2] = 0; + + theta[3] = 0; + theta[4] = 1; + theta[5] = 0; + + theta[6] = 0; + theta[7] = 0; + theta[8] = 1; + stan::io::reader reader(theta, theta_i); + Eigen::Matrix S + = reader.cholesky_factor_corr(3); + EXPECT_FLOAT_EQ(theta[0], S(0, 0)); + EXPECT_FLOAT_EQ(theta[1], S(1, 0)); + EXPECT_FLOAT_EQ(theta[4], S(1, 1)); + EXPECT_FLOAT_EQ(theta[7], S(1, 2)); + EXPECT_FLOAT_EQ(theta[8], S(2, 2)); +} + +TEST(io_reader, cholesky_factor_corr_exception) { + std::vector theta_i; + std::vector theta(9); + Eigen::Matrix S; + + // non lower-triangular matrix (column major) + // the rest of these tests are with check_cholesky_factor_corr + theta[0] = 1; + theta[1] = 0; + theta[2] = 0; + + theta[3] = 0.5; + theta[4] = 1; + theta[5] = 0; + + theta[6] = 0; + theta[7] = 0; + theta[8] = 1; + stan::io::reader reader(theta, theta_i); + EXPECT_THROW(reader.cholesky_factor_corr(3), std::domain_error); +} +TEST(io_reader, cholesky_factor_corr_constrain) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 8; ++i) + theta.push_back(-static_cast(i)); + stan::io::reader reader(theta, theta_i); + Eigen::Matrix L( + reader.cholesky_factor_corr_constrain(3U)); + EXPECT_NO_THROW(stan::math::check_cholesky_factor_corr( + "test_cholesky_factor_corr_constrain", "L", L)); + EXPECT_EQ(3, L.rows()); + EXPECT_EQ(3, L.cols()); + EXPECT_EQ(9, L.size()); + EXPECT_EQ(5U, reader.available()); +} + +TEST(io_reader, eos_exception) { + std::vector theta; + theta.push_back(1.0); + theta.push_back(2.0); + std::vector theta_i; + theta_i.push_back(1); + stan::io::reader reader(theta, theta_i); + + EXPECT_EQ(2U, reader.available()); + EXPECT_EQ(1U, reader.available_i()); + + EXPECT_NO_THROW(reader.scalar()); + EXPECT_NO_THROW(reader.scalar()); + EXPECT_THROW(reader.scalar(), std::runtime_error); + + // should go back to working + EXPECT_NO_THROW(reader.integer()); + EXPECT_THROW(reader.integer(), std::runtime_error); + + // should keep throwing + EXPECT_THROW(reader.scalar(), std::runtime_error); + EXPECT_THROW(reader.integer(), std::runtime_error); +} + +TEST(io_reader, lub_exception) { + std::vector theta; + for (int i = 0; i < 10; ++i) + theta.push_back(static_cast(i)); + std::vector theta_i; + for (int i = 0; i < 10; ++i) + theta_i.push_back(i); + stan::io::reader reader(theta, theta_i); + + EXPECT_THROW(reader.scalar_lb(10.0), std::domain_error); + EXPECT_THROW(reader.scalar_ub(-2.0), std::domain_error); + EXPECT_THROW(reader.scalar_lub(-20.0, -18.0), std::domain_error); + EXPECT_THROW(reader.scalar_lub(-18.0, -20.0), std::domain_error); + EXPECT_FLOAT_EQ(4.0, reader.scalar()); + + EXPECT_THROW(reader.integer_lb(10), std::runtime_error); + EXPECT_THROW(reader.integer_ub(-2), std::runtime_error); + EXPECT_THROW(reader.integer_lub(-20, -18), std::runtime_error); + EXPECT_THROW(reader.integer_lub(-18, -20), std::runtime_error); + EXPECT_EQ(4, reader.integer()); +} + +TEST(io_reader, matrix_lb) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::reader reader(theta, theta_i); + for (int i = 0; i < 7; ++i) { + double x = reader.scalar(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + double lb = -1.5; + Eigen::Matrix y + = reader.matrix_lb(lb, 3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(7.0, y(0, 0)); + EXPECT_FLOAT_EQ(8.0, y(1, 0)); + EXPECT_FLOAT_EQ(9.0, y(2, 0)); + EXPECT_FLOAT_EQ(10.0, y(0, 1)); + EXPECT_FLOAT_EQ(11.0, y(1, 1)); + EXPECT_FLOAT_EQ(12.0, y(2, 1)); + + double a = reader.scalar(); + EXPECT_FLOAT_EQ(13.0, a); +} + +TEST(io_reader, matrix_lb_constrain) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::reader reader(theta, theta_i); + for (int i = 0; i < 7; ++i) { + double x = reader.scalar(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + double lb = -1.5; + Eigen::Matrix y + = reader.matrix_lb_constrain(lb, 3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(7.0, lb), y(0, 0)); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(8.0, lb), y(1, 0)); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(9.0, lb), y(2, 0)); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(10.0, lb), y(0, 1)); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(11.0, lb), y(1, 1)); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(12.0, lb), y(2, 1)); + + double a = reader.scalar(); + EXPECT_FLOAT_EQ(13.0, a); +} + +TEST(io_reader, matrix_lb_constrain_lp) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::reader reader(theta, theta_i); + for (int i = 0; i < 7; ++i) { + double x = reader.scalar(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + double lb = -1.5; + double lp = -5.0; + Eigen::Matrix y + = reader.matrix_lb_constrain(lb, 3, 2, lp); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(7.0, lb, lp), y(0, 0)); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(8.0, lb, lp), y(1, 0)); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(9.0, lb, lp), y(2, 0)); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(10.0, lb, lp), y(0, 1)); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(11.0, lb, lp), y(1, 1)); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(12.0, lb, lp), y(2, 1)); + + double a = reader.scalar(); + EXPECT_FLOAT_EQ(13.0, a); +} + +TEST(io_reader, matrix_ub) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::reader reader(theta, theta_i); + for (int i = 0; i < 7; ++i) { + double x = reader.scalar(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + double ub = 12.5; + Eigen::Matrix y + = reader.matrix_ub(ub, 3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(7.0, y(0, 0)); + EXPECT_FLOAT_EQ(8.0, y(1, 0)); + EXPECT_FLOAT_EQ(9.0, y(2, 0)); + EXPECT_FLOAT_EQ(10.0, y(0, 1)); + EXPECT_FLOAT_EQ(11.0, y(1, 1)); + EXPECT_FLOAT_EQ(12.0, y(2, 1)); + + double a = reader.scalar(); + EXPECT_FLOAT_EQ(13.0, a); +} + +TEST(io_reader, matrix_ub_constrain) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::reader reader(theta, theta_i); + for (int i = 0; i < 7; ++i) { + double x = reader.scalar(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + double ub = 14.1; + Eigen::Matrix y + = reader.matrix_ub_constrain(ub, 3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(7.0, ub), y(0, 0)); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(8.0, ub), y(1, 0)); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(9.0, ub), y(2, 0)); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(10.0, ub), y(0, 1)); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(11.0, ub), y(1, 1)); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(12.0, ub), y(2, 1)); + + double a = reader.scalar(); + EXPECT_FLOAT_EQ(13.0, a); +} + +TEST(io_reader, matrix_ub_constrain_lp) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::reader reader(theta, theta_i); + for (int i = 0; i < 7; ++i) { + double x = reader.scalar(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + double ub = 12.1; + double lp = -5.0; + Eigen::Matrix y + = reader.matrix_ub_constrain(ub, 3, 2, lp); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(7.0, ub, lp), y(0, 0)); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(8.0, ub, lp), y(1, 0)); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(9.0, ub, lp), y(2, 0)); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(10.0, ub, lp), y(0, 1)); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(11.0, ub, lp), y(1, 1)); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(12.0, ub, lp), y(2, 1)); + + double a = reader.scalar(); + EXPECT_FLOAT_EQ(13.0, a); +} + +TEST(io_reader, matrix_lub) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::reader reader(theta, theta_i); + for (int i = 0; i < 7; ++i) { + double x = reader.scalar(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + double lb = 6.9; + double ub = 12.5; + Eigen::Matrix y + = reader.matrix_lub(lb, ub, 3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(7.0, y(0, 0)); + EXPECT_FLOAT_EQ(8.0, y(1, 0)); + EXPECT_FLOAT_EQ(9.0, y(2, 0)); + EXPECT_FLOAT_EQ(10.0, y(0, 1)); + EXPECT_FLOAT_EQ(11.0, y(1, 1)); + EXPECT_FLOAT_EQ(12.0, y(2, 1)); + + double a = reader.scalar(); + EXPECT_FLOAT_EQ(13.0, a); +} + +TEST(io_reader, matrix_lub_constrain) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::reader reader(theta, theta_i); + for (int i = 0; i < 7; ++i) { + double x = reader.scalar(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + double lb = 3.5; + double ub = 14.1; + Eigen::Matrix y + = reader.matrix_lub_constrain(lb, ub, 3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(7.0, lb, ub), y(0, 0)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(8.0, lb, ub), y(1, 0)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(9.0, lb, ub), y(2, 0)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(10.0, lb, ub), y(0, 1)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(11.0, lb, ub), y(1, 1)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(12.0, lb, ub), y(2, 1)); + + double a = reader.scalar(); + EXPECT_FLOAT_EQ(13.0, a); +} + +TEST(io_reader, matrix_lub_constrain_lp) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::reader reader(theta, theta_i); + for (int i = 0; i < 7; ++i) { + double x = reader.scalar(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + double lb = 4.1; + double ub = 12.1; + double lp = -5.0; + Eigen::Matrix y + = reader.matrix_lub_constrain(lb, ub, 3, 2, lp); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(7.0, lb, ub, lp), y(0, 0)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(8.0, lb, ub, lp), y(1, 0)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(9.0, lb, ub, lp), y(2, 0)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(10.0, lb, ub, lp), y(0, 1)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(11.0, lb, ub, lp), y(1, 1)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(12.0, lb, ub, lp), y(2, 1)); + + double a = reader.scalar(); + EXPECT_FLOAT_EQ(13.0, a); +} + +TEST(io_reader, SimplexThrows) { + std::vector theta; + std::vector theta_i; + stan::io::reader reader(theta, theta_i); + + double x = 0; + double lp = 0; + EXPECT_THROW(reader.simplex(x), std::invalid_argument); + EXPECT_THROW(reader.simplex_constrain(x), std::invalid_argument); + EXPECT_THROW(reader.simplex_constrain(x, lp), std::invalid_argument); +} + +TEST(io_reader, UnitVectorThrows) { + std::vector theta; + std::vector theta_i; + stan::io::reader reader(theta, theta_i); + + double x = 0; + double lp = 0; + EXPECT_THROW(reader.unit_vector(x), std::invalid_argument); + EXPECT_THROW(reader.unit_vector_constrain(x), std::invalid_argument); + EXPECT_THROW(reader.unit_vector_constrain(x, lp), std::invalid_argument); +} + +TEST(IoReader, var_vector) { + using stan::math::var; + using stan::math::var_value; + std::vector theta{0, 1, 2, 3, 4}; + std::vector theta_i; + stan::io::reader reader(theta, theta_i); + auto vec_x = reader.var_vector(5); + EXPECT_TRUE((stan::is_var_vector::value)); + for (int i = 0; i < 5; ++i) { + EXPECT_EQ(vec_x.val()(i), i); + } + auto vec_x_empty = reader.var_vector(0); + stan::math::recover_memory(); +} + +TEST(IoReader, var_vector_double) { + using stan::math::var; + using stan::math::var_value; + std::vector theta{0, 1, 2, 3, 4}; + std::vector theta_i; + stan::io::reader reader(theta, theta_i); + auto vec_x = reader.var_vector(5); + EXPECT_TRUE( + (stan::is_eigen_vector::value + && std::is_arithmetic>::value)); + for (int i = 0; i < 5; ++i) { + EXPECT_EQ(vec_x.val()(i), i); + } +} + +TEST(IoReader, var_row_vector) { + using stan::math::var; + using stan::math::var_value; + std::vector theta{0, 1, 2, 3, 4}; + std::vector theta_i; + stan::io::reader reader(theta, theta_i); + auto vec_x = reader.var_row_vector(5); + EXPECT_TRUE((stan::is_var_row_vector::value)); + for (int i = 0; i < 5; ++i) { + EXPECT_EQ(vec_x.val()(i), i); + } + auto vec_x_empty = reader.var_row_vector(0); +} + +TEST(IoReader, var_row_vector_double) { + using stan::math::var; + using stan::math::var_value; + std::vector theta{0, 1, 2, 3, 4}; + std::vector theta_i; + stan::io::reader reader(theta, theta_i); + auto vec_x = reader.var_row_vector(5); + EXPECT_TRUE( + (stan::is_eigen_row_vector::value + && std::is_arithmetic>::value)); + for (int i = 0; i < 5; ++i) { + EXPECT_EQ(vec_x.val()(i), i); + } + auto vec_x_empty = reader.var_row_vector(0); +} + +TEST(IoReader, var_matrix) { + using stan::math::var; + using stan::math::var_value; + std::vector theta{0, 1, 2, 3, 4, 5, 6, 7, 8}; + std::vector theta_i; + stan::io::reader reader(theta, theta_i); + auto mat_x = reader.var_matrix(3, 3); + EXPECT_TRUE((stan::is_var_matrix::value)); + for (int i = 0; i < 9; ++i) { + EXPECT_EQ(mat_x.val()(i), i); + } + auto mat_x_empty = reader.var_matrix(0, 0); +} + +TEST(IoReader, var_matrix_double) { + using stan::math::var; + using stan::math::var_value; + std::vector theta{0, 1, 2, 3, 4, 5, 6, 7, 8}; + std::vector theta_i; + stan::io::reader reader(theta, theta_i); + auto mat_x = reader.var_matrix(3, 3); + EXPECT_TRUE( + (stan::is_eigen_dense_dynamic::value + && std::is_arithmetic>::value)); + for (int i = 0; i < 9; ++i) { + EXPECT_EQ(mat_x.val()(i), i); + } + auto mat_x_empty = reader.var_matrix(0, 0); +} diff --git a/src/test/unit/io/reader_test.cpp b/src/test/unit/io/reader_test.cpp index 8277deeb653..995f9c0104a 100644 --- a/src/test/unit/io/reader_test.cpp +++ b/src/test/unit/io/reader_test.cpp @@ -107,6 +107,20 @@ TEST(io_reader, scalar_pos_constrain) { EXPECT_FLOAT_EQ(exp(-1.0), reader.scalar_pos_constrain()); EXPECT_FLOAT_EQ(exp(0.0), reader.scalar_pos_constrain()); } +TEST(io_reader, scalar_pos_constrain_falselp) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::reader reader(theta, theta_i); + double lp = -1.2; + EXPECT_FLOAT_EQ(exp(-2.0), reader.scalar_pos_constrain(lp)); + EXPECT_FLOAT_EQ(exp(3.0), reader.scalar_pos_constrain(lp)); + EXPECT_FLOAT_EQ(exp(-1.0), reader.scalar_pos_constrain(lp)); + EXPECT_FLOAT_EQ(exp(0.0), reader.scalar_pos_constrain(lp)); +} TEST(io_reader, scalar_pos_constrain_jacobian) { std::vector theta_i; std::vector theta; From e1e2fd4adce69493be37503a34200fbf94ef68a8 Mon Sep 17 00:00:00 2001 From: Steve Bronder Date: Wed, 10 Feb 2021 21:29:18 -0500 Subject: [PATCH 02/29] Revert "Updates the Math submodule to 711fd70." This reverts commit d1c22b70165fa82f029578c06b4f644d42b4c3bb. --- lib/stan_math | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/stan_math b/lib/stan_math index 711fd707244..e684aa6ec76 160000 --- a/lib/stan_math +++ b/lib/stan_math @@ -1 +1 @@ -Subproject commit 711fd70724411c56e47ac400505186a2d659a4b9 +Subproject commit e684aa6ec761aac129ef05741262dfcc7d9519c3 From 3d8bfa0e43258e6c3b3e76c8ae4a98bd8130338b Mon Sep 17 00:00:00 2001 From: Steve Bronder Date: Wed, 10 Feb 2021 21:29:57 -0500 Subject: [PATCH 03/29] Revert "update reader with template for Jacobian" This reverts commit 414e086974b17fa6b6d5f1d47a523866ca08faa6. --- src/stan/io/reader.hpp | 1041 +++---------------- src/test/unit/io/reader2_test.cpp | 1551 ----------------------------- src/test/unit/io/reader_test.cpp | 14 - 3 files changed, 123 insertions(+), 2483 deletions(-) delete mode 100644 src/test/unit/io/reader2_test.cpp diff --git a/src/stan/io/reader.hpp b/src/stan/io/reader.hpp index dcfc8fd0d2f..05931c61589 100644 --- a/src/stan/io/reader.hpp +++ b/src/stan/io/reader.hpp @@ -34,8 +34,8 @@ namespace io { template class reader { private: - Eigen::Map> data_r_; - Eigen::Map> data_i_; + Eigen::Map> data_r_; + Eigen::Map> data_i_; size_t pos_{0}; size_t int_pos_{0}; @@ -161,7 +161,6 @@ class reader { * log_prob Reference to log probability variable to increment. * @return Next scalar. */ - template inline T scalar_constrain(T & /*log_prob*/) { return scalar(); } /** @@ -227,7 +226,9 @@ class reader { * @return Column vector made up of the next scalars. */ inline auto vector_constrain(size_t m) { - return this->vector(m); + if (m == 0) + return map_vector_t(nullptr, m); + return map_vector_t(&scalar_ptr_increment(m), m); } /** * Return a column vector of specified dimensionality made up of @@ -237,35 +238,10 @@ class reader { * lp Log probability to increment. * @return Column vector made up of the next scalars. */ - template inline auto vector_constrain(size_t m, T & /*lp*/) { - return this->vector(m); - } - - /** - * Return a column vector of specified dimensionality made up of - * the next scalars. The constraint and hence Jacobian are no-ops. - * - * @param m Number of rows in the vector to read. - * lp Log probability to increment. - * @return Column vector made up of the next scalars. - */ - template * = nullptr> - inline auto var_vector_constrain(size_t m, T & /*lp*/) { - return this->vector(m); - } - - /** - * Return a column vector of specified dimensionality made up of - * the next scalars. The constraint and hence Jacobian are no-ops. - * - * @param m Number of rows in the vector to read. - * lp Log probability to increment. - * @return Column vector made up of the next scalars. - */ - template * = nullptr> - inline auto var_vector_constrain(size_t m, T & /*lp*/) { - return this->var_vector(m); + if (m == 0) + return map_vector_t(nullptr, m); + return map_vector_t(&scalar_ptr_increment(m), m); } /** @@ -316,7 +292,9 @@ class reader { * @return Column vector made up of the next scalars. */ inline auto row_vector_constrain(size_t m) { - return this->row_vector(m); + if (m == 0) + return map_row_vector_t(nullptr, m); + return map_row_vector_t(&scalar_ptr_increment(m), m); } /** @@ -328,37 +306,10 @@ class reader { * lp Log probability to increment. * @return Column vector made up of the next scalars. */ - template inline auto row_vector_constrain(size_t m, T & /*lp*/) { - return this->row_vector(m); - } - - /** - * Return a row vector of specified dimensionality made up of - * the next scalars. The constraint is a no-op, so the log - * probability is not incremented. - * - * @param m Number of rows in the vector to read. - * lp Log probability to increment. - * @return Column vector made up of the next scalars. - */ - template * = nullptr> - inline auto var_row_vector_constrain(size_t m, T & /*lp*/) { - return this->var_row_vector(m); - } - - /** - * Return a row vector of specified dimensionality made up of - * the next scalars. The constraint is a no-op, so the log - * probability is not incremented. - * - * @param m Number of rows in the vector to read. - * lp Log probability to increment. - * @return Column vector made up of the next scalars. - */ - template * = nullptr> - inline auto var_row_vector_constrain(size_t m, T & /*lp*/) { - return this->var_row_vector(m); + if (m == 0) + return map_row_vector_t(nullptr, m); + return map_row_vector_t(&scalar_ptr_increment(m), m); } /** @@ -379,11 +330,9 @@ class reader { * @return Eigen::Matrix made up of the next scalars. */ inline auto matrix(size_t m, size_t n) { - if (m == 0 || n == 0) { + if (m == 0 || n == 0) return map_matrix_t(nullptr, m, n); - } else { - return map_matrix_t(&scalar_ptr_increment(m * n), m, n); - } + return map_matrix_t(&scalar_ptr_increment(m * n), m, n); } /** @@ -405,12 +354,10 @@ class reader { */ template * = nullptr> inline var_matrix_t var_matrix(size_t m, size_t n) { - if (m == 0 || n == 0) { + if (m == 0 || n == 0) return var_matrix_t(Eigen::MatrixXd(0, 0)); - } else { - return stan::math::to_var_value( - map_matrix_t(&scalar_ptr_increment(m * n), m, n)); - } + return stan::math::to_var_value( + map_matrix_t(&scalar_ptr_increment(m * n), m, n)); } /** @@ -446,7 +393,9 @@ class reader { * @return Matrix made up of the next scalars. */ inline auto matrix_constrain(size_t m, size_t n) { - return this->matrix(m, n); + if (m == 0 || n == 0) + return map_matrix_t(nullptr, m, n); + return map_matrix_t(&scalar_ptr_increment(m * n), m, n); } /** @@ -461,43 +410,10 @@ class reader { * lp Log probability to increment. * @return Matrix made up of the next scalars. */ - template inline auto matrix_constrain(size_t m, size_t n, T & /*lp*/) { - return this->matrix(m, n); - } - - /** - * Return a matrix of the specified dimensionality made up of - * the next scalars arranged in column-major order. The - * constraint is a no-op, hence the log probability is not - * incremented. See matrix(size_t, size_t) - * for more information. - * - * @param m Number of rows. - * @param n Number of columns. - * lp Log probability to increment. - * @return Matrix made up of the next scalars. - */ - template * = nullptr> - inline auto var_matrix_constrain(size_t m, size_t n, T & /*lp*/) { - return this->matrix(m, n); - } - - /** - * Return a matrix of the specified dimensionality made up of - * the next scalars arranged in column-major order. The - * constraint is a no-op, hence the log probability is not - * incremented. See matrix(size_t, size_t) - * for more information. - * - * @param m Number of rows. - * @param n Number of columns. - * lp Log probability to increment. - * @return Matrix made up of the next scalars. - */ - template * = nullptr> - inline auto var_matrix_constrain(size_t m, size_t n, T & /*lp*/) { - return this->var_matrix(m, n); + if (m == 0 || n == 0) + return map_matrix_t(nullptr, m, n); + return map_matrix_t(&scalar_ptr_increment(m * n), m, n); } /** @@ -536,7 +452,6 @@ class reader { * @throw std::runtime_error If the next integer read is not * greater than or equal to the lower bound. */ - template inline int integer_lb_constrain(int lb, T & /*lp*/) { return integer_lb(lb); } /** @@ -575,7 +490,6 @@ class reader { * @throw std::runtime_error If the next integer read is not * less than or equal to the upper bound. */ - template inline int integer_ub_constrain(int ub, T & /*lp*/) { return integer_ub(ub); } /** @@ -628,7 +542,6 @@ class reader { * @throw std::runtime_error If the next integer read is not * less than or equal to the upper bound. */ - template inline int integer_lub_constrain(int lb, int ub, T & /*lp*/) { return integer_lub(lb, ub); } @@ -669,13 +582,8 @@ class reader { * @param lp Reference to log probability variable to increment. * @return The next scalar transformed to be positive. */ - template inline T scalar_pos_constrain(T &lp) { - if (Jacobian) { - return stan::math::positive_constrain(scalar(), lp); - } else { - return stan::math::positive_constrain(scalar()); - } + return stan::math::positive_constrain(scalar(), lp); } /** @@ -725,13 +633,9 @@ class reader { * @param lb Lower bound on result. * @param lp Reference to log probability variable to increment. */ - template + template inline T scalar_lb_constrain(const TL lb, T &lp) { - if (Jacobian) { - return stan::math::lb_constrain(scalar(), lb, lp); - } else { - return stan::math::lb_constrain(scalar(), lb); - } + return stan::math::lb_constrain(scalar(), lb, lp); } /** @@ -781,13 +685,9 @@ class reader { * @param ub Upper bound on result. * @param lp Reference to log probability variable to increment. */ - template + template inline T scalar_ub_constrain(const TU ub, T &lp) { - if (Jacobian) { - return stan::math::ub_constrain(scalar(), ub, lp); - } else { - return stan::math::ub_constrain(scalar(), ub); - } + return stan::math::ub_constrain(scalar(), ub, lp); } /** @@ -843,13 +743,9 @@ class reader { * @tparam TL Type of lower bound. * @tparam TU Type of upper bound. */ - template + template inline T scalar_lub_constrain(TL lb, TU ub, T &lp) { - if (Jacobian) { - return stan::math::lub_constrain(scalar(), lb, ub, lp); - } else { - return stan::math::lub_constrain(scalar(), lb, ub); - } + return stan::math::lub_constrain(scalar(), lb, ub, lp); } /** @@ -863,7 +759,8 @@ class reader { */ template inline T scalar_offset_multiplier(const TL offset, const TS multiplier) { - return scalar(); + T x(scalar()); + return x; } /** @@ -901,14 +798,10 @@ class reader { * @tparam TL Type of offset. * @tparam TS Type of multiplier. */ - template + template inline T scalar_offset_multiplier_constrain(TL offset, TS multiplier, T &lp) { - if (Jacobian) { - return stan::math::offset_multiplier_constrain(scalar(), offset, multiplier, - lp); - } else { - return stan::math::offset_multiplier_constrain(scalar(), offset, multiplier); - } + return stan::math::offset_multiplier_constrain(scalar(), offset, multiplier, + lp); } /** @@ -946,13 +839,8 @@ class reader { * @param lp Reference to log probability variable to increment. * @return The next scalar transformed to a probability. */ - template inline T prob_constrain(T &lp) { - if (Jacobian) { - return stan::math::prob_constrain(scalar(), lp); - } else { - return stan::math::prob_constrain(scalar()); - } + return stan::math::prob_constrain(scalar(), lp); } /** @@ -994,13 +882,8 @@ class reader { * probability to increment. * @return The next scalar transformed to a correlation. */ - template inline T corr_constrain(T &lp) { - if (Jacobian) { - return stan::math::corr_constrain(scalar(), lp); - } else { - return stan::math::corr_constrain(scalar()); - } + return stan::math::corr_constrain(scalar(), lp); } /** @@ -1025,29 +908,6 @@ class reader { return theta; } - /** - * Return a unit_vector of the specified size made up of the - * next scalars. - * - *

See stan::math::check_unit_vector. - * - * @param k Size of returned unit_vector - * @return unit_vector read from the specified size number of scalars - * @throw std::runtime_error if the next k values is not a unit_vector - * @throw std::invalid_argument if k is zero - */ - inline var_vector_t var_unit_vector(size_t k) { - using stan::math::value_of; - if (k == 0) { - std::string msg = "io::unit_vector: unit vectors cannot be size 0."; - throw std::invalid_argument(msg); - } - var_vector_t theta(var_vector(k)); - stan::math::check_unit_vector("stan::io::unit_vector", "Constrained vector", - value_of(theta)); - return theta; - } - /** * Return the next unit_vector transformed vector of the specified * length. This operation consumes one less than the specified @@ -1082,47 +942,14 @@ class reader { * @return The next unit_vector of the specified size. * @throw std::invalid_argument if k is zero */ - template - inline vector_t unit_vector_constrain(size_t k, T &lp) { - if (k == 0) { - std::string msg - = "io::unit_vector_constrain:" - " unit vectors cannot be size 0."; - throw std::invalid_argument(msg); - } - if (Jacobian) { - return stan::math::unit_vector_constrain(vector(k), lp); - } else { - return stan::math::unit_vector_constrain(vector(k)); - } - } - - /** - * Return the next unit_vector of the specified size (using one fewer - * unconstrained scalars), incrementing the specified reference with the - * log absolute Jacobian determinant. - * - *

See stan::math::unit_vector_constrain(Eigen::Matrix,T&). - * - * @param k Size of unit_vector. - * @param lp Log probability to increment with log absolute - * Jacobian determinant. - * @return The next unit_vector of the specified size. - * @throw std::invalid_argument if k is zero - */ - template - inline var_vector_t var_unit_vector_constrain(size_t k, T &lp) { + inline auto unit_vector_constrain(size_t k, T &lp) { if (k == 0) { std::string msg = "io::unit_vector_constrain:" " unit vectors cannot be size 0."; throw std::invalid_argument(msg); } - if (Jacobian) { - return stan::math::unit_vector_constrain(var_vector(k), lp); - } else { - return stan::math::unit_vector_constrain(var_vector(k)); - } + return stan::math::unit_vector_constrain(vector(k), lp); } /** @@ -1146,28 +973,6 @@ class reader { return theta; } - /** - * Return a simplex of the specified size made up of the - * next scalars. - * - *

See stan::math::check_simplex. - * - * @param k Size of returned simplex. - * @return Simplex read from the specified size number of scalars. - * @throw std::runtime_error if the k values is not a simplex. - * @throw std::invalid_argument if k is zero - */ - inline var_vector_t var_simplex(size_t k) { - using stan::math::value_of; - if (k == 0) { - std::string msg = "io::simplex: simplexes cannot be size 0."; - throw std::invalid_argument(msg); - } - var_vector_t theta(var_vector(k)); - stan::math::check_simplex("stan::io::simplex", "Constrained vector", value_of(theta)); - return theta; - } - /** * Return the next simplex transformed vector of the specified * length. This operation consumes one less than the specified @@ -1200,43 +1005,12 @@ class reader { * @return The next simplex of the specified size. * @throws std::invalid_argument if number of dimensions (`k`) is zero */ - template - inline vector_t simplex_constrain(size_t k, T &lp) { - if (k == 0) { - std::string msg = "io::simplex_constrain: simplexes cannot be size 0."; - throw std::invalid_argument(msg); - } - if (Jacobian) { - return stan::math::simplex_constrain(vector(k - 1), lp); - } else { - return stan::math::simplex_constrain(vector(k - 1)); - } - } - - /** - * Return the next simplex of the specified size (using one fewer - * unconstrained scalars), incrementing the specified reference with the - * log absolute Jacobian determinant. - * - *

See stan::math::simplex_constrain(Eigen::Matrix,T&). - * - * @param k Size of simplex. - * @param lp Log probability to increment with log absolute - * Jacobian determinant. - * @return The next simplex of the specified size. - * @throws std::invalid_argument if number of dimensions (`k`) is zero - */ - template - inline var_vector_t var_simplex_constrain(size_t k, T &lp) { + inline auto simplex_constrain(size_t k, T &lp) { if (k == 0) { std::string msg = "io::simplex_constrain: simplexes cannot be size 0."; throw std::invalid_argument(msg); } - if (Jacobian) { - return stan::math::simplex_constrain(var_vector(k - 1), lp); - } else { - return stan::math::simplex_constrain(var_vector(k - 1)); - } + return stan::math::simplex_constrain(vector(k - 1), lp); } /** @@ -1255,23 +1029,6 @@ class reader { return x; } - /** - * Return the next vector of specified size containing - * values in ascending order. - * - *

See stan::math::check_ordered(T) for - * behavior on failure. - * - * @param k Size of returned vector. - * @return Vector of positive values in ascending order. - */ - inline var_vector_t var_ordered(size_t k) { - using stan::math::value_of; - var_vector_t x(var_vector(k)); - stan::math::check_ordered("stan::io::ordered", "Constrained vector", value_of(x)); - return x; - } - /** * Return the next ordered vector of the specified length. * @@ -1296,33 +1053,8 @@ class reader { * @param lp Log probability reference to increment. * @return Next ordered vector of the specified size. */ - template - inline vector_t ordered_constrain(size_t k, T &lp) { - if (Jacobian) { - return stan::math::ordered_constrain(vector(k), lp); - } else { - return stan::math::ordered_constrain(vector(k)); - } - } - - /** - * Return the next ordered vector of the specified - * size, incrementing the specified reference with the log - * absolute Jacobian of the determinant. - * - *

See stan::math::ordered_constrain(Matrix,T&). - * - * @param k Size of vector. - * @param lp Log probability reference to increment. - * @return Next ordered vector of the specified size. - */ - template - inline var_vector_t var_ordered_constrain(size_t k, T &lp) { - if (Jacobian) { - return stan::math::ordered_constrain(var_vector(k), lp); - } else { - return stan::math::ordered_constrain(var_vector(k)); - } + inline auto ordered_constrain(size_t k, T &lp) { + return stan::math::ordered_constrain(vector(k), lp); } /** @@ -1342,25 +1074,6 @@ class reader { return x; } - /** - * Return the next vector of specified size containing - * positive values in ascending order. - * - *

See stan::math::check_positive_ordered(T) for - * behavior on failure. - * - * @param k Size of returned vector. - * @return Vector of positive values in ascending order. - */ - inline var_vector_t var_positive_ordered(size_t k) { - using stan::math::value_of; - var_vector_t x(var_vector(k)); - stan::math::check_positive_ordered("stan::io::positive_ordered", - "Constrained vector", value_of(x)); - return x; - } - - /** * Return the next positive ordered vector of the specified length. * @@ -1374,20 +1087,6 @@ class reader { return stan::math::positive_ordered_constrain(vector(k)); } - - /** - * Return the next positive ordered vector of the specified length. - * - *

See stan::math::positive_ordered_constrain(Matrix). - * - * @param k Length of returned vector. - * @return Next positive_ordered vector of the specified - * length. - */ - inline auto var_positive_ordered_constrain(size_t k) { - return stan::math::positive_ordered_constrain(var_vector(k)); - } - /** * Return the next positive_ordered vector of the specified * size, incrementing the specified reference with the log @@ -1399,38 +1098,13 @@ class reader { * @param lp Log probability reference to increment. * @return Next positive_ordered vector of the specified size. */ - template - inline vector_t positive_ordered_constrain(size_t k, T &lp) { - if (Jacobian) { - return stan::math::positive_ordered_constrain(vector(k), lp); - } else { - return stan::math::positive_ordered_constrain(vector(k)); - } + inline auto positive_ordered_constrain(size_t k, T &lp) { + return stan::math::positive_ordered_constrain(vector(k), lp); } /** - * Return the next positive_ordered vector of the specified - * size, incrementing the specified reference with the log - * absolute Jacobian of the determinant. - * - *

See stan::math::positive_ordered_constrain(Matrix,T&). - * - * @param k Size of vector. - * @param lp Log probability reference to increment. - * @return Next positive_ordered vector of the specified size. - */ - template - inline var_vector_t var_positive_ordered_constrain(size_t k, T &lp) { - if (Jacobian) { - return stan::math::positive_ordered_constrain(var_vector(k), lp); - } else { - return stan::math::positive_ordered_constrain(var_vector(k)); - } - } - - /** - * Return the next Cholesky factor with the specified - * dimensionality, reading it directly without transforms. + * Return the next Cholesky factor with the specified + * dimensionality, reading it directly without transforms. * * @param M Rows of Cholesky factor * @param N Columns of Cholesky factor @@ -1445,23 +1119,6 @@ class reader { return y; } - /** - * Return the next Cholesky factor with the specified - * dimensionality, reading it directly without transforms. - * - * @param M Rows of Cholesky factor - * @param N Columns of Cholesky factor - * @return Next Cholesky factor. - * @throw std::domain_error if the matrix is not a valid - * Cholesky factor. - */ - inline var_matrix_t var_cholesky_factor_cov(size_t M, size_t N) { - var_matrix_t y(var_matrix(M, N)); - stan::math::check_cholesky_factor("stan::io::cholesky_factor_cov", - "Constrained matrix", value_of(y)); - return y; - } - /** * Return the next Cholesky factor with the specified * dimensionality, reading from an unconstrained vector of the @@ -1491,39 +1148,9 @@ class reader { * @throw std::domain_error if the matrix is not a valid * Cholesky factor. */ - template - inline matrix_t cholesky_factor_cov_constrain(size_t M, size_t N, T &lp) { - if (Jacobian) { - return stan::math::cholesky_factor_constrain( - vector((N * (N + 1)) / 2 + (M - N) * N), M, N, lp); - } else { - return stan::math::cholesky_factor_constrain( - vector((N * (N + 1)) / 2 + (M - N) * N), M, N); - } - } - - /** - * Return the next Cholesky factor with the specified - * dimensionality, reading from an unconstrained vector of the - * appropriate size, and increment the log probability reference - * with the log Jacobian adjustment for the transform. - * - * @param M Rows of Cholesky factor - * @param N Columns of Cholesky factor - * @param[in,out] lp log probability - * @return Next Cholesky factor. - * @throw std::domain_error if the matrix is not a valid - * Cholesky factor. - */ - template - inline var_matrix_t var_cholesky_factor_cov_constrain(size_t M, size_t N, T &lp) { - if (Jacobian) { - return stan::math::cholesky_factor_constrain( - var_vector((N * (N + 1)) / 2 + (M - N) * N), M, N, lp); - } else { - return stan::math::cholesky_factor_constrain( - var_vector((N * (N + 1)) / 2 + (M - N) * N), M, N); - } + inline auto cholesky_factor_cov_constrain(size_t M, size_t N, T &lp) { + return stan::math::cholesky_factor_constrain( + vector((N * (N + 1)) / 2 + (M - N) * N), M, N, lp); } /** @@ -1544,24 +1171,6 @@ class reader { return y; } - /** - * Return the next Cholesky factor for a correlation matrix with - * the specified dimensionality, reading it directly without - * transforms. - * - * @param K Rows and columns of Cholesky factor - * @return Next Cholesky factor for a correlation matrix. - * @throw std::domain_error if the matrix is not a valid - * Cholesky factor for a correlation matrix. - */ - inline var_matrix_t var_cholesky_factor_corr(size_t K) { - using stan::math::check_cholesky_factor_corr; - var_matrix_t y(var_matrix(K, K)); - check_cholesky_factor_corr("stan::io::cholesky_factor_corr", - "Constrained matrix", value_of(y)); - return y; - } - /** * Return the next Cholesky factor for a correlation matrix with * the specified dimensionality, reading from an unconstrained @@ -1576,19 +1185,6 @@ class reader { return stan::math::cholesky_corr_constrain(vector((K * (K - 1)) / 2), K); } - /** - * Return the next Cholesky factor for a correlation matrix with - * the specified dimensionality, reading from an unconstrained - * vector of the appropriate size. - * - * @param K Rows and columns of Cholesky factor. - * @return Next Cholesky factor for a correlation matrix. - * @throw std::domain_error if the matrix is not a valid - * Cholesky factor for a correlation matrix. - */ - inline auto var_cholesky_factor_corr_constrain(size_t K) { - return stan::math::cholesky_corr_constrain(var_vector((K * (K - 1)) / 2), K); - } /** * Return the next Cholesky factor for a correlation matrix with * the specified dimensionality, reading from an unconstrained @@ -1602,39 +1198,9 @@ class reader { * @throw std::domain_error if the matrix is not a valid * Cholesky factor for a correlation matrix. */ - template - inline matrix_t cholesky_factor_corr_constrain(size_t K, T &lp) { - if (Jacobian) { - return stan::math::cholesky_corr_constrain(vector((K * (K - 1)) / 2), K, - lp); - } else { - return stan::math::cholesky_corr_constrain(vector((K * (K - 1)) / 2), K, - lp); - } - } - - /** - * Return the next Cholesky factor for a correlation matrix with - * the specified dimensionality, reading from an unconstrained - * vector of the appropriate size, and increment the log - * probability reference with the log Jacobian adjustment for - * the transform. - * - * @param K Rows and columns of Cholesky factor - * @param lp Log probability reference to increment. - * @return Next Cholesky factor for a correlation matrix. - * @throw std::domain_error if the matrix is not a valid - * Cholesky factor for a correlation matrix. - */ - template - inline var_matrix_t var_cholesky_factor_corr_constrain(size_t K, T &lp) { - if (Jacobian) { - return stan::math::cholesky_corr_constrain(var_vector((K * (K - 1)) / 2), K, - lp); - } else { - return stan::math::cholesky_corr_constrain(var_vector((K * (K - 1)) / 2), K, - lp); - } + inline auto cholesky_factor_corr_constrain(size_t K, T &lp) { + return stan::math::cholesky_corr_constrain(vector((K * (K - 1)) / 2), K, + lp); } /** @@ -1649,10 +1215,9 @@ class reader { * covariance matrix */ inline map_matrix_t cov_matrix(size_t k) { - using stan::math::value_of; map_matrix_t y(matrix(k, k)); stan::math::check_cov_matrix("stan::io::cov_matrix", "Constrained matrix", - value_of(y)); + y); return y; } @@ -1679,35 +1244,9 @@ class reader { * @param lp Log probability reference to increment. * @return The next covariance matrix of the specified dimensionality. */ - template - inline matrix_t cov_matrix_constrain(size_t k, T &lp) { - if (Jacobian) { - return stan::math::cov_matrix_constrain(vector(k + (k * (k - 1)) / 2), k, - lp); - } else { - return stan::math::cov_matrix_constrain(vector(k + (k * (k - 1)) / 2), k); - } - } - - /** - * Return the next covariance matrix of the specified dimensionality, - * incrementing the specified reference with the log absolute Jacobian - * determinant. - * - *

See stan::math::cov_matrix_constrain(Matrix,T&). - * - * @param k Dimensionality of the (square) covariance matrix. - * @param lp Log probability reference to increment. - * @return The next covariance matrix of the specified dimensionality. - */ - template - inline var_matrix_t var_cov_matrix_constrain(size_t k, T &lp) { - if (Jacobian) { - return stan::math::cov_matrix_constrain(var_vector(k + (k * (k - 1)) / 2), k, - lp); - } else { - return stan::math::cov_matrix_constrain(var_vector(k + (k * (k - 1)) / 2), k); - } + inline auto cov_matrix_constrain(size_t k, T &lp) { + return stan::math::cov_matrix_constrain(vector(k + (k * (k - 1)) / 2), k, + lp); } /** @@ -1726,23 +1265,6 @@ class reader { return x; } - /** - * Returns the next correlation matrix of the specified dimensionality. - * - *

See stan::math::check_corr_matrix(Matrix). - * - * @param k Dimensionality of correlation matrix. - * @return Next correlation matrix of the specified dimensionality. - * @throw std::runtime_error if the matrix is not a correlation matrix - */ - inline var_matrix_t var_corr_matrix(size_t k) { - using stan::math::value_of; - var_matrix_t x(var_matrix(k, k)); - stan::math::check_corr_matrix("stan::math::corr_matrix", - "Constrained matrix", value_of(x)); - return x; - } - /** * Return the next correlation matrix of the specified dimensionality. * @@ -1755,38 +1277,6 @@ class reader { return stan::math::corr_matrix_constrain(vector((k * (k - 1)) / 2), k); } - /** - * Return the next correlation matrix of the specified dimensionality. - * - *

See stan::math::corr_matrix_constrain(Matrix). - * - * @param k Dimensionality of correlation matrix. - * @return Next correlation matrix of the specified dimensionality. - */ - inline auto var_corr_matrix_constrain(size_t k) { - return stan::math::corr_matrix_constrain(var_vector((k * (k - 1)) / 2), k); - } - - /** - * Return the next correlation matrix of the specified dimensionality, - * incrementing the specified reference with the log absolute Jacobian - * determinant. - * - *

See stan::math::corr_matrix_constrain(Matrix,T&). - * - * @param k Dimensionality of the (square) correlation matrix. - * @param lp Log probability reference to increment. - * @return The next correlation matrix of the specified dimensionality. - */ - template - inline matrix_t corr_matrix_constrain(size_t k, T &lp) { - if (Jacobian) { - return stan::math::corr_matrix_constrain(vector((k * (k - 1)) / 2), k, lp); - } else { - return stan::math::corr_matrix_constrain(vector((k * (k - 1)) / 2), k); - } - } - /** * Return the next correlation matrix of the specified dimensionality, * incrementing the specified reference with the log absolute Jacobian @@ -1798,13 +1288,8 @@ class reader { * @param lp Log probability reference to increment. * @return The next correlation matrix of the specified dimensionality. */ - template - inline var_matrix_t var_corr_matrix_constrain(size_t k, T &lp) { - if (Jacobian) { - return stan::math::corr_matrix_constrain(var_vector((k * (k - 1)) / 2), k, lp); - } else { - return stan::math::corr_matrix_constrain(var_vector((k * (k - 1)) / 2), k); - } + inline auto corr_matrix_constrain(size_t k, T &lp) { + return stan::math::corr_matrix_constrain(vector((k * (k - 1)) / 2), k, lp); } template @@ -1815,41 +1300,14 @@ class reader { return v; } - template - inline var_vector_t vector_lb(const TL lb, size_t m) { - using stan::math::value_of; - var_vector_t v(var_vector(m)); - stan::math::check_greater_or_equal("stan::io::vector_lb", - "Constrained vector", value_of(v), lb); - return v; - } - template inline auto vector_lb_constrain(const TL lb, size_t m) { return stan::math::lb_constrain(vector(m), lb); } template - inline auto var_vector_lb_constrain(const TL lb, size_t m) { - return stan::math::lb_constrain(var_vector(m), lb); - } - - template - inline vector_t vector_lb_constrain(const TL lb, size_t m, T &lp) { - if (Jacobian) { - return stan::math::lb_constrain(vector(m), lb, lp); - } else { - return stan::math::lb_constrain(vector(m), lb); - } - } - - template - inline var_vector_t var_vector_lb_constrain(const TL lb, size_t m, T &lp) { - if (Jacobian) { - return stan::math::lb_constrain(var_vector(m), lb, lp); - } else { - return stan::math::lb_constrain(var_vector(m), lb); - } + inline auto vector_lb_constrain(const TL lb, size_t m, T &lp) { + return stan::math::lb_constrain(vector(m), lb, lp); } template @@ -1860,41 +1318,14 @@ class reader { return v; } - template - inline var_row_vector_t var_row_vector_lb(const TL lb, size_t m) { - using stan::math::value_of; - var_row_vector_t v(var_row_vector(m)); - stan::math::check_greater_or_equal("stan::io::row_vector_lb", - "Constrained row vector", value_of(v), lb); - return v; - } - template inline auto row_vector_lb_constrain(const TL lb, size_t m) { return stan::math::lb_constrain(row_vector(m), lb); } template - inline auto var_row_vector_lb_constrain(const TL lb, size_t m) { - return stan::math::lb_constrain(var_row_vector(m), lb); - } - - template - inline row_vector_t row_vector_lb_constrain(const TL lb, size_t m, T &lp) { - if (Jacobian) { - return stan::math::lb_constrain(row_vector(m), lb, lp); - } else { - return stan::math::lb_constrain(row_vector(m), lb); - } - } - - template - inline var_row_vector_t var_row_vector_lb_constrain(const TL lb, size_t m, T &lp) { - if (Jacobian) { - return stan::math::lb_constrain(var_row_vector(m), lb, lp); - } else { - return stan::math::lb_constrain(var_row_vector(m), lb); - } + inline auto row_vector_lb_constrain(const TL lb, size_t m, T &lp) { + return stan::math::lb_constrain(row_vector(m), lb, lp); } template @@ -1905,41 +1336,19 @@ class reader { return mat; } - template - inline var_matrix_t var_matrix_lb(const TL lb, const size_t m, size_t n) { - using stan::math::value_of; - var_matrix_t mat(var_matrix(m, n)); - stan::math::check_greater_or_equal("stan::io::matrix_lb", - "Constrained matrix", value_of(mat), lb); - return mat; - } - template inline auto matrix_lb_constrain(const TL lb, size_t m, size_t n) { - return stan::math::lb_constrain(matrix(m, n), lb); + return matrix(m, n) + .unaryExpr([&](auto &&x) { return stan::math::lb_constrain(x, lb); }) + .eval(); } template - inline auto var_matrix_lb_constrain(const TL lb, size_t m, size_t n) { - return stan::math::lb_constrain(var_matrix(m, n), lb); - } - - template - inline matrix_t matrix_lb_constrain(const TL lb, size_t m, size_t n, T &lp) { - if (Jacobian) { - return stan::math::lb_constrain(matrix(m, n), lb, lp).eval(); - } else { - return stan::math::lb_constrain(matrix(m, n), lb).eval(); - } - } - - template - inline var_matrix_t var_matrix_lb_constrain(const TL lb, size_t m, size_t n, T &lp) { - if (Jacobian) { - return stan::math::lb_constrain(var_matrix(m, n), lb, lp).eval(); - } else { - return stan::math::lb_constrain(var_matrix(m, n), lb).eval(); - } + inline auto matrix_lb_constrain(const TL lb, size_t m, size_t n, T &lp) { + return matrix(m, n) + .unaryExpr( + [&](auto &&x) { return stan::math::lb_constrain(x, lb, lp); }) + .eval(); } template @@ -1950,41 +1359,14 @@ class reader { return v; } - template - inline var_vector_t var_vector_ub(const TU ub, size_t m) { - using stan::math::value_of; - var_vector_t v(vector(m)); - stan::math::check_less_or_equal("stan::io::vector_ub", "Constrained vector", - value_of(v), ub); - return v; - } - template inline auto vector_ub_constrain(const TU ub, size_t m) { return stan::math::ub_constrain(vector(m), ub); } template - inline auto var_vector_ub_constrain(const TU ub, size_t m) { - return stan::math::ub_constrain(var_vector(m), ub); - } - - template - inline vector_t vector_ub_constrain(const TU ub, size_t m, T &lp) { - if (Jacobian) { - return stan::math::ub_constrain(vector(m), ub, lp); - } else { - return stan::math::ub_constrain(vector(m), ub); - } - } - - template - inline var_vector_t var_vector_ub_constrain(const TU ub, size_t m, T &lp) { - if (Jacobian) { - return stan::math::ub_constrain(var_vector(m), ub, lp); - } else { - return stan::math::ub_constrain(var_vector(m), ub); - } + inline auto vector_ub_constrain(const TU ub, size_t m, T &lp) { + return stan::math::ub_constrain(vector(m), ub, lp); } template @@ -1995,41 +1377,14 @@ class reader { return v; } - template - inline var_row_vector_t var_row_vector_ub(const TU ub, size_t m) { - using stan::math::value_of; - var_row_vector_t v(var_row_vector(m)); - stan::math::check_less_or_equal("stan::io::row_vector_ub", - "Constrained row vector", value_of(v), ub); - return v; - } - template inline auto row_vector_ub_constrain(const TU ub, size_t m) { return stan::math::ub_constrain(row_vector(m), ub); } template - inline auto var_row_vector_ub_constrain(const TU ub, size_t m) { - return stan::math::ub_constrain(var_row_vector(m), ub); - } - - template - inline row_vector_t row_vector_ub_constrain(const TU ub, size_t m, T &lp) { - if (Jacobian) { - return stan::math::ub_constrain(row_vector(m), ub, lp); - } else { - return stan::math::ub_constrain(row_vector(m), ub); - } - } - - template - inline var_row_vector_t var_row_vector_ub_constrain(const TU ub, size_t m, T &lp) { - if (Jacobian) { - return stan::math::ub_constrain(var_row_vector(m), ub, lp); - } else { - return stan::math::ub_constrain(var_row_vector(m), ub); - } + inline auto row_vector_ub_constrain(const TU ub, size_t m, T &lp) { + return stan::math::ub_constrain(row_vector(m), ub, lp); } template @@ -2040,43 +1395,20 @@ class reader { return mat; } - template - inline var_matrix_t var_matrix_ub(const TU ub, size_t m, size_t n) { - using stan::math::value_of; - var_matrix_t mat(var_matrix(m, n)); - stan::math::check_less_or_equal("stan::io::matrix_ub", "Constrained matrix", - value_of(mat), ub); - return mat; - } - template inline auto matrix_ub_constrain(const TU ub, const size_t m, size_t n) { - return stan::math::ub_constrain(matrix(m, n), ub); + return matrix(m, n) + .unaryExpr([&](auto &&x) { return stan::math::ub_constrain(x, ub); }) + .eval(); } template - inline auto var_matrix_ub_constrain(const TU ub, const size_t m, size_t n) { - return stan::math::ub_constrain(var_matrix(m, n), ub); - } - - template - inline matrix_t matrix_ub_constrain(const TU ub, const size_t m, size_t n, + inline auto matrix_ub_constrain(const TU ub, const size_t m, size_t n, T &lp) { - if (Jacobian) { - return stan::math::ub_constrain(matrix(m, n), ub, lp); - } else { - return stan::math::ub_constrain(matrix(m, n), ub); - } - } - - template - inline var_matrix_t var_matrix_ub_constrain(const TU ub, const size_t m, size_t n, - T &lp) { - if (Jacobian) { - return stan::math::ub_constrain(var_matrix(m, n), ub, lp); - } else { - return stan::math::ub_constrain(var_matrix(m, n), ub); - } + return matrix(m, n) + .unaryExpr( + [&](auto &&x) { return stan::math::ub_constrain(x, ub, lp); }) + .eval(); } template @@ -2087,41 +1419,14 @@ class reader { return v; } - template - inline var_vector_t var_vector_lub(const TL lb, const TU ub, size_t m) { - using stan::math::value_of; - var_vector_t v(var_vector(m)); - stan::math::check_bounded( - "stan::io::vector_lub", "Constrained vector", value_of(v), lb, ub); - return v; - } - template inline auto vector_lub_constrain(const TL lb, const TU ub, size_t m) { return stan::math::lub_constrain(vector(m), lb, ub); } template - inline auto var_vector_lub_constrain(const TL lb, const TU ub, size_t m) { - return stan::math::lub_constrain(var_vector(m), lb, ub); - } - - template - inline vector_t vector_lub_constrain(const TL lb, const TU ub, size_t m, T &lp) { - if (Jacobian) { - return stan::math::lub_constrain(vector(m), lb, ub, lp); - } else { - return stan::math::lub_constrain(vector(m), lb, ub); - } - } - - template - inline var_vector_t var_vector_lub_constrain(const TL lb, const TU ub, size_t m, T &lp) { - if (Jacobian) { - return stan::math::lub_constrain(var_vector(m), lb, ub, lp); - } else { - return stan::math::lub_constrain(var_vector(m), lb, ub); - } + inline auto vector_lub_constrain(const TL lb, const TU ub, size_t m, T &lp) { + return stan::math::lub_constrain(vector(m), lb, ub, lp); } template @@ -2131,16 +1436,6 @@ class reader { "stan::io::row_vector_lub", "Constrained row vector", v, lb, ub); return v; } - - template - inline var_row_vector_t var_row_vector_lub(const TL lb, const TU ub, size_t m) { - using stan::math::value_of; - var_row_vector_t v(var_row_vector(m)); - stan::math::check_bounded( - "stan::io::row_vector_lub", "Constrained row vector", value_of(v), lb, ub); - return v; - } - template inline row_vector_t row_vector_lub_constrain(const TL lb, const TU ub, size_t m) { @@ -2148,71 +1443,35 @@ class reader { } template - inline var_row_vector_t var_row_vector_lub_constrain(const TL lb, const TU ub, - size_t m) { - return stan::math::lub_constrain(var_row_vector(m), lb, ub); - } - - template inline row_vector_t row_vector_lub_constrain(const TL lb, const TU ub, size_t m, T &lp) { - if (Jacobian) { - return stan::math::lub_constrain(row_vector(m), lb, ub, lp); - } else { - return stan::math::lub_constrain(row_vector(m), lb, ub); - } - } - - template - inline var_row_vector_t var_row_vector_lub_constrain(const TL lb, const TU ub, - size_t m, T &lp) { - if (Jacobian) { - return stan::math::lub_constrain(var_row_vector(m), lb, ub, lp); - } else { - return stan::math::lub_constrain(var_row_vector(m), lb, ub); - } + return stan::math::lub_constrain(row_vector(m), lb, ub, lp); } template inline map_matrix_t matrix_lub(const TL lb, const TU ub, size_t m, size_t n) { - using stan::math::value_of; map_matrix_t mat(matrix(m, n)); stan::math::check_bounded( - "stan::io::row_vector_lub", "Constrained row vector", value_of(mat), lb, ub); - return mat; - } - - template - inline var_matrix_t var_matrix_lub(const TL lb, const TU ub, size_t m, size_t n) { - using stan::math::value_of; - var_matrix_t mat(var_matrix(m, n)); - stan::math::check_bounded( - "stan::io::row_vector_lub", "Constrained row vector", value_of(mat), lb, ub); + "stan::io::row_vector_lub", "Constrained row vector", mat, lb, ub); return mat; } template inline auto matrix_lub_constrain(const TL lb, const TU ub, size_t m, size_t n) { - return stan::math::lub_constrain(matrix(m, n), lb, ub); + return matrix(m, n) + .unaryExpr( + [&](auto &&x) { return stan::math::lub_constrain(x, lb, ub); }) + .eval(); } template - inline auto var_matrix_lub_constrain(const TL lb, const TU ub, size_t m, - size_t n) { - return stan::math::lub_constrain(var_matrix(m, n), lb, ub); - } - - template inline auto matrix_lub_constrain(const TL lb, const TU ub, size_t m, size_t n, T &lp) { - return stan::math::lub_constrain(matrix(m, n), lb, ub, lp); - } - - template - inline auto var_matrix_lub_constrain(const TL lb, const TU ub, size_t m, size_t n, - T &lp) { - return stan::math::lub_constrain(var_matrix(m, n), lb, ub, lp); + return matrix(m, n) + .unaryExpr( + [&](auto &&x) { return stan::math::lub_constrain(x, lb, ub, lp); }) + .eval(); } template @@ -2221,12 +1480,6 @@ class reader { return vector(m); } - template - inline auto var_vector_offset_multiplier(const TL offset, - const TS multiplier, size_t m) { - return var_vector(m); - } - template inline auto vector_offset_multiplier_constrain(const TL offset, const TS multiplier, @@ -2236,33 +1489,11 @@ class reader { } template - inline auto var_vector_offset_multiplier_constrain(const TL offset, - const TS multiplier, - size_t m) { - return stan::math::offset_multiplier_constrain(var_vector(m), offset, - multiplier); - } - - template - inline vector_t vector_offset_multiplier_constrain(const TL offset, - const TS multiplier, size_t m, - T &lp) { - if (Jacobian) { - return stan::math::offset_multiplier_constrain(vector(m), offset, multiplier, lp); - } else { - return stan::math::offset_multiplier_constrain(vector(m), offset, multiplier); - } - } - - template - inline var_vector_t var_vector_offset_multiplier_constrain(const TL offset, + inline auto vector_offset_multiplier_constrain(const TL offset, const TS multiplier, size_t m, T &lp) { - if (Jacobian) { - return stan::math::offset_multiplier_constrain(var_vector(m), offset, multiplier, lp); - } else { - return stan::math::offset_multiplier_constrain(var_vector(m), offset, multiplier); - } + return stan::math::offset_multiplier_constrain(vector(m), offset, + multiplier, lp); } template @@ -2273,68 +1504,42 @@ class reader { } template - inline var_row_vector_t var_row_vector_offset_multiplier(const TL offset, - const TS multiplier, - size_t m) { - return var_row_vector(m); - } - - template - inline auto row_vector_offset_multiplier_constrain(const TL offset, const TS multiplier, size_t m) { - return stan::math::offset_multiplier_constrain(row_vector(m), offset, multiplier); + inline auto row_vector_offset_multiplier_constrain(const TL offset, + const TS multiplier, + size_t m) { + return stan::math::offset_multiplier_constrain(row_vector(m), offset, + multiplier); } template - inline auto var_row_vector_offset_multiplier_constrain(const TL offset, const TS multiplier, size_t m) { - return stan::math::offset_multiplier_constrain(var_row_vector(m), offset, multiplier); - } - - template - inline row_vector_t row_vector_offset_multiplier_constrain(const TL offset, const TS multiplier, size_t m, T &lp) { - return stan::math::offset_multiplier_constrain(row_vector(m), offset, multiplier, lp); - } - - template - inline var_row_vector_t var_row_vector_offset_multiplier_constrain(const TL offset, const TS multiplier, size_t m, T &lp) { - return stan::math::offset_multiplier_constrain(var_row_vector(m), offset, multiplier, lp); + inline auto row_vector_offset_multiplier_constrain(const TL offset, + const TS multiplier, + size_t m, T &lp) { + return stan::math::offset_multiplier_constrain(row_vector(m), offset, + multiplier, lp); } template - inline map_matrix_t matrix_offset_multiplier(const TL offset, const TS multiplier, size_t m, size_t n) { + inline map_matrix_t matrix_offset_multiplier(const TL offset, + const TS multiplier, size_t m, + size_t n) { return matrix(m, n); } template - inline var_matrix_t var_matrix_offset_multiplier(const TL offset, const TS multiplier, size_t m, size_t n) { - return var_matrix(m, n); - } - - template - inline auto matrix_offset_multiplier_constrain(const TL offset, const TS multiplier, size_t m, size_t n) { - return stan::math::offset_multiplier_constrain(matrix(m, n), offset, multiplier); + inline auto matrix_offset_multiplier_constrain(const TL offset, + const TS multiplier, size_t m, + size_t n) { + return stan::math::offset_multiplier_constrain(matrix(m, n), offset, + multiplier); } template - inline auto var_matrix_offset_multiplier_constrain(const TL offset, const TS multiplier, size_t m, size_t n) { - return stan::math::offset_multiplier_constrain(var_matrix(m, n), offset, multiplier); - } - - template - inline matrix_t matrix_offset_multiplier_constrain(const TL offset, const TS multiplier, size_t m, size_t n, T &lp) { - if (Jacobian) { - return stan::math::offset_multiplier_constrain(matrix(m, n), offset, multiplier, lp); - } else { - return stan::math::offset_multiplier_constrain(matrix(m, n), offset, multiplier); - } - } - - template - inline var_matrix_t var_matrix_offset_multiplier_constrain(const TL offset, const TS multiplier, size_t m, size_t n, T &lp) { - if (Jacobian) { - return stan::math::offset_multiplier_constrain(var_matrix(m, n), offset, multiplier, lp); - } else { - return stan::math::offset_multiplier_constrain(var_matrix(m, n), offset, multiplier); - } + inline auto matrix_offset_multiplier_constrain(const TL offset, + const TS multiplier, size_t m, + size_t n, T &lp) { + return stan::math::offset_multiplier_constrain(matrix(m, n), offset, + multiplier, lp); } }; diff --git a/src/test/unit/io/reader2_test.cpp b/src/test/unit/io/reader2_test.cpp deleted file mode 100644 index 995f9c0104a..00000000000 --- a/src/test/unit/io/reader2_test.cpp +++ /dev/null @@ -1,1551 +0,0 @@ -#include -#include - -TEST(io_reader, eigen_input) { - Eigen::Matrix theta_i(1); - Eigen::VectorXd theta(2); - theta[0] = 1.0; - theta[1] = 2.0; - theta_i[0] = 1; - stan::io::reader reader(theta, theta_i); - double x = reader.scalar(); - EXPECT_FLOAT_EQ(1.0, x); - double y = reader.scalar(); - EXPECT_FLOAT_EQ(2.0, y); - int z = reader.integer(); - EXPECT_EQ(1, z); - EXPECT_EQ(0U, reader.available()); -} - -TEST(io_reader, zeroSizeVecs) { - std::vector theta_i; - std::vector theta; - theta.push_back(1.0); - stan::io::reader reader(theta, theta_i); - - EXPECT_FLOAT_EQ(1.0, reader.scalar()); // finish available - - // these all fail in 2.6.3 - EXPECT_EQ(0, reader.std_vector(0).size()); - EXPECT_EQ(0, reader.vector(0).size()); - EXPECT_EQ(0, reader.row_vector(0).size()); - EXPECT_EQ(0, reader.matrix(0, 3).size()); - EXPECT_EQ(0, reader.matrix(3, 0).size()); -} - -TEST(io_reader, scalar) { - std::vector theta_i; - std::vector theta; - theta.push_back(1.0); - theta.push_back(2.0); - stan::io::reader reader(theta, theta_i); - double x = reader.scalar(); - EXPECT_FLOAT_EQ(1.0, x); - double y = reader.scalar(); - EXPECT_FLOAT_EQ(2.0, y); - EXPECT_EQ(0U, reader.available()); -} -TEST(io_reader, scalar_constrain) { - std::vector theta_i; - std::vector theta; - theta.push_back(1.0); - theta.push_back(2.0); - stan::io::reader reader(theta, theta_i); - double x = reader.scalar_constrain(); - EXPECT_FLOAT_EQ(1.0, x); - double y = reader.scalar_constrain(); - EXPECT_FLOAT_EQ(2.0, y); - EXPECT_EQ(0U, reader.available()); -} -TEST(io_reader, scalar_constrain_jacobian) { - std::vector theta_i; - std::vector theta; - theta.push_back(1.0); - theta.push_back(2.0); - stan::io::reader reader(theta, theta_i); - double lp = -1.2; - double x = reader.scalar_constrain(lp); - EXPECT_FLOAT_EQ(1.0, x); - EXPECT_FLOAT_EQ(-1.2, lp); - double y = reader.scalar_constrain(lp); - EXPECT_FLOAT_EQ(2.0, y); - EXPECT_FLOAT_EQ(-1.2, lp); - EXPECT_EQ(0U, reader.available()); -} - -TEST(io_reader, scalar_pos) { - std::vector theta_i; - std::vector theta; - theta.push_back(1.0); - theta.push_back(2.0); - stan::io::reader reader(theta, theta_i); - double x = reader.scalar_pos(); - EXPECT_FLOAT_EQ(1.0, x); - double y = reader.scalar_pos(); - EXPECT_FLOAT_EQ(2.0, y); - EXPECT_EQ(0U, reader.available()); -} -TEST(io_reader, scalar_pos_exception) { - std::vector theta_i; - std::vector theta; - theta.push_back(1.0); - theta.push_back(-1.0); - stan::io::reader reader(theta, theta_i); - EXPECT_NO_THROW(reader.scalar_pos()); - EXPECT_THROW(reader.scalar_pos(), std::domain_error); -} -TEST(io_reader, scalar_pos_constrain) { - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(0.0); - stan::io::reader reader(theta, theta_i); - EXPECT_FLOAT_EQ(exp(-2.0), reader.scalar_pos_constrain()); - EXPECT_FLOAT_EQ(exp(3.0), reader.scalar_pos_constrain()); - EXPECT_FLOAT_EQ(exp(-1.0), reader.scalar_pos_constrain()); - EXPECT_FLOAT_EQ(exp(0.0), reader.scalar_pos_constrain()); -} -TEST(io_reader, scalar_pos_constrain_falselp) { - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(0.0); - stan::io::reader reader(theta, theta_i); - double lp = -1.2; - EXPECT_FLOAT_EQ(exp(-2.0), reader.scalar_pos_constrain(lp)); - EXPECT_FLOAT_EQ(exp(3.0), reader.scalar_pos_constrain(lp)); - EXPECT_FLOAT_EQ(exp(-1.0), reader.scalar_pos_constrain(lp)); - EXPECT_FLOAT_EQ(exp(0.0), reader.scalar_pos_constrain(lp)); -} -TEST(io_reader, scalar_pos_constrain_jacobian) { - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(0.0); - stan::io::reader reader(theta, theta_i); - double lp = -1.2; - EXPECT_FLOAT_EQ(exp(-2.0), reader.scalar_pos_constrain(lp)); - EXPECT_FLOAT_EQ(exp(3.0), reader.scalar_pos_constrain(lp)); - EXPECT_FLOAT_EQ(exp(-1.0), reader.scalar_pos_constrain(lp)); - EXPECT_FLOAT_EQ(exp(0.0), reader.scalar_pos_constrain(lp)); - EXPECT_FLOAT_EQ(-1.2 + -2.0 + 3.0 - 1.0, lp); -} - -TEST(io_reader, scalar_lb) { - std::vector theta_i; - std::vector theta; - theta.push_back(-1.0); - theta.push_back(2.0); - stan::io::reader reader(theta, theta_i); - double x = reader.scalar_lb(-2.0); - EXPECT_FLOAT_EQ(-1.0, x); - double y = reader.scalar_lb(1.0); - EXPECT_FLOAT_EQ(2.0, y); - EXPECT_EQ(0U, reader.available()); -} -TEST(io_reader, scalar_lb_exception) { - std::vector theta_i; - std::vector theta; - theta.push_back(-1.0); - theta.push_back(2.0); - stan::io::reader reader(theta, theta_i); - EXPECT_NO_THROW(reader.scalar_lb(-1.0)); - EXPECT_THROW(reader.scalar_lb(3.0), std::domain_error); -} -TEST(io_reader, scalar_lb_constrain) { - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(0.0); - stan::io::reader reader(theta, theta_i); - EXPECT_FLOAT_EQ(1.0 + exp(-2.0), reader.scalar_lb_constrain(1.0)); - EXPECT_FLOAT_EQ(5.0 + exp(3.0), reader.scalar_lb_constrain(5.0)); - EXPECT_FLOAT_EQ(-2.0 + exp(-1.0), reader.scalar_lb_constrain(-2.0)); - EXPECT_FLOAT_EQ(15.0 + exp(0.0), reader.scalar_lb_constrain(15.0)); -} -TEST(io_reader, scalar_lb_constrain_jacobian) { - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(0.0); - stan::io::reader reader(theta, theta_i); - double lp = -1.5; - EXPECT_FLOAT_EQ(1.0 + exp(-2.0), reader.scalar_lb_constrain(1.0, lp)); - EXPECT_FLOAT_EQ(5.0 + exp(3.0), reader.scalar_lb_constrain(5.0, lp)); - EXPECT_FLOAT_EQ(-2.0 + exp(-1.0), reader.scalar_lb_constrain(-2.0, lp)); - EXPECT_FLOAT_EQ(15.0 + exp(0.0), reader.scalar_lb_constrain(15.0, lp)); - EXPECT_FLOAT_EQ(-1.5 - 2.0 + 3.0 - 1.0, lp); -} - -TEST(io_reader, scalar_ub) { - std::vector theta_i; - std::vector theta; - theta.push_back(-1.0); - theta.push_back(2.0); - stan::io::reader reader(theta, theta_i); - double x = reader.scalar_ub(-0.5); - EXPECT_FLOAT_EQ(-1.0, x); - double y = reader.scalar_ub(5.0); - EXPECT_FLOAT_EQ(2.0, y); - - EXPECT_EQ(0U, reader.available()); -} -TEST(io_reader, scalar_ub_exception) { - std::vector theta_i; - std::vector theta; - theta.push_back(-1.0); - theta.push_back(2.0); - stan::io::reader reader(theta, theta_i); - EXPECT_NO_THROW(reader.scalar_ub(-1.0)); - EXPECT_THROW(reader.scalar_ub(1.0), std::domain_error); -} -TEST(io_reader, scalar_ub_constrain) { - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(0.0); - stan::io::reader reader(theta, theta_i); - EXPECT_FLOAT_EQ(1.0 - exp(-2.0), reader.scalar_ub_constrain(1.0)); - EXPECT_FLOAT_EQ(5.0 - exp(3.0), reader.scalar_ub_constrain(5.0)); - EXPECT_FLOAT_EQ(-2.0 - exp(-1.0), reader.scalar_ub_constrain(-2.0)); - EXPECT_FLOAT_EQ(15.0 - exp(0.0), reader.scalar_ub_constrain(15.0)); -} -TEST(io_reader, scalar_ub_constrain_jacobian) { - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(0.0); - stan::io::reader reader(theta, theta_i); - double lp = -12.9; - EXPECT_FLOAT_EQ(1.0 - exp(-2.0), reader.scalar_ub_constrain(1.0, lp)); - EXPECT_FLOAT_EQ(5.0 - exp(3.0), reader.scalar_ub_constrain(5.0, lp)); - EXPECT_FLOAT_EQ(-2.0 - exp(-1.0), reader.scalar_ub_constrain(-2.0, lp)); - EXPECT_FLOAT_EQ(15.0 - exp(0.0), reader.scalar_ub_constrain(15.0, lp)); - EXPECT_FLOAT_EQ(-12.9 - 2.0 + 3.0 - 1.0, lp); -} - -TEST(io_reader, scalar_lub) { - std::vector theta_i; - std::vector theta; - theta.push_back(-1.0); - theta.push_back(2.0); - stan::io::reader reader(theta, theta_i); - double x = reader.scalar_lub(-3.0, 3.0); - EXPECT_FLOAT_EQ(-1.0, x); - double y = reader.scalar_lub(-3.0, 3.0); - EXPECT_FLOAT_EQ(2.0, y); - - EXPECT_EQ(0U, reader.available()); -} -TEST(io_reader, scalar_lub_exception) { - std::vector theta_i; - std::vector theta; - theta.push_back(-1.0); - theta.push_back(2.0); - stan::io::reader reader(theta, theta_i); - EXPECT_NO_THROW(reader.scalar_lub(-2.0, 2.0)); - EXPECT_THROW(reader.scalar_lub(-1.0, 1.0), std::domain_error); -} -const double inv_logit_m2 = 0.1192029; // stan::math::inv_logit(-2.0) -const double inv_logit_m1 = 0.2689414; // stan::math::inv_logit(-1.0) -const double inv_logit_0 = 0.5; // stan::math::inv_logit(0) -const double inv_logit_3 = 0.9525741; // stan::math::inv_logit(3.0) - -TEST(io_reader, scalar_lub_constrain) { - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(0.0); - stan::io::reader reader(theta, theta_i); - EXPECT_FLOAT_EQ(inv_logit_m2, reader.scalar_lub_constrain(0.0, 1.0)); - EXPECT_FLOAT_EQ(3.0 + 2.0 * inv_logit_3, - reader.scalar_lub_constrain(3.0, 5.0)); - EXPECT_FLOAT_EQ(-3.0 + 5.0 * inv_logit_m1, - reader.scalar_lub_constrain(-3.0, 2.0)); - EXPECT_FLOAT_EQ(-15.0 + 30.0 * inv_logit_0, - reader.scalar_lub_constrain(-15.0, 15.0)); -} -TEST(io_reader, scalar_lub_constrain_jacobian) { - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(0.0); - stan::io::reader reader(theta, theta_i); - double lp = -7.2; - EXPECT_FLOAT_EQ(0.0 + 1.0 * inv_logit_m2, - reader.scalar_lub_constrain(0.0, 1.0, lp)); - EXPECT_FLOAT_EQ(3.0 + 2.0 * inv_logit_3, - reader.scalar_lub_constrain(3.0, 5.0, lp)); - EXPECT_FLOAT_EQ(-3.0 + 5.0 * inv_logit_m1, - reader.scalar_lub_constrain(-3.0, 2.0, lp)); - EXPECT_FLOAT_EQ(-15.0 + 30.0 * inv_logit_0, - reader.scalar_lub_constrain(-15.0, 15.0, lp)); - double expected_lp = -7.2 - + log((1.0 - 0.0) * inv_logit_m2 * (1 - inv_logit_m2)) - + log((5.0 - 3.0) * inv_logit_3 * (1 - inv_logit_3)) - + log((2.0 - -3.0) * inv_logit_m1 * (1 - inv_logit_m1)) - + log((15.0 - -15.0) * inv_logit_0 * (1 - inv_logit_0)); - EXPECT_FLOAT_EQ(expected_lp, lp); -} - -TEST(io_reader, scalar_offset_multiplier) { - std::vector theta_i; - std::vector theta; - theta.push_back(-1.0); - theta.push_back(2.0); - stan::io::reader reader(theta, theta_i); - double x = reader.scalar_offset_multiplier(-3.0, 3.0); - EXPECT_FLOAT_EQ(-1.0, x); - double y = reader.scalar_offset_multiplier(-3.0, 3.0); - EXPECT_FLOAT_EQ(2.0, y); - - EXPECT_EQ(0U, reader.available()); -} -TEST(io_reader, scalar_offset_multiplier_exception) { - std::vector theta_i; - std::vector theta; - theta.push_back(-1.0); - theta.push_back(2.0); - stan::io::reader reader(theta, theta_i); - EXPECT_NO_THROW(reader.scalar_offset_multiplier(-2.0, -2.0)); - EXPECT_THROW(reader.scalar_offset_multiplier_constrain(-2.0, -2.0), - std::domain_error); -} - -TEST(io_reader, scalar_offset_multiplier_constrain) { - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(0.0); - stan::io::reader reader(theta, theta_i); - EXPECT_FLOAT_EQ(-2.0, reader.scalar_offset_multiplier_constrain(0.0, 1.0)); - EXPECT_FLOAT_EQ(3.0 + 5.0 * 3.0, - reader.scalar_offset_multiplier_constrain(3.0, 5.0)); - EXPECT_FLOAT_EQ(-3.0 + 2.0 * -1.0, - reader.scalar_offset_multiplier_constrain(-3.0, 2.0)); - EXPECT_FLOAT_EQ(-15.0, - reader.scalar_offset_multiplier_constrain(-15.0, 15.0)); -} -TEST(io_reader, scalar_offset_multiplier_constrain_jacobian) { - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(0.0); - stan::io::reader reader(theta, theta_i); - double lp = -7.2; - EXPECT_FLOAT_EQ(-2.0, - reader.scalar_offset_multiplier_constrain(0.0, 1.0, lp)); - EXPECT_FLOAT_EQ(3.0 + 5.0 * 3.0, - reader.scalar_offset_multiplier_constrain(3.0, 5.0, lp)); - EXPECT_FLOAT_EQ(-3.0 + 2.0 * -1.0, - reader.scalar_offset_multiplier_constrain(-3.0, 2.0, lp)); - EXPECT_FLOAT_EQ(-15.0, - reader.scalar_offset_multiplier_constrain(-15.0, 15.0, lp)); - double expected_lp = -7.2 + log(1.0) + log(5.0) + log(2.0) + log(15.0); - EXPECT_FLOAT_EQ(expected_lp, lp); -} - -TEST(io_reader, prob) { - std::vector theta_i; - std::vector theta; - theta.push_back(0.9); - theta.push_back(0.1); - theta.push_back(0.0); - stan::io::reader reader(theta, theta_i); - double p1 = reader.prob(); - EXPECT_FLOAT_EQ(0.9, p1); - double p2 = reader.prob(); - EXPECT_FLOAT_EQ(0.1, p2); - double p3 = reader.prob(); - EXPECT_FLOAT_EQ(0.0, p3); - - EXPECT_EQ(0U, reader.available()); -} -TEST(io_reader, prob_constrain) { - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(0.0); - stan::io::reader reader(theta, theta_i); - EXPECT_FLOAT_EQ(inv_logit_m2, reader.prob_constrain()); - EXPECT_FLOAT_EQ(inv_logit_3, reader.prob_constrain()); - EXPECT_FLOAT_EQ(inv_logit_m1, reader.prob_constrain()); - EXPECT_FLOAT_EQ(inv_logit_0, reader.prob_constrain()); -} -TEST(io_reader, prob_constrain_jacobian) { - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(0.0); - stan::io::reader reader(theta, theta_i); - double lp = -0.88; - EXPECT_FLOAT_EQ(inv_logit_m2, reader.prob_constrain(lp)); - EXPECT_FLOAT_EQ(inv_logit_3, reader.prob_constrain(lp)); - EXPECT_FLOAT_EQ(inv_logit_m1, reader.prob_constrain(lp)); - EXPECT_FLOAT_EQ(inv_logit_0, reader.prob_constrain(lp)); - double expected_lp = -0.88 + log(inv_logit_m2 * (1.0 - inv_logit_m2)) - + log(inv_logit_3 * (1.0 - inv_logit_3)) - + log(inv_logit_m1 * (1.0 - inv_logit_m1)) - + log(inv_logit_0 * (1.0 - inv_logit_0)); - EXPECT_FLOAT_EQ(expected_lp, lp); -} - -TEST(io_reader, corr) { - std::vector theta_i; - std::vector theta; - theta.push_back(-0.9); - theta.push_back(0.1); - theta.push_back(0.0); - stan::io::reader reader(theta, theta_i); - double rho1 = reader.corr(); - EXPECT_FLOAT_EQ(-0.9, rho1); - double rho2 = reader.corr(); - EXPECT_FLOAT_EQ(0.1, rho2); - double rho3 = reader.corr(); - EXPECT_FLOAT_EQ(0.0, rho3); - - EXPECT_EQ(0U, reader.available()); -} -TEST(io_reader, corr_exception) { - std::vector theta_i; - std::vector theta; - theta.push_back(-0.9); - theta.push_back(-1.1); - theta.push_back(1.1); - stan::io::reader reader(theta, theta_i); - EXPECT_NO_THROW(reader.corr()); - EXPECT_THROW(reader.corr(), std::domain_error); - EXPECT_THROW(reader.corr(), std::domain_error); -} -TEST(io_reader, corr_constrain) { - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(0.0); - stan::io::reader reader(theta, theta_i); - EXPECT_FLOAT_EQ(tanh(-2.0), reader.corr_constrain()); - EXPECT_FLOAT_EQ(tanh(3.0), reader.corr_constrain()); - EXPECT_FLOAT_EQ(tanh(-1.0), reader.corr_constrain()); - EXPECT_FLOAT_EQ(tanh(0.0), reader.corr_constrain()); -} -TEST(io_reader, corr_constrain_jacobian) { - using std::tanh; - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(0.0); - stan::io::reader reader(theta, theta_i); - double lp = -10.0; - EXPECT_FLOAT_EQ(tanh(-2.0), reader.corr_constrain(lp)); - EXPECT_FLOAT_EQ(tanh(3.0), reader.corr_constrain(lp)); - EXPECT_FLOAT_EQ(tanh(-1.0), reader.corr_constrain(lp)); - EXPECT_FLOAT_EQ(tanh(0.0), reader.corr_constrain(lp)); - double expected_lp = -10.0 + log(1.0 - tanh(-2.0) * tanh(-2.0)) - + log(1.0 - tanh(3.0) * tanh(3.0)) - + log(1.0 - tanh(-1.0) * tanh(-1.0)) - + log(1.0 - tanh(0.0) * tanh(0.0)); - EXPECT_FLOAT_EQ(expected_lp, lp); -} - -TEST(io_reader, std_vector) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100U; ++i) - theta.push_back(static_cast(i)); - stan::io::reader reader(theta, theta_i); - for (size_t i = 0; i < 10U; ++i) { - double x = reader.scalar(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - std::vector y = reader.std_vector(3); - EXPECT_EQ(3U, y.size()); - EXPECT_FLOAT_EQ(10.0, y[0]); - EXPECT_FLOAT_EQ(11.0, y[1]); - EXPECT_FLOAT_EQ(12.0, y[2]); - - std::vector z = reader.std_vector(17); - EXPECT_EQ(17U, z.size()); - - double a = reader.scalar(); - EXPECT_FLOAT_EQ(30.0, a); -} - -TEST(io_reader, vector) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100U; ++i) - theta.push_back(static_cast(i)); - stan::io::reader reader(theta, theta_i); - for (size_t i = 0; i < 7U; ++i) { - double x = reader.scalar(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - Eigen::Matrix y = reader.vector(4); - EXPECT_EQ(4, y.rows()); - EXPECT_EQ(1, y.cols()); - EXPECT_EQ(4, y.size()); - EXPECT_FLOAT_EQ(7.0, y[0]); - EXPECT_FLOAT_EQ(8.0, y[1]); - EXPECT_FLOAT_EQ(9.0, y[2]); - EXPECT_FLOAT_EQ(10.0, y[3]); - - double z = reader.scalar(); - EXPECT_FLOAT_EQ(11.0, z); -} - -TEST(io_reader, row_vector) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100U; ++i) - theta.push_back(static_cast(i)); - stan::io::reader reader(theta, theta_i); - for (size_t i = 0; i < 7U; ++i) { - double x = reader.scalar(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - Eigen::Matrix y = reader.row_vector(4); - EXPECT_EQ(4, y.cols()); - EXPECT_EQ(1, y.rows()); - EXPECT_EQ(4, y.size()); - EXPECT_FLOAT_EQ(7.0, y[0]); - EXPECT_FLOAT_EQ(8.0, y[1]); - EXPECT_FLOAT_EQ(9.0, y[2]); - EXPECT_FLOAT_EQ(10.0, y[3]); - - double z = reader.scalar(); - EXPECT_FLOAT_EQ(11.0, z); -} - -TEST(io_reader, matrix) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::reader reader(theta, theta_i); - for (int i = 0; i < 7; ++i) { - double x = reader.scalar(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - Eigen::Matrix y = reader.matrix(3, 2); - EXPECT_EQ(3, y.rows()); - EXPECT_EQ(2, y.cols()); - EXPECT_FLOAT_EQ(7.0, y(0, 0)); - EXPECT_FLOAT_EQ(8.0, y(1, 0)); - EXPECT_FLOAT_EQ(9.0, y(2, 0)); - EXPECT_FLOAT_EQ(10.0, y(0, 1)); - EXPECT_FLOAT_EQ(11.0, y(1, 1)); - EXPECT_FLOAT_EQ(12.0, y(2, 1)); - - double a = reader.scalar(); - EXPECT_FLOAT_EQ(13.0, a); -} - -TEST(io_reader, matrix_constrain) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::reader reader(theta, theta_i); - for (int i = 0; i < 7; ++i) { - double x = reader.scalar(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - Eigen::Matrix y - = reader.matrix_constrain(3, 2); - EXPECT_EQ(3, y.rows()); - EXPECT_EQ(2, y.cols()); - EXPECT_FLOAT_EQ(7.0, y(0, 0)); - EXPECT_FLOAT_EQ(8.0, y(1, 0)); - EXPECT_FLOAT_EQ(9.0, y(2, 0)); - EXPECT_FLOAT_EQ(10.0, y(0, 1)); - EXPECT_FLOAT_EQ(11.0, y(1, 1)); - EXPECT_FLOAT_EQ(12.0, y(2, 1)); - - double a = reader.scalar(); - EXPECT_FLOAT_EQ(13.0, a); -} - -TEST(io_reader, unit_vector) { - std::vector theta_i(0); - std::vector theta(4, sqrt(0.25)); - stan::io::reader reader(theta, theta_i); - Eigen::Matrix y = reader.unit_vector(4); - EXPECT_EQ(4, y.size()); - EXPECT_FLOAT_EQ(sqrt(0.25), y[0]); - EXPECT_FLOAT_EQ(sqrt(0.25), y[1]); - EXPECT_FLOAT_EQ(sqrt(0.25), y[2]); - EXPECT_FLOAT_EQ(sqrt(0.25), y[3]); -} -TEST(io_reader, unit_vector_exception) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100; ++i) - theta.push_back(static_cast(i)); - stan::io::reader reader(theta, theta_i); - theta[0] = 0.00; - theta[1] = -sqrt(0.29); - theta[2] = sqrt(0.70); - theta[3] = -sqrt(0.01); - theta[4] = sqrt(1.0); - theta[5] = sqrt(1.0); - EXPECT_NO_THROW(reader.unit_vector(4)); - EXPECT_THROW(reader.unit_vector(2), std::domain_error); - EXPECT_THROW(reader.unit_vector(0), std::invalid_argument); -} - -TEST(io_reader, simplex) { - std::vector theta_i(0); - std::vector theta(4, 0.25); - stan::io::reader reader(theta, theta_i); - Eigen::Matrix y = reader.simplex(4); - EXPECT_EQ(4, y.size()); - EXPECT_FLOAT_EQ(0.25, y[0]); - EXPECT_FLOAT_EQ(0.25, y[1]); - EXPECT_FLOAT_EQ(0.25, y[2]); - EXPECT_FLOAT_EQ(0.25, y[3]); -} -TEST(io_reader, simplex_exception) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100; ++i) - theta.push_back(static_cast(i)); - stan::io::reader reader(theta, theta_i); - theta[0] = 0.00; - theta[1] = 0.29; - theta[2] = 0.70; - theta[3] = 0.01; - theta[4] = 1.0; - theta[5] = 1.0; - EXPECT_NO_THROW(reader.simplex(4)); - EXPECT_THROW(reader.simplex(2), std::domain_error); - EXPECT_THROW(reader.simplex(0), std::invalid_argument); -} - -TEST(io_reader, ordered) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::reader reader(theta, theta_i); - EXPECT_FLOAT_EQ(0.0, reader.scalar()); // throw away theta[0] - Eigen::Matrix y = reader.ordered(5); - EXPECT_EQ(5, y.size()); - EXPECT_FLOAT_EQ(1.0, y[0]); - EXPECT_FLOAT_EQ(2.0, y[1]); - EXPECT_FLOAT_EQ(5.0, y[4]); - EXPECT_FLOAT_EQ(6.0, reader.scalar()); -} -TEST(io_reader, ordered_exception) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::reader reader(theta, theta_i); - EXPECT_FLOAT_EQ(0.0, reader.scalar()); // throw away theta[0] - Eigen::Matrix y = reader.ordered(5); - EXPECT_EQ(5, y.size()); - EXPECT_FLOAT_EQ(1.0, y[0]); - EXPECT_FLOAT_EQ(2.0, y[1]); - EXPECT_FLOAT_EQ(5.0, y[4]); - EXPECT_FLOAT_EQ(6.0, reader.scalar()); -} -TEST(io_reader, ordered_constrain) { - std::vector theta_i; - std::vector theta; - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); - double v0 = 3.0; - double v1 = v0 + exp(-1.0); - double v2 = v1 + exp(-2.0); - double v3 = v2 + exp(0.0); - stan::io::reader reader(theta, theta_i); - Eigen::Matrix phi(reader.ordered_constrain(4)); - EXPECT_FLOAT_EQ(v0, phi[0]); - EXPECT_FLOAT_EQ(v1, phi[1]); - EXPECT_FLOAT_EQ(v2, phi[2]); - EXPECT_FLOAT_EQ(v3, phi[3]); -} -TEST(io_reader, ordered_constrain_jacobian) { - std::vector theta_i; - std::vector theta; - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); - double v0 = 3.0; - double v1 = v0 + exp(-1.0); - double v2 = v1 + exp(-2.0); - double v3 = v2 + exp(0.0); - stan::io::reader reader(theta, theta_i); - double lp = -101.1; - double expected_lp = lp - 1.0 - 2.0 + 0.0; - Eigen::Matrix phi(reader.ordered_constrain(4, lp)); - EXPECT_FLOAT_EQ(v0, phi[0]); - EXPECT_FLOAT_EQ(v1, phi[1]); - EXPECT_FLOAT_EQ(v2, phi[2]); - EXPECT_FLOAT_EQ(v3, phi[3]); - EXPECT_FLOAT_EQ(expected_lp, lp); -} - -TEST(io_reader, positive_ordered) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::reader reader(theta, theta_i); - EXPECT_FLOAT_EQ(0.0, reader.scalar()); // throw away theta[0] - Eigen::Matrix y = reader.positive_ordered(5); - EXPECT_EQ(5, y.size()); - EXPECT_FLOAT_EQ(1.0, y[0]); - EXPECT_FLOAT_EQ(2.0, y[1]); - EXPECT_FLOAT_EQ(5.0, y[4]); - EXPECT_FLOAT_EQ(6.0, reader.scalar()); -} - -TEST(io_reader, positive_ordered_constrain) { - std::vector theta_i; - std::vector theta; - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); - double v0 = exp(3.0); - double v1 = v0 + exp(-1.0); - double v2 = v1 + exp(-2.0); - double v3 = v2 + exp(0.0); - stan::io::reader reader(theta, theta_i); - Eigen::Matrix phi( - reader.positive_ordered_constrain(4)); - EXPECT_FLOAT_EQ(v0, phi[0]); - EXPECT_FLOAT_EQ(v1, phi[1]); - EXPECT_FLOAT_EQ(v2, phi[2]); - EXPECT_FLOAT_EQ(v3, phi[3]); -} -TEST(io_reader, positive_ordered_constrain_jacobian) { - std::vector theta_i; - std::vector theta; - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); - double v0 = exp(3.0); - double v1 = v0 + exp(-1.0); - double v2 = v1 + exp(-2.0); - double v3 = v2 + exp(0.0); - stan::io::reader reader(theta, theta_i); - double lp = -101.1; - double expected_lp = lp + 3.0 - 1.0 - 2.0 + 0.0; - Eigen::Matrix phi( - reader.positive_ordered_constrain(4, lp)); - EXPECT_FLOAT_EQ(v0, phi[0]); - EXPECT_FLOAT_EQ(v1, phi[1]); - EXPECT_FLOAT_EQ(v2, phi[2]); - EXPECT_FLOAT_EQ(v3, phi[3]); - EXPECT_FLOAT_EQ(expected_lp, lp); -} - -TEST(io_reader, corr_matrix) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - theta[0] = 1.0000000000000000; - theta[1] = 0.1817621852191252; - theta[2] = 0.8620926037637362; - theta[3] = 0.1817621852191252; - theta[4] = 1.0000000000000000; - theta[5] = 0.2248293054822660; - theta[6] = 0.8620926037637362; - theta[7] = 0.2248293054822660; - theta[8] = 1.0000000000000001; // allow some tolerance - stan::io::reader reader(theta, theta_i); - Eigen::Matrix S - = reader.corr_matrix(3); - EXPECT_FLOAT_EQ(theta[0], S(0, 0)); -} -TEST(io_reader, corr_matrix_exception) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - theta[0] = 1.5; - theta[1] = 1.0; - theta[2] = 2.0; - theta[3] = 0.0; - theta[4] = 1.0; - stan::io::reader reader(theta, theta_i); - EXPECT_THROW(reader.corr_matrix(1), std::domain_error); - EXPECT_THROW(reader.corr_matrix(2), std::domain_error); -} -TEST(io_reader, corr_matrix_constrain) { - using Eigen::Dynamic; - using Eigen::Matrix; - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(-1.0); - theta.push_back(0.0); - theta.push_back(0.5); - theta.push_back(1.0); - theta.push_back(2.0); - theta.push_back(1.0); - stan::io::reader reader(theta, theta_i); - Matrix R(reader.corr_matrix_constrain(3U)); - EXPECT_EQ(3, R.rows()); - EXPECT_EQ(3, R.cols()); - EXPECT_EQ(9, R.size()); - EXPECT_EQ(4U, reader.available()); - for (size_t i = 0; i < 3U; ++i) { - EXPECT_FLOAT_EQ(1.0, R(i, i)); - for (size_t j = i + 1; j < 3U; ++j) - EXPECT_FLOAT_EQ(R(i, j), R(j, i)); - } - Eigen::SelfAdjointEigenSolver< - Eigen::Matrix> - solver(R, Eigen::EigenvaluesOnly); - assert(solver.eigenvalues()[0] > 1E-10); -} -TEST(io_reader, corr_matrix_constrain_jacobian) { - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(-1.0); - theta.push_back(0.0); - theta.push_back(0.5); - theta.push_back(1.0); - theta.push_back(2.0); - theta.push_back(1.0); - stan::io::reader reader(theta, theta_i); - double lp = -9.2; - Eigen::Matrix R( - reader.corr_matrix_constrain(3U, lp)); - EXPECT_EQ(3, R.rows()); - EXPECT_EQ(3, R.cols()); - EXPECT_EQ(9, R.size()); - EXPECT_EQ(4U, reader.available()); - for (size_t i = 0; i < 3U; ++i) { - EXPECT_FLOAT_EQ(1.0, R(i, i)); - for (size_t j = i + 1; j < 3U; ++j) - EXPECT_FLOAT_EQ(R(i, j), R(j, i)); - } - Eigen::SelfAdjointEigenSolver< - Eigen::Matrix> - solver(R, Eigen::EigenvaluesOnly); - assert(solver.eigenvalues()[0] > 1E-10); - // FIXME: test jacobian -} - -TEST(io_reader, cov_matrix) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - theta[0] = 6.3295234356180128; - theta[1] = 0.6351775806192667; - theta[2] = 3.8081029582054304; - theta[3] = 0.6351775806192667; - theta[4] = 1.9293554162496527; - theta[5] = 0.5483126868366485; - theta[6] = 3.8081029582054304; - theta[7] = 0.5483126868366485; - theta[8] = 3.0827514661973088; - stan::io::reader reader(theta, theta_i); - Eigen::Matrix S - = reader.cov_matrix(3); - EXPECT_FLOAT_EQ(theta[0], S(0, 0)); - EXPECT_FLOAT_EQ(theta[1], S(1, 0)); - EXPECT_FLOAT_EQ(theta[7], S(2, 1)); - EXPECT_FLOAT_EQ(theta[8], S(2, 2)); -} -TEST(io_reader, cov_matrix_exception) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - theta[0] = 6.3; - theta[1] = 0.7; - theta[2] = 0.6; - theta[3] = 1.9; - stan::io::reader reader(theta, theta_i); - EXPECT_THROW(reader.cov_matrix(2), std::domain_error); - EXPECT_THROW(reader.cov_matrix(0), std::invalid_argument); -} -TEST(io_reader, cov_matrix_constrain) { - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(-1.0); - theta.push_back(0.0); - theta.push_back(0.5); - theta.push_back(1.0); - theta.push_back(2.0); - theta.push_back(1.0); - stan::io::reader reader(theta, theta_i); - Eigen::Matrix S( - reader.cov_matrix_constrain(3U)); - EXPECT_EQ(3, S.rows()); - EXPECT_EQ(3, S.cols()); - EXPECT_EQ(9, S.size()); - EXPECT_EQ(1U, reader.available()); - for (size_t i = 0; i < 3U; ++i) - for (size_t j = i + 1; j < 3U; ++j) - EXPECT_FLOAT_EQ(S(i, j), S(j, i)); - Eigen::SelfAdjointEigenSolver< - Eigen::Matrix> - solver(S, Eigen::EigenvaluesOnly); - assert(solver.eigenvalues()[0] - > 1E-10); // check positive definite with smallest eigenvalue > 0 -} -TEST(io_reader, cov_matrix_constrain_jacobian) { - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(-1.0); - theta.push_back(0.0); - theta.push_back(0.5); - theta.push_back(1.0); - theta.push_back(2.0); - theta.push_back(1.0); - stan::io::reader reader(theta, theta_i); - double lp = -3.1; - - Eigen::Matrix S( - reader.cov_matrix_constrain(3U, lp)); - - EXPECT_EQ(3, S.rows()); - EXPECT_EQ(3, S.cols()); - EXPECT_EQ(9, S.size()); - EXPECT_EQ(1U, reader.available()); - for (size_t i = 0; i < 3U; ++i) - for (size_t j = i + 1; j < 3U; ++j) - EXPECT_FLOAT_EQ(S(i, j), S(j, i)); - Eigen::SelfAdjointEigenSolver< - Eigen::Matrix> - solver(S, Eigen::EigenvaluesOnly); - assert(solver.eigenvalues()[0] - > 1E-10); // check positive definite with smallest eigenvalue > 0 - // FIXME: test Jacobian -} - -TEST(io_reader, cholesky_factor_cov) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - // column major - theta[0] = 1; - theta[1] = 2; - theta[2] = 3; - - theta[3] = 0; - theta[4] = 4; - theta[5] = 5; - - theta[6] = 0; - theta[7] = 0; - theta[8] = 6; - stan::io::reader reader(theta, theta_i); - Eigen::Matrix S - = reader.cholesky_factor_cov(3, 3); - EXPECT_FLOAT_EQ(theta[0], S(0, 0)); - EXPECT_FLOAT_EQ(theta[1], S(1, 0)); - EXPECT_FLOAT_EQ(theta[7], S(1, 2)); - EXPECT_FLOAT_EQ(theta[8], S(2, 2)); -} -TEST(io_reader, cholesky_factor_cov_asymmetric) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - // column major - theta[0] = 1; - theta[1] = 2; - theta[2] = 3; - - theta[3] = 0; - theta[4] = 4; - theta[5] = 5; - - stan::io::reader reader(theta, theta_i); - Eigen::Matrix S - = reader.cholesky_factor_cov(3, 2); - EXPECT_FLOAT_EQ(theta[0], S(0, 0)); - EXPECT_FLOAT_EQ(theta[1], S(1, 0)); - EXPECT_FLOAT_EQ(theta[2], S(2, 0)); - - EXPECT_FLOAT_EQ(theta[3], S(0, 1)); - EXPECT_FLOAT_EQ(theta[4], S(1, 1)); - EXPECT_FLOAT_EQ(theta[5], S(2, 1)); -} - -TEST(io_reader, cholesky_factor_cov_exception) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - theta[0] = -6.3; - stan::io::reader reader(theta, theta_i); - EXPECT_THROW(reader.cholesky_factor_cov(2, 2), std::domain_error); - EXPECT_THROW(reader.cholesky_factor_cov(0, 0), std::domain_error); - - theta[0] = 1; - EXPECT_THROW(reader.cholesky_factor_cov(2, 3), std::domain_error); -} -TEST(io_reader, cholesky_factor_cov_constrain) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 8; ++i) - theta.push_back(-static_cast(i)); - stan::io::reader reader(theta, theta_i); - Eigen::Matrix L( - reader.cholesky_factor_cov_constrain(3U, 3U)); - EXPECT_NO_THROW(stan::math::check_cholesky_factor( - "test_cholesky_factor_constrain", "L", L)); - EXPECT_EQ(3, L.rows()); - EXPECT_EQ(3, L.cols()); - EXPECT_EQ(9, L.size()); - EXPECT_EQ(2U, reader.available()); -} -TEST(io_reader, cholesky_factor_cov_constrain_asymmetric) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 8; ++i) - theta.push_back(-static_cast(i)); - stan::io::reader reader(theta, theta_i); - Eigen::Matrix L( - reader.cholesky_factor_cov_constrain(3U, 2U)); - EXPECT_NO_THROW(stan::math::check_cholesky_factor( - "test_cholesky_factor_constrain", "L", L)); - EXPECT_EQ(3, L.rows()); - EXPECT_EQ(2, L.cols()); - EXPECT_EQ(6, L.size()); - EXPECT_EQ(3U, reader.available()); -} -TEST(io_reader, cholesky_factor_cov_constrain_jacobian) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 8; ++i) - theta.push_back(-static_cast(i)); - stan::io::reader reader(theta, theta_i); - double lp = 1.9; - Eigen::Matrix L( - reader.cholesky_factor_cov_constrain(3U, 3U, lp)); - EXPECT_NO_THROW(stan::math::check_cholesky_factor( - "test_cholesky_factor_constrain", "L", L)); - EXPECT_EQ(3, L.rows()); - EXPECT_EQ(3, L.cols()); - EXPECT_EQ(9, L.size()); - EXPECT_EQ(2U, reader.available()); - EXPECT_EQ(1.9 + log(L(0, 0)) + log(L(1, 1)) + log(L(2, 2)), lp); -} -TEST(io_reader, cholesky_factor_cov_constrain_jacobian_asymmetric) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 12; ++i) - theta.push_back(-static_cast(i)); - stan::io::reader reader(theta, theta_i); - double lp = 1.9; - Eigen::Matrix L( - reader.cholesky_factor_cov_constrain(4U, 3U, lp)); - EXPECT_NO_THROW(stan::math::check_cholesky_factor( - "test_cholesky_factor_constrain", "L", L)); - EXPECT_EQ(4, L.rows()); - EXPECT_EQ(3, L.cols()); - EXPECT_EQ(12, L.size()); - EXPECT_EQ(3U, reader.available()); - EXPECT_EQ(1.9 + log(L(0, 0)) + log(L(1, 1)) + log(L(2, 2)), lp); -} - -TEST(io_reader, cholesky_factor_corr) { - std::vector theta_i; - std::vector theta(9); - // column major - theta[0] = 1; - theta[1] = 0; - theta[2] = 0; - - theta[3] = 0; - theta[4] = 1; - theta[5] = 0; - - theta[6] = 0; - theta[7] = 0; - theta[8] = 1; - stan::io::reader reader(theta, theta_i); - Eigen::Matrix S - = reader.cholesky_factor_corr(3); - EXPECT_FLOAT_EQ(theta[0], S(0, 0)); - EXPECT_FLOAT_EQ(theta[1], S(1, 0)); - EXPECT_FLOAT_EQ(theta[4], S(1, 1)); - EXPECT_FLOAT_EQ(theta[7], S(1, 2)); - EXPECT_FLOAT_EQ(theta[8], S(2, 2)); -} - -TEST(io_reader, cholesky_factor_corr_exception) { - std::vector theta_i; - std::vector theta(9); - Eigen::Matrix S; - - // non lower-triangular matrix (column major) - // the rest of these tests are with check_cholesky_factor_corr - theta[0] = 1; - theta[1] = 0; - theta[2] = 0; - - theta[3] = 0.5; - theta[4] = 1; - theta[5] = 0; - - theta[6] = 0; - theta[7] = 0; - theta[8] = 1; - stan::io::reader reader(theta, theta_i); - EXPECT_THROW(reader.cholesky_factor_corr(3), std::domain_error); -} -TEST(io_reader, cholesky_factor_corr_constrain) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 8; ++i) - theta.push_back(-static_cast(i)); - stan::io::reader reader(theta, theta_i); - Eigen::Matrix L( - reader.cholesky_factor_corr_constrain(3U)); - EXPECT_NO_THROW(stan::math::check_cholesky_factor_corr( - "test_cholesky_factor_corr_constrain", "L", L)); - EXPECT_EQ(3, L.rows()); - EXPECT_EQ(3, L.cols()); - EXPECT_EQ(9, L.size()); - EXPECT_EQ(5U, reader.available()); -} - -TEST(io_reader, eos_exception) { - std::vector theta; - theta.push_back(1.0); - theta.push_back(2.0); - std::vector theta_i; - theta_i.push_back(1); - stan::io::reader reader(theta, theta_i); - - EXPECT_EQ(2U, reader.available()); - EXPECT_EQ(1U, reader.available_i()); - - EXPECT_NO_THROW(reader.scalar()); - EXPECT_NO_THROW(reader.scalar()); - EXPECT_THROW(reader.scalar(), std::runtime_error); - - // should go back to working - EXPECT_NO_THROW(reader.integer()); - EXPECT_THROW(reader.integer(), std::runtime_error); - - // should keep throwing - EXPECT_THROW(reader.scalar(), std::runtime_error); - EXPECT_THROW(reader.integer(), std::runtime_error); -} - -TEST(io_reader, lub_exception) { - std::vector theta; - for (int i = 0; i < 10; ++i) - theta.push_back(static_cast(i)); - std::vector theta_i; - for (int i = 0; i < 10; ++i) - theta_i.push_back(i); - stan::io::reader reader(theta, theta_i); - - EXPECT_THROW(reader.scalar_lb(10.0), std::domain_error); - EXPECT_THROW(reader.scalar_ub(-2.0), std::domain_error); - EXPECT_THROW(reader.scalar_lub(-20.0, -18.0), std::domain_error); - EXPECT_THROW(reader.scalar_lub(-18.0, -20.0), std::domain_error); - EXPECT_FLOAT_EQ(4.0, reader.scalar()); - - EXPECT_THROW(reader.integer_lb(10), std::runtime_error); - EXPECT_THROW(reader.integer_ub(-2), std::runtime_error); - EXPECT_THROW(reader.integer_lub(-20, -18), std::runtime_error); - EXPECT_THROW(reader.integer_lub(-18, -20), std::runtime_error); - EXPECT_EQ(4, reader.integer()); -} - -TEST(io_reader, matrix_lb) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::reader reader(theta, theta_i); - for (int i = 0; i < 7; ++i) { - double x = reader.scalar(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - double lb = -1.5; - Eigen::Matrix y - = reader.matrix_lb(lb, 3, 2); - EXPECT_EQ(3, y.rows()); - EXPECT_EQ(2, y.cols()); - EXPECT_FLOAT_EQ(7.0, y(0, 0)); - EXPECT_FLOAT_EQ(8.0, y(1, 0)); - EXPECT_FLOAT_EQ(9.0, y(2, 0)); - EXPECT_FLOAT_EQ(10.0, y(0, 1)); - EXPECT_FLOAT_EQ(11.0, y(1, 1)); - EXPECT_FLOAT_EQ(12.0, y(2, 1)); - - double a = reader.scalar(); - EXPECT_FLOAT_EQ(13.0, a); -} - -TEST(io_reader, matrix_lb_constrain) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::reader reader(theta, theta_i); - for (int i = 0; i < 7; ++i) { - double x = reader.scalar(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - double lb = -1.5; - Eigen::Matrix y - = reader.matrix_lb_constrain(lb, 3, 2); - EXPECT_EQ(3, y.rows()); - EXPECT_EQ(2, y.cols()); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(7.0, lb), y(0, 0)); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(8.0, lb), y(1, 0)); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(9.0, lb), y(2, 0)); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(10.0, lb), y(0, 1)); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(11.0, lb), y(1, 1)); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(12.0, lb), y(2, 1)); - - double a = reader.scalar(); - EXPECT_FLOAT_EQ(13.0, a); -} - -TEST(io_reader, matrix_lb_constrain_lp) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::reader reader(theta, theta_i); - for (int i = 0; i < 7; ++i) { - double x = reader.scalar(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - double lb = -1.5; - double lp = -5.0; - Eigen::Matrix y - = reader.matrix_lb_constrain(lb, 3, 2, lp); - EXPECT_EQ(3, y.rows()); - EXPECT_EQ(2, y.cols()); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(7.0, lb, lp), y(0, 0)); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(8.0, lb, lp), y(1, 0)); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(9.0, lb, lp), y(2, 0)); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(10.0, lb, lp), y(0, 1)); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(11.0, lb, lp), y(1, 1)); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(12.0, lb, lp), y(2, 1)); - - double a = reader.scalar(); - EXPECT_FLOAT_EQ(13.0, a); -} - -TEST(io_reader, matrix_ub) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::reader reader(theta, theta_i); - for (int i = 0; i < 7; ++i) { - double x = reader.scalar(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - double ub = 12.5; - Eigen::Matrix y - = reader.matrix_ub(ub, 3, 2); - EXPECT_EQ(3, y.rows()); - EXPECT_EQ(2, y.cols()); - EXPECT_FLOAT_EQ(7.0, y(0, 0)); - EXPECT_FLOAT_EQ(8.0, y(1, 0)); - EXPECT_FLOAT_EQ(9.0, y(2, 0)); - EXPECT_FLOAT_EQ(10.0, y(0, 1)); - EXPECT_FLOAT_EQ(11.0, y(1, 1)); - EXPECT_FLOAT_EQ(12.0, y(2, 1)); - - double a = reader.scalar(); - EXPECT_FLOAT_EQ(13.0, a); -} - -TEST(io_reader, matrix_ub_constrain) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::reader reader(theta, theta_i); - for (int i = 0; i < 7; ++i) { - double x = reader.scalar(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - double ub = 14.1; - Eigen::Matrix y - = reader.matrix_ub_constrain(ub, 3, 2); - EXPECT_EQ(3, y.rows()); - EXPECT_EQ(2, y.cols()); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(7.0, ub), y(0, 0)); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(8.0, ub), y(1, 0)); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(9.0, ub), y(2, 0)); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(10.0, ub), y(0, 1)); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(11.0, ub), y(1, 1)); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(12.0, ub), y(2, 1)); - - double a = reader.scalar(); - EXPECT_FLOAT_EQ(13.0, a); -} - -TEST(io_reader, matrix_ub_constrain_lp) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::reader reader(theta, theta_i); - for (int i = 0; i < 7; ++i) { - double x = reader.scalar(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - double ub = 12.1; - double lp = -5.0; - Eigen::Matrix y - = reader.matrix_ub_constrain(ub, 3, 2, lp); - EXPECT_EQ(3, y.rows()); - EXPECT_EQ(2, y.cols()); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(7.0, ub, lp), y(0, 0)); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(8.0, ub, lp), y(1, 0)); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(9.0, ub, lp), y(2, 0)); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(10.0, ub, lp), y(0, 1)); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(11.0, ub, lp), y(1, 1)); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(12.0, ub, lp), y(2, 1)); - - double a = reader.scalar(); - EXPECT_FLOAT_EQ(13.0, a); -} - -TEST(io_reader, matrix_lub) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::reader reader(theta, theta_i); - for (int i = 0; i < 7; ++i) { - double x = reader.scalar(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - double lb = 6.9; - double ub = 12.5; - Eigen::Matrix y - = reader.matrix_lub(lb, ub, 3, 2); - EXPECT_EQ(3, y.rows()); - EXPECT_EQ(2, y.cols()); - EXPECT_FLOAT_EQ(7.0, y(0, 0)); - EXPECT_FLOAT_EQ(8.0, y(1, 0)); - EXPECT_FLOAT_EQ(9.0, y(2, 0)); - EXPECT_FLOAT_EQ(10.0, y(0, 1)); - EXPECT_FLOAT_EQ(11.0, y(1, 1)); - EXPECT_FLOAT_EQ(12.0, y(2, 1)); - - double a = reader.scalar(); - EXPECT_FLOAT_EQ(13.0, a); -} - -TEST(io_reader, matrix_lub_constrain) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::reader reader(theta, theta_i); - for (int i = 0; i < 7; ++i) { - double x = reader.scalar(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - double lb = 3.5; - double ub = 14.1; - Eigen::Matrix y - = reader.matrix_lub_constrain(lb, ub, 3, 2); - EXPECT_EQ(3, y.rows()); - EXPECT_EQ(2, y.cols()); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(7.0, lb, ub), y(0, 0)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(8.0, lb, ub), y(1, 0)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(9.0, lb, ub), y(2, 0)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(10.0, lb, ub), y(0, 1)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(11.0, lb, ub), y(1, 1)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(12.0, lb, ub), y(2, 1)); - - double a = reader.scalar(); - EXPECT_FLOAT_EQ(13.0, a); -} - -TEST(io_reader, matrix_lub_constrain_lp) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::reader reader(theta, theta_i); - for (int i = 0; i < 7; ++i) { - double x = reader.scalar(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - double lb = 4.1; - double ub = 12.1; - double lp = -5.0; - Eigen::Matrix y - = reader.matrix_lub_constrain(lb, ub, 3, 2, lp); - EXPECT_EQ(3, y.rows()); - EXPECT_EQ(2, y.cols()); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(7.0, lb, ub, lp), y(0, 0)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(8.0, lb, ub, lp), y(1, 0)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(9.0, lb, ub, lp), y(2, 0)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(10.0, lb, ub, lp), y(0, 1)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(11.0, lb, ub, lp), y(1, 1)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(12.0, lb, ub, lp), y(2, 1)); - - double a = reader.scalar(); - EXPECT_FLOAT_EQ(13.0, a); -} - -TEST(io_reader, SimplexThrows) { - std::vector theta; - std::vector theta_i; - stan::io::reader reader(theta, theta_i); - - double x = 0; - double lp = 0; - EXPECT_THROW(reader.simplex(x), std::invalid_argument); - EXPECT_THROW(reader.simplex_constrain(x), std::invalid_argument); - EXPECT_THROW(reader.simplex_constrain(x, lp), std::invalid_argument); -} - -TEST(io_reader, UnitVectorThrows) { - std::vector theta; - std::vector theta_i; - stan::io::reader reader(theta, theta_i); - - double x = 0; - double lp = 0; - EXPECT_THROW(reader.unit_vector(x), std::invalid_argument); - EXPECT_THROW(reader.unit_vector_constrain(x), std::invalid_argument); - EXPECT_THROW(reader.unit_vector_constrain(x, lp), std::invalid_argument); -} - -TEST(IoReader, var_vector) { - using stan::math::var; - using stan::math::var_value; - std::vector theta{0, 1, 2, 3, 4}; - std::vector theta_i; - stan::io::reader reader(theta, theta_i); - auto vec_x = reader.var_vector(5); - EXPECT_TRUE((stan::is_var_vector::value)); - for (int i = 0; i < 5; ++i) { - EXPECT_EQ(vec_x.val()(i), i); - } - auto vec_x_empty = reader.var_vector(0); - stan::math::recover_memory(); -} - -TEST(IoReader, var_vector_double) { - using stan::math::var; - using stan::math::var_value; - std::vector theta{0, 1, 2, 3, 4}; - std::vector theta_i; - stan::io::reader reader(theta, theta_i); - auto vec_x = reader.var_vector(5); - EXPECT_TRUE( - (stan::is_eigen_vector::value - && std::is_arithmetic>::value)); - for (int i = 0; i < 5; ++i) { - EXPECT_EQ(vec_x.val()(i), i); - } -} - -TEST(IoReader, var_row_vector) { - using stan::math::var; - using stan::math::var_value; - std::vector theta{0, 1, 2, 3, 4}; - std::vector theta_i; - stan::io::reader reader(theta, theta_i); - auto vec_x = reader.var_row_vector(5); - EXPECT_TRUE((stan::is_var_row_vector::value)); - for (int i = 0; i < 5; ++i) { - EXPECT_EQ(vec_x.val()(i), i); - } - auto vec_x_empty = reader.var_row_vector(0); -} - -TEST(IoReader, var_row_vector_double) { - using stan::math::var; - using stan::math::var_value; - std::vector theta{0, 1, 2, 3, 4}; - std::vector theta_i; - stan::io::reader reader(theta, theta_i); - auto vec_x = reader.var_row_vector(5); - EXPECT_TRUE( - (stan::is_eigen_row_vector::value - && std::is_arithmetic>::value)); - for (int i = 0; i < 5; ++i) { - EXPECT_EQ(vec_x.val()(i), i); - } - auto vec_x_empty = reader.var_row_vector(0); -} - -TEST(IoReader, var_matrix) { - using stan::math::var; - using stan::math::var_value; - std::vector theta{0, 1, 2, 3, 4, 5, 6, 7, 8}; - std::vector theta_i; - stan::io::reader reader(theta, theta_i); - auto mat_x = reader.var_matrix(3, 3); - EXPECT_TRUE((stan::is_var_matrix::value)); - for (int i = 0; i < 9; ++i) { - EXPECT_EQ(mat_x.val()(i), i); - } - auto mat_x_empty = reader.var_matrix(0, 0); -} - -TEST(IoReader, var_matrix_double) { - using stan::math::var; - using stan::math::var_value; - std::vector theta{0, 1, 2, 3, 4, 5, 6, 7, 8}; - std::vector theta_i; - stan::io::reader reader(theta, theta_i); - auto mat_x = reader.var_matrix(3, 3); - EXPECT_TRUE( - (stan::is_eigen_dense_dynamic::value - && std::is_arithmetic>::value)); - for (int i = 0; i < 9; ++i) { - EXPECT_EQ(mat_x.val()(i), i); - } - auto mat_x_empty = reader.var_matrix(0, 0); -} diff --git a/src/test/unit/io/reader_test.cpp b/src/test/unit/io/reader_test.cpp index 995f9c0104a..8277deeb653 100644 --- a/src/test/unit/io/reader_test.cpp +++ b/src/test/unit/io/reader_test.cpp @@ -107,20 +107,6 @@ TEST(io_reader, scalar_pos_constrain) { EXPECT_FLOAT_EQ(exp(-1.0), reader.scalar_pos_constrain()); EXPECT_FLOAT_EQ(exp(0.0), reader.scalar_pos_constrain()); } -TEST(io_reader, scalar_pos_constrain_falselp) { - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(0.0); - stan::io::reader reader(theta, theta_i); - double lp = -1.2; - EXPECT_FLOAT_EQ(exp(-2.0), reader.scalar_pos_constrain(lp)); - EXPECT_FLOAT_EQ(exp(3.0), reader.scalar_pos_constrain(lp)); - EXPECT_FLOAT_EQ(exp(-1.0), reader.scalar_pos_constrain(lp)); - EXPECT_FLOAT_EQ(exp(0.0), reader.scalar_pos_constrain(lp)); -} TEST(io_reader, scalar_pos_constrain_jacobian) { std::vector theta_i; std::vector theta; From 5f9e5428b06843d941e359ba8ceeb37a7f472586 Mon Sep 17 00:00:00 2001 From: Steve Bronder Date: Fri, 19 Feb 2021 15:52:47 -0500 Subject: [PATCH 04/29] adds deserializer type with methods for lb/ub/lub --- src/stan/io/deserializer.hpp | 256 +++++++++++++++ src/test/unit/io/deserializer_test.cpp | 413 +++++++++++++++++++++++++ 2 files changed, 669 insertions(+) create mode 100644 src/stan/io/deserializer.hpp create mode 100644 src/test/unit/io/deserializer_test.cpp diff --git a/src/stan/io/deserializer.hpp b/src/stan/io/deserializer.hpp new file mode 100644 index 00000000000..0281a69aafd --- /dev/null +++ b/src/stan/io/deserializer.hpp @@ -0,0 +1,256 @@ +#ifndef STAN_IO_DESERIALIZER_HPP +#define STAN_IO_DESERIALIZER_HPP + +#include + +namespace stan { + +namespace io { + +/** + * A stream-based reader for integer, scalar, vector, matrix + * and array data types, with Jacobian calculations. + * + * The template parameter T represents the type of + * scalars and the values in vectors and matrices. The only + * requirement on the template type T is that a + * double can be copied into it, as in + * + * T t = 0.0; + * + * This includes double itself and the reverse-mode + * algorithmic differentiation class stan::math::var. + * + *

For transformed values, the scalar type parameter T + * must support the transforming operations, such as exp(x) + * for positive-bounded variables. It must also support equality and + * inequality tests with double values. + * + * @tparam T Basic scalar type. + */ +template +class deserializer { +private: + Eigen::Map> data_r_; + Eigen::Map> data_i_; + size_t r_size_{0}; + size_t i_size_{0}; + size_t pos_r_{0}; + size_t pos_i_{0}; + + inline const T &scalar_ptr() { return data_r_.coeffRef(pos_r_); } + + inline const T& scalar_ptr_increment(size_t m) { + pos_r_ += m; + return data_r_.coeffRef(pos_r_ - m); + } + + inline const int &int_ptr() { return data_i_.coeffRef(pos_i_); } + + inline const int &int_ptr_increment(size_t m) { + pos_i_ += m; + return data_i_.coeffRef(pos_i_ - m); + } + void check_r_capacity() const { + if (pos_r_ >= r_size_) { + []() STAN_COLD_PATH { + throw std::runtime_error("no more scalars to read"); + }(); + } + } + + void check_i_capacity() const { + if (pos_i_ >= i_size_) { + []() STAN_COLD_PATH { + throw std::runtime_error("no more integers to read"); + }(); + } + } + +public: + using matrix_t = Eigen::Matrix; + using vector_t = Eigen::Matrix; + using row_vector_t = Eigen::Matrix; + + using map_matrix_t = Eigen::Map; + using map_vector_t = Eigen::Map; + using map_row_vector_t = Eigen::Map; + + using var_matrix_t = stan::math::var_value< + Eigen::Matrix>; + using var_vector_t + = stan::math::var_value>; + using var_row_vector_t + = stan::math::var_value>; + + /** + * Construct a variable reader using the specified vectors + * as the source of scalar and integer values for data. This + * class holds a reference to the specified data vectors. + * + * Attempting to read beyond the end of the data or integer + * value sequences raises a runtime exception. + * + * @param data_r Sequence of scalar values. + * @param data_i Sequence of integer values. + */ + template * = nullptr> + deserializer(RVec& data_r, IntVec& data_i) + : data_r_(data_r.data(), data_r.size()), + data_i_(data_i.data(), data_i.size()), + r_size_(data_r.size()), + i_size_(data_i.size()) {} + + + /** + * Return the number of scalars remaining to be read. + * + * @return Number of scalars left to read. + */ + inline size_t available() const noexcept { return r_size_ - pos_r_; } + + /** + * Return the number of integers remaining to be read. + * + * @return Number of integers left to read. + */ + inline size_t available_i() const noexcept { return i_size_ - pos_i_; } + + template , is_autodiff>* = nullptr> + auto read() { + check_r_capacity(); + return data_r_.coeffRef(pos_r_++); + } + + template * = nullptr> + auto read() { + check_r_capacity(); + return std::complex(data_r_.coeffRef(pos_r_++), data_r_.coeffRef(pos_r_++)); + } + + template * = nullptr> + auto read() { + check_i_capacity(); + return data_i_.coeffRef(pos_i_++); + } + + template * = nullptr> + auto read(Size m) { + if (unlikely(m == 0)) { + return map_vector_t(nullptr, m); + } else { + return map_vector_t(&scalar_ptr_increment(m), m); + } + } + + template * = nullptr> + auto read(Size m) { + if (unlikely(m == 0)) { + return map_row_vector_t(nullptr, m); + } else { + return map_row_vector_t(&scalar_ptr_increment(m), m); + } + } + + template * = nullptr> + auto read(Rows rows, Cols cols) { + if (rows == 0 || cols == 0) { + return map_matrix_t(nullptr, rows, cols); + } else { + return map_matrix_t(&scalar_ptr_increment(rows * cols), rows, cols); + } + } + + template * = nullptr, + require_var_matrix_t* = nullptr> + auto read(Sizes... sizes) { + using value_t = typename Ret::value_type; + return stan::math::to_var_value(this->read(sizes...)); + } + + template * = nullptr, + require_var_matrix_t* = nullptr> + auto read(Sizes... sizes) { + using value_t = typename Ret::value_type; + return this->read(sizes...); + } + + template * = nullptr> + inline auto read(Size m, Sizes... dims) { + if (unlikely(m == 0)) { + return Ret(); + } else { + using ret_value_type = value_type_t; + Ret ret_vec; + ret_vec.reserve(m); + for (Size i = 0; i < m; ++i) { + ret_vec.emplace_back(this->read(dims...)); + } + return ret_vec; + } + } + + template + auto read_lb(const LB& lb, Sizes... sizes) { + using stan::math::check_greater_or_equal; + auto ret = this->read(sizes...); + check_greater_or_equal("io deserializer", "Lower Bound", ret, lb); + return ret; + } + + + template + auto read_lb_constrain(const LB& lb, LP& lp, Sizes... sizes) { + if (Jacobian) { + return stan::math::lb_constrain(this->read(sizes...), lb, lp); + } else { + return stan::math::lb_constrain(this->read(sizes...), lb); + } + } + + template + auto read_ub(const UB& ub, Sizes... sizes) { + using stan::math::check_less_or_equal; + auto ret = this->read(sizes...); + check_less_or_equal("io deserializer", "Upper Bound", ret, ub); + return ret; + } + + + template + auto read_ub_constrain(const UB& ub, LP& lp, Sizes... sizes) { + if (Jacobian) { + return stan::math::ub_constrain(this->read(sizes...), ub, lp); + } else { + return stan::math::ub_constrain(this->read(sizes...), ub); + } + } + + template + auto read_lub(const LB& lb, const UB& ub, Sizes... sizes) { + using stan::math::check_bounded; + auto ret = this->read(sizes...); + check_bounded("io deserializer", "Upper and Lower Bound", ret, lb, ub); + return ret; + } + + + template + auto read_lub_constrain(const LB& lb, const UB& ub, LP& lp, Sizes... sizes) { + if (Jacobian) { + return stan::math::lub_constrain(this->read(sizes...), lb, ub, lp); + } else { + return stan::math::lub_constrain(this->read(sizes...), lb, ub); + } + } + +}; + + +} +} + +#endif diff --git a/src/test/unit/io/deserializer_test.cpp b/src/test/unit/io/deserializer_test.cpp new file mode 100644 index 00000000000..3e3ef9d4ede --- /dev/null +++ b/src/test/unit/io/deserializer_test.cpp @@ -0,0 +1,413 @@ +#include +#include + +TEST(deserializer, eigen_input) { + Eigen::Matrix theta_i(1); + Eigen::VectorXd theta(2); + theta[0] = 1.0; + theta[1] = 2.0; + theta_i[0] = 1; + stan::io::deserializer deserializer(theta, theta_i); + double x = deserializer.read(); + EXPECT_FLOAT_EQ(1.0, x); + double y = deserializer.read(); + EXPECT_FLOAT_EQ(2.0, y); + int z = deserializer.read(); + EXPECT_EQ(1, z); + EXPECT_EQ(0U, deserializer.available()); +} + +TEST(deserializer, zeroSizeVecs) { + std::vector theta_i; + std::vector theta; + theta.push_back(1.0); + stan::io::deserializer deserializer(theta, theta_i); + + EXPECT_FLOAT_EQ(1.0, deserializer.read()); // finish available + + EXPECT_EQ(0, deserializer.read>(0).size()); + EXPECT_EQ(0, deserializer.read(0).size()); + EXPECT_EQ(0, deserializer.read(0).size()); + EXPECT_EQ(0, deserializer.read(0, 3).size()); + EXPECT_EQ(0, deserializer.read(3, 0).size()); + EXPECT_EQ(0, deserializer.read>>(0, 0, 0, 0).size()); +} + +TEST(deserializer_scalar, read) { + std::vector theta_i; + std::vector theta; + theta.push_back(1.0); + theta.push_back(2.0); + stan::io::deserializer deserializer(theta, theta_i); + double x = deserializer.read(); + EXPECT_FLOAT_EQ(1.0, x); + double y = deserializer.read(); + EXPECT_FLOAT_EQ(2.0, y); + EXPECT_EQ(0U, deserializer.available()); +} + +TEST(deserializer_vector, read) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100U; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (size_t i = 0; i < 7U; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + Eigen::Matrix y = deserializer.read(4); + EXPECT_EQ(4, y.rows()); + EXPECT_EQ(1, y.cols()); + EXPECT_EQ(4, y.size()); + EXPECT_FLOAT_EQ(7.0, y[0]); + EXPECT_FLOAT_EQ(8.0, y[1]); + EXPECT_FLOAT_EQ(9.0, y[2]); + EXPECT_FLOAT_EQ(10.0, y[3]); + + double z = deserializer.read(); + EXPECT_FLOAT_EQ(11.0, z); +} + +TEST(deserializer_rowvector, read) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100U; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (size_t i = 0; i < 7U; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + Eigen::Matrix y = deserializer.read(4); + EXPECT_EQ(4, y.cols()); + EXPECT_EQ(1, y.rows()); + EXPECT_EQ(4, y.size()); + EXPECT_FLOAT_EQ(7.0, y[0]); + EXPECT_FLOAT_EQ(8.0, y[1]); + EXPECT_FLOAT_EQ(9.0, y[2]); + EXPECT_FLOAT_EQ(10.0, y[3]); + + double z = deserializer.read(); + EXPECT_FLOAT_EQ(11.0, z); +} + +TEST(deserializer_stdvec, std_vector_vector) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100U; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + auto y = deserializer.read>(5, 4); + EXPECT_EQ(5, y.size()); + int sentinal = 0; + for (int i = 0; i < y.size(); ++i) { + EXPECT_EQ(4, y[i].rows()); + EXPECT_EQ(1, y[i].cols()); + for (int j = 0; j < 4; ++j) { + EXPECT_FLOAT_EQ(sentinal, y[i].coeff(j)); + sentinal++; + } + } +} + +TEST(deserializer_stdvec, std_vector_std_vector_matrix) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 120U; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + auto y = deserializer.read>>(5, 4, 3, 2); + EXPECT_EQ(5, y.size()); + int sentinal = 0; + for (int i = 0; i < y.size(); ++i) { + EXPECT_EQ(4, y[i].size()); + for (int j = 0; j < 4; ++j) { + EXPECT_EQ(3, y[i][j].rows()); + EXPECT_EQ(2, y[i][j].cols()); + for (int k = 0; k < 6; ++k) { + EXPECT_FLOAT_EQ(sentinal, y[i][j].coeff(k)); + sentinal++; + } + } + } +} + +// lower bounds + + +TEST(deserializer_scalar, read_lb) { + std::vector theta_i; + std::vector theta; + theta.push_back(-1.0); + theta.push_back(2.0); + stan::io::deserializer deserializer(theta, theta_i); + double x = deserializer.read_lb(-2.0); + EXPECT_FLOAT_EQ(-1.0, x); + double y = deserializer.read_lb(1.0); + EXPECT_FLOAT_EQ(2.0, y); + EXPECT_EQ(0U, deserializer.available()); +} +TEST(deserializer_scalar, read_lb_exception) { + std::vector theta_i; + std::vector theta; + theta.push_back(-1.0); + theta.push_back(2.0); + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_NO_THROW(deserializer.read_lb(-1.0)); + EXPECT_THROW(deserializer.read_lb(3.0), std::domain_error); +} +TEST(deserializer_scalar, read_lb_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0.0; + EXPECT_FLOAT_EQ(1.0 + exp(-2.0), (deserializer.read_lb_constrain(1.0, lp))); + EXPECT_FLOAT_EQ(5.0 + exp(3.0), (deserializer.read_lb_constrain(5.0, lp))); + EXPECT_FLOAT_EQ(-2.0 + exp(-1.0), (deserializer.read_lb_constrain(-2.0, lp))); + EXPECT_FLOAT_EQ(15.0 + exp(0.0), (deserializer.read_lb_constrain(15.0, lp))); +} +TEST(deserializer_scalar, read_lb_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = -1.5; + EXPECT_FLOAT_EQ(1.0 + exp(-2.0), (deserializer.read_lb_constrain(1.0, lp))); + EXPECT_FLOAT_EQ(5.0 + exp(3.0), (deserializer.read_lb_constrain(5.0, lp))); + EXPECT_FLOAT_EQ(-2.0 + exp(-1.0), (deserializer.read_lb_constrain(-2.0, lp))); + EXPECT_FLOAT_EQ(15.0 + exp(0.0), (deserializer.read_lb_constrain(15.0, lp))); + EXPECT_FLOAT_EQ(-1.5 - 2.0 + 3.0 - 1.0, lp); +} + +// ub + +TEST(deserializer_scalar, read_ub) { + std::vector theta_i; + std::vector theta; + theta.push_back(-1.0); + theta.push_back(2.0); + stan::io::deserializer deserializer(theta, theta_i); + double x = deserializer.read_ub(-0.5); + EXPECT_FLOAT_EQ(-1.0, x); + double y = deserializer.read_ub(5.0); + EXPECT_FLOAT_EQ(2.0, y); + + EXPECT_EQ(0U, deserializer.available()); +} +TEST(deserializer_scalar, read_ub_exception) { + std::vector theta_i; + std::vector theta; + theta.push_back(-1.0); + theta.push_back(2.0); + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_NO_THROW(deserializer.read_ub(-1.0)); + EXPECT_THROW(deserializer.read_ub(1.0), std::domain_error); +} +TEST(deserializer_scalar, read_ub_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0; + EXPECT_FLOAT_EQ(1.0 - exp(-2.0), (deserializer.read_ub_constrain(1.0, lp))); + EXPECT_FLOAT_EQ(5.0 - exp(3.0), (deserializer.read_ub_constrain(5.0, lp))); + EXPECT_FLOAT_EQ(-2.0 - exp(-1.0), (deserializer.read_ub_constrain(-2.0, lp))); + EXPECT_FLOAT_EQ(15.0 - exp(0.0), (deserializer.read_ub_constrain(15.0, lp))); +} +TEST(deserializer_scalar, read_ub_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = -12.9; + EXPECT_FLOAT_EQ(1.0 - exp(-2.0), (deserializer.read_ub_constrain(1.0, lp))); + EXPECT_FLOAT_EQ(5.0 - exp(3.0), (deserializer.read_ub_constrain(5.0, lp))); + EXPECT_FLOAT_EQ(-2.0 - exp(-1.0), (deserializer.read_ub_constrain(-2.0, lp))); + EXPECT_FLOAT_EQ(15.0 - exp(0.0), (deserializer.read_ub_constrain(15.0, lp))); + EXPECT_FLOAT_EQ(-12.9 - 2.0 + 3.0 - 1.0, lp); +} + +// lub + + +TEST(deserializer_scalar, read_lub) { + std::vector theta_i; + std::vector theta; + theta.push_back(-1.0); + theta.push_back(2.0); + stan::io::deserializer deserializer(theta, theta_i); + double x = deserializer.read_lub(-3.0, 3.0); + EXPECT_FLOAT_EQ(-1.0, x); + double y = deserializer.read_lub(-3.0, 3.0); + EXPECT_FLOAT_EQ(2.0, y); + + EXPECT_EQ(0U, deserializer.available()); +} +TEST(deserializer_scalar, read_lub_exception) { + std::vector theta_i; + std::vector theta; + theta.push_back(-1.0); + theta.push_back(2.0); + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_NO_THROW(deserializer.read_lub(-2.0, 2.0)); + EXPECT_THROW(deserializer.read_lub(-1.0, 1.0), std::domain_error); +} +const double inv_logit_m2 = 0.1192029; // stan::math::inv_logit(-2.0) +const double inv_logit_m1 = 0.2689414; // stan::math::inv_logit(-1.0) +const double inv_logit_0 = 0.5; // stan::math::inv_logit(0) +const double inv_logit_3 = 0.9525741; // stan::math::inv_logit(3.0) + +TEST(deserializer_scalar, read_lub_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0; + EXPECT_FLOAT_EQ(inv_logit_m2, (deserializer.read_lub_constrain(0.0, 1.0, lp))); + EXPECT_FLOAT_EQ(3.0 + 2.0 * inv_logit_3, + (deserializer.read_lub_constrain(3.0, 5.0, lp))); + EXPECT_FLOAT_EQ(-3.0 + 5.0 * inv_logit_m1, + (deserializer.read_lub_constrain(-3.0, 2.0, lp))); + EXPECT_FLOAT_EQ(-15.0 + 30.0 * inv_logit_0, + (deserializer.read_lub_constrain(-15.0, 15.0, lp))); +} +TEST(deserializer_scalar, read_lub_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = -7.2; + EXPECT_FLOAT_EQ(0.0 + 1.0 * inv_logit_m2, + (deserializer.read_lub_constrain(0.0, 1.0, lp))); + EXPECT_FLOAT_EQ(3.0 + 2.0 * inv_logit_3, + (deserializer.read_lub_constrain(3.0, 5.0, lp))); + EXPECT_FLOAT_EQ(-3.0 + 5.0 * inv_logit_m1, + (deserializer.read_lub_constrain(-3.0, 2.0, lp))); + EXPECT_FLOAT_EQ(-15.0 + 30.0 * inv_logit_0, + (deserializer.read_lub_constrain(-15.0, 15.0, lp))); + double expected_lp = -7.2 + + log((1.0 - 0.0) * inv_logit_m2 * (1 - inv_logit_m2)) + + log((5.0 - 3.0) * inv_logit_3 * (1 - inv_logit_3)) + + log((2.0 - -3.0) * inv_logit_m1 * (1 - inv_logit_m1)) + + log((15.0 - -15.0) * inv_logit_0 * (1 - inv_logit_0)); + EXPECT_FLOAT_EQ(expected_lp, lp); +} + +// var matrix + + +TEST(deserializer_varmat, var_vector) { + using stan::math::var; + using stan::math::var_value; + using var_vec = var_value; + std::vector theta{0, 1, 2, 3, 4}; + std::vector theta_i; + stan::io::deserializer deserializer(theta, theta_i); + auto vec_x = deserializer.read(5); + EXPECT_TRUE((stan::is_var_vector::value)); + for (int i = 0; i < 5; ++i) { + EXPECT_EQ(vec_x.val()(i), i); + } + auto vec_x_empty = deserializer.read(0); + stan::math::recover_memory(); +} + +TEST(deserializer_varmat, var_vector_double) { + using stan::math::var; + using stan::math::var_value; + using var_vec = var_value; + std::vector theta{0, 1, 2, 3, 4}; + std::vector theta_i; + stan::io::deserializer deserializer(theta, theta_i); + auto vec_x = deserializer.read(5); + EXPECT_TRUE( + (stan::is_eigen_vector::value + && std::is_arithmetic>::value)); + for (int i = 0; i < 5; ++i) { + EXPECT_EQ(vec_x.val()(i), i); + } +} + +TEST(deserializer_varmat, var_row_vector) { + using stan::math::var; + using stan::math::var_value; + using var_row_vec = var_value; + std::vector theta{0, 1, 2, 3, 4}; + std::vector theta_i; + stan::io::deserializer deserializer(theta, theta_i); + auto vec_x = deserializer.read(5); + EXPECT_TRUE((stan::is_var_row_vector::value)); + for (int i = 0; i < 5; ++i) { + EXPECT_EQ(vec_x.val()(i), i); + } + auto vec_x_empty = deserializer.read(0); +} + +TEST(deserializer_varmat, var_row_vector_double) { + using stan::math::var; + using stan::math::var_value; + using var_row_vec = var_value; + std::vector theta{0, 1, 2, 3, 4}; + std::vector theta_i; + stan::io::deserializer deserializer(theta, theta_i); + auto vec_x = deserializer.read(5); + EXPECT_TRUE( + (stan::is_eigen_row_vector::value + && std::is_arithmetic>::value)); + for (int i = 0; i < 5; ++i) { + EXPECT_EQ(vec_x.val()(i), i); + } + auto vec_x_empty = deserializer.read(0); +} + +TEST(deserializer_varmat, var_matrix) { + using stan::math::var; + using stan::math::var_value; + using var_matrix = var_value; + std::vector theta{0, 1, 2, 3, 4, 5, 6, 7, 8}; + std::vector theta_i; + stan::io::deserializer deserializer(theta, theta_i); + auto mat_x = deserializer.read(3, 3); + EXPECT_TRUE((stan::is_var_matrix::value)); + for (int i = 0; i < 9; ++i) { + EXPECT_EQ(mat_x.val()(i), i); + } + auto mat_x_empty = deserializer.read(0, 0); +} + +TEST(deserializer_varmat, var_matrix_double) { + using stan::math::var; + using stan::math::var_value; + using var_matrix = var_value; + std::vector theta{0, 1, 2, 3, 4, 5, 6, 7, 8}; + std::vector theta_i; + stan::io::deserializer deserializer(theta, theta_i); + auto mat_x = deserializer.read(3, 3); + EXPECT_TRUE( + (stan::is_eigen_dense_dynamic::value + && std::is_arithmetic>::value)); + for (int i = 0; i < 9; ++i) { + EXPECT_EQ(mat_x.val()(i), i); + } + auto mat_x_empty = deserializer.read(0, 0); +} From 95314942545ffa5adfdcf3b6ed9780f44210e2d3 Mon Sep 17 00:00:00 2001 From: Steve Bronder Date: Tue, 23 Feb 2021 17:23:22 -0500 Subject: [PATCH 05/29] adds tests for matrix deserialization stuff --- lib/stan_math | 2 +- src/stan/io/deserializer.hpp | 884 +++++++++++++++++++------ src/test/unit/io/deserializer_test.cpp | 534 ++++++++++++++- 3 files changed, 1176 insertions(+), 244 deletions(-) diff --git a/lib/stan_math b/lib/stan_math index d829fd60621..dad89bba60e 160000 --- a/lib/stan_math +++ b/lib/stan_math @@ -1 +1 @@ -Subproject commit d829fd60621c2f68b6e4dc0f4be212c3fb6ad725 +Subproject commit dad89bba60e7dbf9a5d10d7698ec745000508579 diff --git a/src/stan/io/deserializer.hpp b/src/stan/io/deserializer.hpp index 0281a69aafd..f14de05de84 100644 --- a/src/stan/io/deserializer.hpp +++ b/src/stan/io/deserializer.hpp @@ -30,227 +30,671 @@ namespace io { */ template class deserializer { -private: - Eigen::Map> data_r_; - Eigen::Map> data_i_; - size_t r_size_{0}; - size_t i_size_{0}; - size_t pos_r_{0}; - size_t pos_i_{0}; - - inline const T &scalar_ptr() { return data_r_.coeffRef(pos_r_); } - - inline const T& scalar_ptr_increment(size_t m) { - pos_r_ += m; - return data_r_.coeffRef(pos_r_ - m); - } - - inline const int &int_ptr() { return data_i_.coeffRef(pos_i_); } - - inline const int &int_ptr_increment(size_t m) { - pos_i_ += m; - return data_i_.coeffRef(pos_i_ - m); - } - void check_r_capacity() const { - if (pos_r_ >= r_size_) { - []() STAN_COLD_PATH { - throw std::runtime_error("no more scalars to read"); - }(); - } - } - - void check_i_capacity() const { - if (pos_i_ >= i_size_) { - []() STAN_COLD_PATH { - throw std::runtime_error("no more integers to read"); - }(); - } - } - -public: - using matrix_t = Eigen::Matrix; - using vector_t = Eigen::Matrix; - using row_vector_t = Eigen::Matrix; - - using map_matrix_t = Eigen::Map; - using map_vector_t = Eigen::Map; - using map_row_vector_t = Eigen::Map; - - using var_matrix_t = stan::math::var_value< - Eigen::Matrix>; - using var_vector_t - = stan::math::var_value>; - using var_row_vector_t - = stan::math::var_value>; - - /** - * Construct a variable reader using the specified vectors - * as the source of scalar and integer values for data. This - * class holds a reference to the specified data vectors. - * - * Attempting to read beyond the end of the data or integer - * value sequences raises a runtime exception. - * - * @param data_r Sequence of scalar values. - * @param data_i Sequence of integer values. - */ - template * = nullptr> - deserializer(RVec& data_r, IntVec& data_i) - : data_r_(data_r.data(), data_r.size()), - data_i_(data_i.data(), data_i.size()), - r_size_(data_r.size()), - i_size_(data_i.size()) {} - - - /** - * Return the number of scalars remaining to be read. - * - * @return Number of scalars left to read. - */ - inline size_t available() const noexcept { return r_size_ - pos_r_; } - - /** - * Return the number of integers remaining to be read. - * - * @return Number of integers left to read. - */ - inline size_t available_i() const noexcept { return i_size_ - pos_i_; } - - template , is_autodiff>* = nullptr> - auto read() { - check_r_capacity(); - return data_r_.coeffRef(pos_r_++); - } - - template * = nullptr> - auto read() { - check_r_capacity(); - return std::complex(data_r_.coeffRef(pos_r_++), data_r_.coeffRef(pos_r_++)); - } - - template * = nullptr> - auto read() { - check_i_capacity(); - return data_i_.coeffRef(pos_i_++); - } - - template * = nullptr> - auto read(Size m) { - if (unlikely(m == 0)) { - return map_vector_t(nullptr, m); - } else { - return map_vector_t(&scalar_ptr_increment(m), m); - } - } - - template * = nullptr> - auto read(Size m) { - if (unlikely(m == 0)) { - return map_row_vector_t(nullptr, m); - } else { - return map_row_vector_t(&scalar_ptr_increment(m), m); - } - } - - template * = nullptr> - auto read(Rows rows, Cols cols) { - if (rows == 0 || cols == 0) { - return map_matrix_t(nullptr, rows, cols); - } else { - return map_matrix_t(&scalar_ptr_increment(rows * cols), rows, cols); - } - } - - template * = nullptr, - require_var_matrix_t* = nullptr> - auto read(Sizes... sizes) { - using value_t = typename Ret::value_type; - return stan::math::to_var_value(this->read(sizes...)); - } - - template * = nullptr, - require_var_matrix_t* = nullptr> - auto read(Sizes... sizes) { - using value_t = typename Ret::value_type; - return this->read(sizes...); - } - - template * = nullptr> - inline auto read(Size m, Sizes... dims) { - if (unlikely(m == 0)) { - return Ret(); - } else { - using ret_value_type = value_type_t; - Ret ret_vec; - ret_vec.reserve(m); - for (Size i = 0; i < m; ++i) { - ret_vec.emplace_back(this->read(dims...)); - } - return ret_vec; - } - } - - template - auto read_lb(const LB& lb, Sizes... sizes) { - using stan::math::check_greater_or_equal; - auto ret = this->read(sizes...); - check_greater_or_equal("io deserializer", "Lower Bound", ret, lb); - return ret; - } - - - template - auto read_lb_constrain(const LB& lb, LP& lp, Sizes... sizes) { - if (Jacobian) { - return stan::math::lb_constrain(this->read(sizes...), lb, lp); - } else { - return stan::math::lb_constrain(this->read(sizes...), lb); - } - } - - template - auto read_ub(const UB& ub, Sizes... sizes) { - using stan::math::check_less_or_equal; - auto ret = this->read(sizes...); - check_less_or_equal("io deserializer", "Upper Bound", ret, ub); - return ret; - } - - - template - auto read_ub_constrain(const UB& ub, LP& lp, Sizes... sizes) { - if (Jacobian) { - return stan::math::ub_constrain(this->read(sizes...), ub, lp); - } else { - return stan::math::ub_constrain(this->read(sizes...), ub); - } - } - - template - auto read_lub(const LB& lb, const UB& ub, Sizes... sizes) { - using stan::math::check_bounded; - auto ret = this->read(sizes...); - check_bounded("io deserializer", "Upper and Lower Bound", ret, lb, ub); - return ret; - } - - - template - auto read_lub_constrain(const LB& lb, const UB& ub, LP& lp, Sizes... sizes) { - if (Jacobian) { - return stan::math::lub_constrain(this->read(sizes...), lb, ub, lp); - } else { - return stan::math::lub_constrain(this->read(sizes...), lb, ub); - } - } - + private: + Eigen::Map> data_r_; + Eigen::Map> data_i_; + size_t r_size_{0}; + size_t i_size_{0}; + size_t pos_r_{0}; + size_t pos_i_{0}; + + inline const T& scalar_ptr() { return data_r_.coeffRef(pos_r_); } + + inline const T& scalar_ptr_increment(size_t m) { + pos_r_ += m; + return data_r_.coeffRef(pos_r_ - m); + } + + inline const int& int_ptr() { return data_i_.coeffRef(pos_i_); } + + inline const int& int_ptr_increment(size_t m) { + pos_i_ += m; + return data_i_.coeffRef(pos_i_ - m); + } + void check_r_capacity() const { + if (pos_r_ >= r_size_) { + []() STAN_COLD_PATH { + throw std::runtime_error("no more scalars to read"); + }(); + } + } + + void check_i_capacity() const { + if (pos_i_ >= i_size_) { + []() STAN_COLD_PATH { + throw std::runtime_error("no more integers to read"); + }(); + } + } + + public: + using matrix_t = Eigen::Matrix; + using vector_t = Eigen::Matrix; + using row_vector_t = Eigen::Matrix; + + using map_matrix_t = Eigen::Map; + using map_vector_t = Eigen::Map; + using map_row_vector_t = Eigen::Map; + + using var_matrix_t = stan::math::var_value< + Eigen::Matrix>; + using var_vector_t + = stan::math::var_value>; + using var_row_vector_t + = stan::math::var_value>; + + /** + * Construct a variable reader using the specified vectors + * as the source of scalar and integer values for data. This + * class holds a reference to the specified data vectors. + * + * Attempting to read beyond the end of the data or integer + * value sequences raises a runtime exception. + * + * @param data_r Sequence of scalar values. + * @param data_i Sequence of integer values. + */ + template * = nullptr> + deserializer(RVec& data_r, IntVec& data_i) + : data_r_(data_r.data(), data_r.size()), + data_i_(data_i.data(), data_i.size()), + r_size_(data_r.size()), + i_size_(data_i.size()) {} + + /** + * Return the number of scalars remaining to be read. + * + * @return Number of scalars left to read. + */ + inline size_t available() const noexcept { return r_size_ - pos_r_; } + + /** + * Return the number of integers remaining to be read. + * + * @return Number of integers left to read. + */ + inline size_t available_i() const noexcept { return i_size_ - pos_i_; } + + template , + is_autodiff>* = nullptr> + auto read() { + check_r_capacity(); + return data_r_.coeffRef(pos_r_++); + } + + template * = nullptr> + auto read() { + check_r_capacity(); + return std::complex(data_r_.coeffRef(pos_r_++), + data_r_.coeffRef(pos_r_++)); + } + + template * = nullptr> + auto read() { + check_i_capacity(); + return data_i_.coeffRef(pos_i_++); + } + + template * = nullptr> + auto read(Size m) { + if (unlikely(m == 0)) { + return map_vector_t(nullptr, m); + } else { + return map_vector_t(&scalar_ptr_increment(m), m); + } + } + + template * = nullptr> + auto read(Size m) { + if (unlikely(m == 0)) { + return map_row_vector_t(nullptr, m); + } else { + return map_row_vector_t(&scalar_ptr_increment(m), m); + } + } + + template * = nullptr> + auto read(Rows rows, Cols cols) { + if (rows == 0 || cols == 0) { + return map_matrix_t(nullptr, rows, cols); + } else { + return map_matrix_t(&scalar_ptr_increment(rows * cols), rows, cols); + } + } + + template * = nullptr, require_var_matrix_t* = nullptr> + auto read(Sizes... sizes) { + using value_t = typename Ret::value_type; + return stan::math::to_var_value(this->read(sizes...)); + } + + template * = nullptr, + require_var_matrix_t* = nullptr> + auto read(Sizes... sizes) { + using value_t = typename Ret::value_type; + return this->read(sizes...); + } + + template * = nullptr> + inline auto read(Size m, Sizes... dims) { + if (unlikely(m == 0)) { + return Ret(); + } else { + using ret_value_type = value_type_t; + Ret ret_vec; + ret_vec.reserve(m); + for (Size i = 0; i < m; ++i) { + ret_vec.emplace_back(this->read(dims...)); + } + return ret_vec; + } + } + + template + auto read_lb(const LB& lb, Sizes... sizes) { + using stan::math::check_greater_or_equal; + auto ret = this->read(sizes...); + check_greater_or_equal("io deserializer", "Lower Bound", ret, lb); + return ret; + } + + template + auto read_lb_constrain(const LB& lb, LP& lp, Sizes... sizes) { + if (Jacobian) { + return stan::math::lb_constrain(this->read(sizes...), lb, lp); + } else { + return stan::math::lb_constrain(this->read(sizes...), lb); + } + } + + template + auto read_ub(const UB& ub, Sizes... sizes) { + using stan::math::check_less_or_equal; + auto ret = this->read(sizes...); + check_less_or_equal("io deserializer", "Upper Bound", ret, ub); + return ret; + } + + template + auto read_ub_constrain(const UB& ub, LP& lp, Sizes... sizes) { + if (Jacobian) { + return stan::math::ub_constrain(this->read(sizes...), ub, lp); + } else { + return stan::math::ub_constrain(this->read(sizes...), ub); + } + } + + template + auto read_lub(const LB& lb, const UB& ub, Sizes... sizes) { + using stan::math::check_bounded; + auto ret = this->read(sizes...); + check_bounded("io deserializer", "Upper and Lower Bound", ret, + lb, ub); + return ret; + } + + template + auto read_lub_constrain(const LB& lb, const UB& ub, LP& lp, Sizes... sizes) { + if (Jacobian) { + return stan::math::lub_constrain(this->read(sizes...), lb, ub, lp); + } else { + return stan::math::lub_constrain(this->read(sizes...), lb, ub); + } + } + + template + auto read_pos(const Sizes&... sizes) { + auto ret = read(sizes...); + stan::math::check_positive("stan::io::deserializer", "Positive Constrained", + ret); + return ret; + } + template * = nullptr> + auto read_pos(LP& lp, const Sizes&... sizes) { + if (Jacobian) { + return stan::math::positive_constrain(this->read(sizes...), lp); + } else { + return stan::math::positive_constrain(this->read(sizes...)); + } + } + + template * = nullptr> + auto read_pos(LP& lp, const size_t vecsize, const Sizes&... sizes) { + using stan::math::positive_constrain; + using ret_value_t = value_type_t; + std::decay_t ret; + for (size_t i = 0; i < vecsize; ++i) { + ret.emplace_back(this->read_pos(lp, sizes...)); + } + return ret; + } + + template + auto read_offset_multiplier(const Offset& offset, const Mult& multiplier, + const Sizes&... sizes) { + return read(sizes...); + } + + template * = nullptr> + auto read_offset_multiplier(const Offset& offset, const Mult& multiplier, LP& lp, + const Sizes&... sizes) { + using stan::math::offset_multiplier_constrain; + if (Jacobian) { + return offset_multiplier_constrain(this->read(sizes...), offset, + multiplier, lp); + } else { + return offset_multiplier_constrain(this->read(sizes...), offset, + multiplier); + } + } + + template * = nullptr> + auto read_offset_multiplier(const Offset& offset, const Mult& multiplier, + LP& lp, const size_t vecsize, + const Sizes&... sizes) { + using stan::math::offset_multiplier_constrain; + using ret_value_t = value_type_t; + std::decay_t ret; + for (size_t i = 0; i < vecsize; ++i) { + ret.emplace_back(this->read_offset_multiplier( + offset, multiplier, lp, sizes...)); + } + return ret; + } + + template + auto read_prob(const Sizes&... sizes) { + auto ret = read(sizes...); + stan::math::check_bounded( + "stan::io::deserializer", "Constrained probability", ret, 0, 1); + return ret; + } + template * = nullptr> + auto read_prob(LP& lp, const Sizes&... sizes) { + if (Jacobian) { + return stan::math::prob_constrain(this->read(sizes...), lp); + } else { + return stan::math::prob_constrain(this->read(sizes...)); + } + } + + template * = nullptr> + auto read_prob(LP& lp, const size_t vecsize, const Sizes&... sizes) { + using stan::math::prob_constrain; + using ret_value_t = value_type_t; + std::decay_t ret; + for (size_t i = 0; i < vecsize; ++i) { + ret.emplace_back(this->read_prob(lp, sizes...)); + } + return ret; + } + + template * = nullptr> + auto read_corr(const Sizes&... sizes) { + auto ret = read(sizes...); + stan::math::check_bounded( + "stan::io::deserializer", "Correlation value", ret, -1, 1); + return ret; + } + + template * = nullptr> + auto read_corr(size_t k) { + using stan::math::check_corr_matrix; + auto ret = read(k, k); + check_corr_matrix("stan::math::corr_matrix", "Constrained matrix", ret); + return ret; + } + + template * = nullptr, + require_not_matrix_t* = nullptr> + auto read_corr(LP& lp, const Sizes&... sizes) { + using stan::math::corr_constrain; + if (Jacobian) { + return corr_constrain(this->read(sizes...), lp); + } else { + return corr_constrain(this->read(sizes...)); + } + } + + template * = nullptr, + require_matrix_t* = nullptr> + auto read_corr(LP& lp, size_t k) { + using stan::math::corr_matrix_constrain; + if (Jacobian) { + return corr_matrix_constrain(this->read((k * (k - 1)) / 2), k, + lp); + } else { + return corr_matrix_constrain(this->read((k * (k - 1)) / 2), k); + } + } + + template * = nullptr> + auto read_corr(LP& lp, const size_t vecsize, const Sizes&... sizes) { + using ret_value_t = value_type_t; + std::decay_t ret; + for (size_t i = 0; i < vecsize; ++i) { + ret.emplace_back(this->read_corr(lp, sizes...)); + } + return ret; + } + + template * = nullptr> + auto read_unit_vector(size_t k) { + if (unlikely(k == 0)) { + std::string msg = "deserializer: unit vectors cannot be size 0."; + throw std::invalid_argument(msg); + } + auto ret = read(k); + stan::math::check_unit_vector("stan::io::deserializer", "Unit Vector", ret); + return ret; + } + + template * = nullptr> + auto read_unit_vector(size_t vecsize, Sizes... sizes) { + using ret_value_t = value_type_t; + std::decay_t ret; + for (size_t i = 0; i < vecsize; ++i) { + ret.emplace_back(this->read_unit_vector(sizes...)); + } + return ret; + } + + template * = nullptr> + auto read_unit_vector(LP& lp, const Sizes&... sizes) { + using stan::math::unit_vector_constrain; + if (Jacobian) { + return unit_vector_constrain(this->read(sizes...), lp); + } else { + return unit_vector_constrain(this->read(sizes...)); + } + } + + template * = nullptr> + auto read_unit_vector(LP& lp, const size_t vecsize, const Sizes&... sizes) { + using stan::math::unit_vector_constrain; + using ret_value_t = value_type_t; + std::decay_t ret; + for (size_t i = 0; i < vecsize; ++i) { + ret.emplace_back( + this->read_unit_vector(lp, sizes...)); + } + return ret; + } + + template * = nullptr> + auto read_simplex(size_t k) { + if (unlikely(k == 0)) { + std::string msg = "deserializer: simplex vectors cannot be size 0."; + throw std::invalid_argument(msg); + } + auto ret = read(k); + stan::math::check_simplex("stan::io::deserializer", "Simplex", ret); + return ret; + } + + template * = nullptr> + auto read_simplex(size_t vecsize, Sizes... sizes) { + using ret_value_t = value_type_t; + std::decay_t ret; + for (size_t i = 0; i < vecsize; ++i) { + ret.emplace_back(this->read_simplex(sizes...)); + } + return ret; + } + + template * = nullptr> + auto read_simplex(LP& lp, const Sizes&... sizes) { + using stan::math::simplex_constrain; + if (Jacobian) { + return simplex_constrain(this->read(sizes...), lp); + } else { + return simplex_constrain(this->read(sizes...)); + } + } + + template * = nullptr> + auto read_simplex(LP& lp, const size_t vecsize, const Sizes&... sizes) { + using stan::math::simplex_constrain; + using ret_value_t = value_type_t; + std::decay_t ret; + for (size_t i = 0; i < vecsize; ++i) { + ret.emplace_back(this->read_simplex(lp, sizes...)); + } + return ret; + } + + template + auto read_ordered(const Sizes&... sizes) { + using stan::math::check_ordered; + auto ret = read(sizes...); + check_ordered("stan::io::deserializer", "Ordered", ret); + return ret; + } + + template * = nullptr> + auto read_ordered(LP& lp, const Sizes&... sizes) { + using stan::math::ordered_constrain; + if (Jacobian) { + return ordered_constrain(this->read(sizes...), lp); + } else { + return ordered_constrain(this->read(sizes...)); + } + } + + template * = nullptr> + auto read_ordered(LP& lp, const size_t vecsize, const Sizes&... sizes) { + using stan::math::ordered_constrain; + using ret_value_t = value_type_t; + std::decay_t ret; + for (size_t i = 0; i < vecsize; ++i) { + ret.emplace_back(this->read_ordered(lp, sizes...)); + } + return ret; + } + + template + auto read_positive_ordered(const Sizes&... sizes) { + using stan::math::check_positive_ordered; + auto ret = read(sizes...); + check_positive_ordered("stan::io::deserializer", "Positive Ordered", ret); + return ret; + } + + template * = nullptr> + auto read_positive_ordered(LP& lp, const Sizes&... sizes) { + using stan::math::positive_ordered_constrain; + if (Jacobian) { + return positive_ordered_constrain(this->read(sizes...), lp); + } else { + return positive_ordered_constrain(this->read(sizes...)); + } + } + + template * = nullptr> + auto read_positive_ordered(LP& lp, const size_t vecsize, + const Sizes&... sizes) { + using stan::math::positive_ordered_constrain; + using ret_value_t = value_type_t; + std::decay_t ret; + for (size_t i = 0; i < vecsize; ++i) { + ret.emplace_back( + this->read_positive_ordered(lp, sizes...)); + } + return ret; + } + + template * = nullptr> + auto read_cholesky_factor_cov(size_t M, size_t N) { + using stan::math::check_cholesky_factor; + auto ret = read(M, N); + check_cholesky_factor("stan::io::deserializer", "Cholesky Factor Cov", ret); + return ret; + } + + template * = nullptr> + auto read_cholesky_factor_cov(size_t vecsize, Sizes... sizes) { + using ret_value_t = value_type_t; + std::decay_t ret; + for (size_t i = 0; i < vecsize; ++i) { + ret.emplace_back(this->read_cholesky_factor_cov(sizes...)); + } + return ret; + } + + template * = nullptr> + auto read_cholesky_factor_cov(LP& lp, size_t M, size_t N) { + if (Jacobian) { + return stan::math::cholesky_factor_constrain( + this->read((N * (N + 1)) / 2 + (M - N) * N), M, N, lp); + } else { + return stan::math::cholesky_factor_constrain( + this->read((N * (N + 1)) / 2 + (M - N) * N), M, N); + } + } + + template * = nullptr> + auto read_cholesky_factor_cov(LP& lp, const size_t vecsize, + const Sizes&... sizes) { + using ret_value_t = value_type_t; + std::decay_t ret; + for (size_t i = 0; i < vecsize; ++i) { + ret.emplace_back( + this->read_cholesky_factor_cov(lp, sizes...)); + } + return ret; + } + + // SDF + + template * = nullptr> + auto read_cholesky_factor_corr(size_t M, size_t N) { + using stan::math::check_cholesky_factor; + auto ret = read(M, N); + check_cholesky_factor_corr("stan::io::cholesky_factor_corr", + "Constrained matrix", ret); + return ret; + } + + template * = nullptr> + auto read_cholesky_factor_corr(size_t vecsize, Sizes... sizes) { + using ret_value_t = value_type_t; + std::decay_t ret; + for (size_t i = 0; i < vecsize; ++i) { + ret.emplace_back(this->read_cholesky_factor_corr(sizes...)); + } + return ret; + } + + template * = nullptr> + auto read_cholesky_factor_corr(LP& lp, size_t K) { + using stan::math::cholesky_corr_constrain; + if (Jacobian) { + return cholesky_corr_constrain(this->read((K * (K - 1)) / 2), K, + lp); + } else { + return cholesky_corr_constrain(this->read((K * (K - 1)) / 2), + K); + } + } + + template * = nullptr> + auto read_cholesky_factor_corr(LP& lp, const size_t vecsize, + const Sizes&... sizes) { + using ret_value_t = value_type_t; + std::decay_t ret; + for (size_t i = 0; i < vecsize; ++i) { + ret.emplace_back( + this->read_cholesky_factor_corr(lp, sizes...)); + } + return ret; + } + + // cov matrix + + template * = nullptr> + auto read_cov_matrix(size_t k) { + using stan::math::check_cov_matrix; + auto ret = read(k, k); + check_cov_matrix("stan::io::cov_matrix", "Constrained matrix", ret); + return ret; + } + + template * = nullptr> + auto read_cov_matrix(size_t vecsize, Sizes... sizes) { + using ret_value_t = value_type_t; + std::decay_t ret; + for (size_t i = 0; i < vecsize; ++i) { + ret.emplace_back(this->read_cholesky_factor_corr(sizes...)); + } + return ret; + } + + template * = nullptr> + auto read_cov_matrix(LP& lp, size_t k) { + using stan::math::cov_matrix_constrain; + if (Jacobian) { + return cov_matrix_constrain(this->read(k + (k * (k - 1)) / 2), + k, lp); + } else { + return cov_matrix_constrain(this->read(k + (k * (k - 1)) / 2), + k); + } + } + + template * = nullptr> + auto read_cov_matrix(LP& lp, const size_t vecsize, const Sizes&... sizes) { + using ret_value_t = value_type_t; + std::decay_t ret; + for (size_t i = 0; i < vecsize; ++i) { + ret.emplace_back( + this->read_cov_matrix(lp, sizes...)); + } + return ret; + } }; - -} -} +} // namespace io +} // namespace stan #endif diff --git a/src/test/unit/io/deserializer_test.cpp b/src/test/unit/io/deserializer_test.cpp index 3e3ef9d4ede..c9c3f87785d 100644 --- a/src/test/unit/io/deserializer_test.cpp +++ b/src/test/unit/io/deserializer_test.cpp @@ -46,29 +46,6 @@ TEST(deserializer_scalar, read) { EXPECT_EQ(0U, deserializer.available()); } -TEST(deserializer_vector, read) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100U; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - for (size_t i = 0; i < 7U; ++i) { - double x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - Eigen::Matrix y = deserializer.read(4); - EXPECT_EQ(4, y.rows()); - EXPECT_EQ(1, y.cols()); - EXPECT_EQ(4, y.size()); - EXPECT_FLOAT_EQ(7.0, y[0]); - EXPECT_FLOAT_EQ(8.0, y[1]); - EXPECT_FLOAT_EQ(9.0, y[2]); - EXPECT_FLOAT_EQ(10.0, y[3]); - - double z = deserializer.read(); - EXPECT_FLOAT_EQ(11.0, z); -} - TEST(deserializer_rowvector, read) { std::vector theta_i; std::vector theta; @@ -313,6 +290,517 @@ TEST(deserializer_scalar, read_lub_constrain_jacobian) { EXPECT_FLOAT_EQ(expected_lp, lp); } +// offset multiplier + +TEST(deserializer_scalar, read_offset_multiplier) { + std::vector theta_i; + std::vector theta; + theta.push_back(-1.0); + theta.push_back(2.0); + stan::io::deserializer deserializer(theta, theta_i); + double x = deserializer.read_offset_multiplier(-3.0, 3.0); + EXPECT_FLOAT_EQ(-1.0, x); + double y = deserializer.read_offset_multiplier(-3.0, 3.0); + EXPECT_FLOAT_EQ(2.0, y); + + EXPECT_EQ(0U, deserializer.available()); +} +TEST(deserializer_scalar, offset_multiplier_exception) { + std::vector theta_i; + std::vector theta; + theta.push_back(-1.0); + theta.push_back(2.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0; + EXPECT_NO_THROW(deserializer.read_offset_multiplier(-2.0, -2.0)); + EXPECT_THROW((deserializer.read_offset_multiplier(-2.0, -2.0, lp)), + std::domain_error); +} + +TEST(deserializer_scalar, offset_multiplier_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0; + EXPECT_FLOAT_EQ(-2.0, (deserializer.read_offset_multiplier(0.0, 1.0, lp))); + EXPECT_FLOAT_EQ(3.0 + 5.0 * 3.0, + (deserializer.read_offset_multiplier(3.0, 5.0, lp))); + EXPECT_FLOAT_EQ(-3.0 + 2.0 * -1.0, + (deserializer.read_offset_multiplier(-3.0, 2.0, lp))); + EXPECT_FLOAT_EQ(-15.0, + (deserializer.read_offset_multiplier(-15.0, 15.0, lp))); +} +TEST(deserializer_scalar, offset_multiplier_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = -7.2; + EXPECT_FLOAT_EQ(-2.0, + (deserializer.read_offset_multiplier(0.0, 1.0, lp))); + EXPECT_FLOAT_EQ(3.0 + 5.0 * 3.0, + (deserializer.read_offset_multiplier(3.0, 5.0, lp))); + EXPECT_FLOAT_EQ(-3.0 + 2.0 * -1.0, + (deserializer.read_offset_multiplier(-3.0, 2.0, lp))); + EXPECT_FLOAT_EQ(-15.0, + (deserializer.read_offset_multiplier(-15.0, 15.0, lp))); + double expected_lp = -7.2 + log(1.0) + log(5.0) + log(2.0) + log(15.0); + EXPECT_FLOAT_EQ(expected_lp, lp); +} + +// prob + +TEST(deserializer_scalar, prob) { + std::vector theta_i; + std::vector theta; + theta.push_back(0.9); + theta.push_back(0.1); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double p1 = deserializer.read_prob(); + EXPECT_FLOAT_EQ(0.9, p1); + double p2 = deserializer.read_prob(); + EXPECT_FLOAT_EQ(0.1, p2); + double p3 = deserializer.read_prob(); + EXPECT_FLOAT_EQ(0.0, p3); + + EXPECT_EQ(0U, deserializer.available()); +} +TEST(deserializer_scalar, prob_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0; + EXPECT_FLOAT_EQ(inv_logit_m2, (deserializer.read_prob(lp))); + EXPECT_FLOAT_EQ(inv_logit_3, (deserializer.read_prob(lp))); + EXPECT_FLOAT_EQ(inv_logit_m1, (deserializer.read_prob(lp))); + EXPECT_FLOAT_EQ(inv_logit_0, (deserializer.read_prob(lp))); +} +TEST(deserializer_scalar, prob_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = -0.88; + EXPECT_FLOAT_EQ(inv_logit_m2, (deserializer.read_prob(lp))); + EXPECT_FLOAT_EQ(inv_logit_3, (deserializer.read_prob(lp))); + EXPECT_FLOAT_EQ(inv_logit_m1, (deserializer.read_prob(lp))); + EXPECT_FLOAT_EQ(inv_logit_0, (deserializer.read_prob(lp))); + double expected_lp = -0.88 + log(inv_logit_m2 * (1.0 - inv_logit_m2)) + + log(inv_logit_3 * (1.0 - inv_logit_3)) + + log(inv_logit_m1 * (1.0 - inv_logit_m1)) + + log(inv_logit_0 * (1.0 - inv_logit_0)); + EXPECT_FLOAT_EQ(expected_lp, lp); +} + +// corr + +TEST(deserializer_scalar, corr) { + std::vector theta_i; + std::vector theta; + theta.push_back(-0.9); + theta.push_back(0.1); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double rho1 = deserializer.read_corr(); + EXPECT_FLOAT_EQ(-0.9, rho1); + double rho2 = deserializer.read_corr(); + EXPECT_FLOAT_EQ(0.1, rho2); + double rho3 = deserializer.read_corr(); + EXPECT_FLOAT_EQ(0.0, rho3); + + EXPECT_EQ(0U, deserializer.available()); +} +TEST(deserializer_scalar, corr_exception) { + std::vector theta_i; + std::vector theta; + theta.push_back(-0.9); + theta.push_back(-1.1); + theta.push_back(1.1); + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_NO_THROW(deserializer.read_corr()); + EXPECT_THROW(deserializer.read_corr(), std::domain_error); + EXPECT_THROW(deserializer.read_corr(), std::domain_error); +} +TEST(deserializer_scalar, corr_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0; + EXPECT_FLOAT_EQ(tanh(-2.0), (deserializer.read_corr(lp))); + EXPECT_FLOAT_EQ(tanh(3.0), (deserializer.read_corr(lp))); + EXPECT_FLOAT_EQ(tanh(-1.0), (deserializer.read_corr(lp))); + EXPECT_FLOAT_EQ(tanh(0.0), (deserializer.read_corr(lp))); +} +TEST(deserializer_scalar, corr_constrain_jacobian) { + using std::tanh; + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = -10.0; + EXPECT_FLOAT_EQ(tanh(-2.0), (deserializer.read_corr(lp))); + EXPECT_FLOAT_EQ(tanh(3.0), (deserializer.read_corr(lp))); + EXPECT_FLOAT_EQ(tanh(-1.0), (deserializer.read_corr(lp))); + EXPECT_FLOAT_EQ(tanh(0.0), (deserializer.read_corr(lp))); + double expected_lp = -10.0 + log(1.0 - tanh(-2.0) * tanh(-2.0)) + + log(1.0 - tanh(3.0) * tanh(3.0)) + + log(1.0 - tanh(-1.0) * tanh(-1.0)) + + log(1.0 - tanh(0.0) * tanh(0.0)); + EXPECT_FLOAT_EQ(expected_lp, lp); +} + +// vectors + +TEST(deserializer_vector, read) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100U; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (size_t i = 0; i < 7U; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + Eigen::Matrix y = deserializer.read(4); + EXPECT_EQ(4, y.rows()); + EXPECT_EQ(1, y.cols()); + EXPECT_EQ(4, y.size()); + EXPECT_FLOAT_EQ(7.0, y[0]); + EXPECT_FLOAT_EQ(8.0, y[1]); + EXPECT_FLOAT_EQ(9.0, y[2]); + EXPECT_FLOAT_EQ(10.0, y[3]); + + double z = deserializer.read(); + EXPECT_FLOAT_EQ(11.0, z); +} + +TEST(deserializer_vector, unit_vector) { + std::vector theta_i(0); + std::vector theta(4, sqrt(0.25)); + stan::io::deserializer deserializer(theta, theta_i); + Eigen::VectorXd y = deserializer.read_unit_vector(4); + EXPECT_EQ(4, y.size()); + EXPECT_FLOAT_EQ(sqrt(0.25), y[0]); + EXPECT_FLOAT_EQ(sqrt(0.25), y[1]); + EXPECT_FLOAT_EQ(sqrt(0.25), y[2]); + EXPECT_FLOAT_EQ(sqrt(0.25), y[3]); +} + +TEST(deserializer_vector, unit_vector_exception) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + theta[0] = 0.00; + theta[1] = -sqrt(0.29); + theta[2] = sqrt(0.70); + theta[3] = -sqrt(0.01); + theta[4] = sqrt(1.0); + theta[5] = sqrt(1.0); + EXPECT_NO_THROW(deserializer.read_unit_vector(4)); + EXPECT_THROW(deserializer.read_unit_vector(2), std::domain_error); + EXPECT_THROW(deserializer.read_unit_vector(0), std::invalid_argument); +} + +TEST(deserializer_vector, simplex) { + std::vector theta_i(0); + std::vector theta(4, 0.25); + stan::io::deserializer deserializer(theta, theta_i); + Eigen::Matrix y = deserializer.read_simplex(4); + EXPECT_EQ(4, y.size()); + EXPECT_FLOAT_EQ(0.25, y[0]); + EXPECT_FLOAT_EQ(0.25, y[1]); + EXPECT_FLOAT_EQ(0.25, y[2]); + EXPECT_FLOAT_EQ(0.25, y[3]); +} +TEST(deserializer_vector, simplex_exception) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + theta[0] = 0.00; + theta[1] = 0.29; + theta[2] = 0.70; + theta[3] = 0.01; + theta[4] = 1.0; + theta[5] = 1.0; + EXPECT_NO_THROW(deserializer.read_simplex(4)); + EXPECT_THROW(deserializer.read_simplex(2), std::domain_error); + EXPECT_THROW(deserializer.read_simplex(0), std::invalid_argument); +} + +TEST(deserializer_vector, ordered) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_FLOAT_EQ(0.0, deserializer.read()); // throw away theta[0] + Eigen::Matrix y = deserializer.read_ordered(5); + EXPECT_EQ(5, y.size()); + EXPECT_FLOAT_EQ(1.0, y[0]); + EXPECT_FLOAT_EQ(2.0, y[1]); + EXPECT_FLOAT_EQ(5.0, y[4]); + EXPECT_FLOAT_EQ(6.0, deserializer.read()); +} +TEST(deserializer_vector, ordered_exception) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_FLOAT_EQ(0.0, deserializer.read()); // throw away theta[0] + Eigen::Matrix y = deserializer.read_ordered(5); + EXPECT_EQ(5, y.size()); + EXPECT_FLOAT_EQ(1.0, y[0]); + EXPECT_FLOAT_EQ(2.0, y[1]); + EXPECT_FLOAT_EQ(5.0, y[4]); + EXPECT_FLOAT_EQ(6.0, deserializer.read()); +} +TEST(deserializer_vector, ordered_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + double v0 = 3.0; + double v1 = v0 + exp(-1.0); + double v2 = v1 + exp(-2.0); + double v3 = v2 + exp(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0; + Eigen::Matrix phi(deserializer.read_ordered(lp, 4)); + EXPECT_FLOAT_EQ(v0, phi[0]); + EXPECT_FLOAT_EQ(v1, phi[1]); + EXPECT_FLOAT_EQ(v2, phi[2]); + EXPECT_FLOAT_EQ(v3, phi[3]); +} +TEST(deserializer_vector, ordered_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + double v0 = 3.0; + double v1 = v0 + exp(-1.0); + double v2 = v1 + exp(-2.0); + double v3 = v2 + exp(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = -101.1; + double expected_lp = lp - 1.0 - 2.0 + 0.0; + Eigen::Matrix phi(deserializer.read_ordered(lp, 4)); + EXPECT_FLOAT_EQ(v0, phi[0]); + EXPECT_FLOAT_EQ(v1, phi[1]); + EXPECT_FLOAT_EQ(v2, phi[2]); + EXPECT_FLOAT_EQ(v3, phi[3]); + EXPECT_FLOAT_EQ(expected_lp, lp); +} + +TEST(deserializer_vector, positive_ordered) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_FLOAT_EQ(0.0, deserializer.read()); // throw away theta[0] + Eigen::Matrix y = deserializer.read_positive_ordered(5); + EXPECT_EQ(5, y.size()); + EXPECT_FLOAT_EQ(1.0, y[0]); + EXPECT_FLOAT_EQ(2.0, y[1]); + EXPECT_FLOAT_EQ(5.0, y[4]); + EXPECT_FLOAT_EQ(6.0, deserializer.read()); +} + +TEST(deserializer_vector, positive_ordered_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + double v0 = exp(3.0); + double v1 = v0 + exp(-1.0); + double v2 = v1 + exp(-2.0); + double v3 = v2 + exp(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0; + Eigen::Matrix phi( + deserializer.read_positive_ordered(lp, 4)); + EXPECT_FLOAT_EQ(v0, phi[0]); + EXPECT_FLOAT_EQ(v1, phi[1]); + EXPECT_FLOAT_EQ(v2, phi[2]); + EXPECT_FLOAT_EQ(v3, phi[3]); +} + +TEST(deserializer_vector, positive_ordered_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + double v0 = exp(3.0); + double v1 = v0 + exp(-1.0); + double v2 = v1 + exp(-2.0); + double v3 = v2 + exp(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = -101.1; + double expected_lp = lp + 3.0 - 1.0 - 2.0 + 0.0; + Eigen::Matrix phi( + deserializer.read_positive_ordered(lp, 4)); + EXPECT_FLOAT_EQ(v0, phi[0]); + EXPECT_FLOAT_EQ(v1, phi[1]); + EXPECT_FLOAT_EQ(v2, phi[2]); + EXPECT_FLOAT_EQ(v3, phi[3]); + EXPECT_FLOAT_EQ(expected_lp, lp); +} + +// matrix + +TEST(deserializer_matrix, read) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (int i = 0; i < 7; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + using eig_mat = Eigen::Matrix; + eig_mat y = deserializer.read(3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(7.0, y(0, 0)); + EXPECT_FLOAT_EQ(8.0, y(1, 0)); + EXPECT_FLOAT_EQ(9.0, y(2, 0)); + EXPECT_FLOAT_EQ(10.0, y(0, 1)); + EXPECT_FLOAT_EQ(11.0, y(1, 1)); + EXPECT_FLOAT_EQ(12.0, y(2, 1)); + + double a = deserializer.read(); + EXPECT_FLOAT_EQ(13.0, a); +} + + +TEST(deserializer_matrix, corr_matrix) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + theta[0] = 1.0000000000000000; + theta[1] = 0.1817621852191252; + theta[2] = 0.8620926037637362; + theta[3] = 0.1817621852191252; + theta[4] = 1.0000000000000000; + theta[5] = 0.2248293054822660; + theta[6] = 0.8620926037637362; + theta[7] = 0.2248293054822660; + theta[8] = 1.0000000000000001; // allow some tolerance + stan::io::deserializer deserializer(theta, theta_i); + Eigen::Matrix S + = deserializer.read_corr(3); + EXPECT_FLOAT_EQ(theta[0], S(0, 0)); +} +TEST(deserializer_matrix, corr_matrix_exception) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + theta[0] = 1.5; + theta[1] = 1.0; + theta[2] = 2.0; + theta[3] = 0.0; + theta[4] = 1.0; + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_THROW(deserializer.read_corr(1), std::domain_error); + EXPECT_THROW(deserializer.read_corr(2), std::domain_error); +} +TEST(deserializer_matrix, corr_matrix_constrain) { + using Eigen::Dynamic; + using Eigen::Matrix; + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(-1.0); + theta.push_back(0.0); + theta.push_back(0.5); + theta.push_back(1.0); + theta.push_back(2.0); + theta.push_back(1.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0; + Matrix R(deserializer.read_corr(lp, 3U)); + EXPECT_EQ(3, R.rows()); + EXPECT_EQ(3, R.cols()); + EXPECT_EQ(9, R.size()); + EXPECT_EQ(4U, deserializer.available()); + for (size_t i = 0; i < 3U; ++i) { + EXPECT_FLOAT_EQ(1.0, R(i, i)); + for (size_t j = i + 1; j < 3U; ++j) + EXPECT_FLOAT_EQ(R(i, j), R(j, i)); + } + Eigen::SelfAdjointEigenSolver< + Eigen::Matrix> + solver(R, Eigen::EigenvaluesOnly); + assert(solver.eigenvalues()[0] > 1E-10); +} +TEST(deserializer_matrix, corr_matrix_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(-1.0); + theta.push_back(0.0); + theta.push_back(0.5); + theta.push_back(1.0); + theta.push_back(2.0); + theta.push_back(1.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = -9.2; + Eigen::Matrix R( + deserializer.read_corr(lp, 3U)); + EXPECT_EQ(3, R.rows()); + EXPECT_EQ(3, R.cols()); + EXPECT_EQ(9, R.size()); + EXPECT_EQ(4U, deserializer.available()); + for (size_t i = 0; i < 3U; ++i) { + EXPECT_FLOAT_EQ(1.0, R(i, i)); + for (size_t j = i + 1; j < 3U; ++j) + EXPECT_FLOAT_EQ(R(i, j), R(j, i)); + } + Eigen::SelfAdjointEigenSolver< + Eigen::Matrix> + solver(R, Eigen::EigenvaluesOnly); + assert(solver.eigenvalues()[0] > 1E-10); + // FIXME: test jacobian +} + // var matrix From 1f9caf07ed7638d4fc2d06172a7ab5c54ac8377e Mon Sep 17 00:00:00 2001 From: Steve Bronder Date: Tue, 23 Feb 2021 19:14:13 -0500 Subject: [PATCH 06/29] start adding docs for deserializer --- src/stan/io/deserializer.hpp | 263 +++++++++-- src/test/unit/io/deserializer_test.cpp | 620 +++++++++++++++++++++++-- 2 files changed, 821 insertions(+), 62 deletions(-) diff --git a/src/stan/io/deserializer.hpp b/src/stan/io/deserializer.hpp index f14de05de84..6dcc2199a97 100644 --- a/src/stan/io/deserializer.hpp +++ b/src/stan/io/deserializer.hpp @@ -31,26 +31,42 @@ namespace io { template class deserializer { private: - Eigen::Map> data_r_; - Eigen::Map> data_i_; - size_t r_size_{0}; - size_t i_size_{0}; - size_t pos_r_{0}; - size_t pos_i_{0}; - - inline const T& scalar_ptr() { return data_r_.coeffRef(pos_r_); } + Eigen::Map> data_r_; // map of reals. + Eigen::Map> data_i_; // map of integers. + size_t r_size_{0}; // size of reals available. + size_t i_size_{0}; // size of integers available. + size_t pos_r_{0}; // current position in map of reals. + size_t pos_i_{0}; // current position in map of integers. + /** + * Return pointer to current scalar. + */ + inline T& scalar_ptr() { return data_r_.coeffRef(pos_r_); } - inline const T& scalar_ptr_increment(size_t m) { + /** + * Return pointer to current scalar and incriment the internal counter. + * @param m amount to move `pos_r_` up. + */ + inline T& scalar_ptr_increment(size_t m) { pos_r_ += m; return data_r_.coeffRef(pos_r_ - m); } - inline const int& int_ptr() { return data_i_.coeffRef(pos_i_); } + /** + * Return pointer to current integer. + */ + inline int& int_ptr() { return data_i_.coeffRef(pos_i_); } - inline const int& int_ptr_increment(size_t m) { + /** + * Return pointer to current integer and incriment the internal counter. + * @param m amount to move `pos_i_` up. + */ + inline int& int_ptr_increment(size_t m) { pos_i_ += m; return data_i_.coeffRef(pos_i_ - m); } + /** + * The that there is anything left to read for scalars. + */ void check_r_capacity() const { if (pos_r_ >= r_size_) { []() STAN_COLD_PATH { @@ -59,6 +75,9 @@ class deserializer { } } + /** + * The that there is anything left to read for integers. + */ void check_i_capacity() const { if (pos_i_ >= i_size_) { []() STAN_COLD_PATH { @@ -116,6 +135,11 @@ class deserializer { */ inline size_t available_i() const noexcept { return i_size_ - pos_i_; } + /** + * Return the next scalar in the sequence. + * + * @return Next scalar value. + */ template , is_autodiff>* = nullptr> auto read() { @@ -130,14 +154,24 @@ class deserializer { data_r_.coeffRef(pos_r_++)); } + /** + * Return the next integer in the integer sequence. + * + * @return Next integer value. + */ template * = nullptr> auto read() { check_i_capacity(); return data_i_.coeffRef(pos_i_++); } + /** + * Return an Eigen column vector of size `m`. + * @tparam Ret The type to return. + */ template * = nullptr> + require_eigen_col_vector_t* = nullptr, + require_not_vt_complex* = nullptr> auto read(Size m) { if (unlikely(m == 0)) { return map_vector_t(nullptr, m); @@ -146,8 +180,32 @@ class deserializer { } } + /** + * Return an Eigen column vector of size `m` with inner complex type. + * @tparam Ret The type to return. + */ + template * = nullptr, + require_vt_complex* = nullptr> + auto read(Size m) { + if (unlikely(m == 0)) { + return Ret(map_vector_t(nullptr, m)); + } else { + Ret ret(m); + for (Eigen::Index i = 0; i < m; ++i) { + ret.coeffRef(i) = std::complex(data_r_.coeffRef(pos_r_++), + data_r_.coeffRef(pos_r_++)); + } + } + } + + /** + * Return an Eigen row vector of size `m`. + * @tparam Ret The type to return. + */ template * = nullptr> + require_eigen_row_vector_t* = nullptr, + require_not_vt_complex* = nullptr> auto read(Size m) { if (unlikely(m == 0)) { return map_row_vector_t(nullptr, m); @@ -156,8 +214,32 @@ class deserializer { } } + /** + * Return an Eigen row vector of size `m` with inner complex type. + * @tparam Ret The type to return. + */ + template * = nullptr, + require_vt_complex* = nullptr> + auto read(Size m) { + if (unlikely(m == 0)) { + return Ret(map_row_vector_t(nullptr, m)); + } else { + Ret ret(m); + for (Eigen::Index i = 0; i < m; ++i) { + ret.coeffRef(i) = std::complex(data_r_.coeffRef(pos_r_++), + data_r_.coeffRef(pos_r_++)); + } + } + } + + /** + * Return an Eigen matrix of size `(rows, cols)`. + * @tparam Ret The type to return. + */ template * = nullptr> + require_eigen_matrix_dynamic_t* = nullptr, + require_not_vt_complex* = nullptr> auto read(Rows rows, Cols cols) { if (rows == 0 || cols == 0) { return map_matrix_t(nullptr, rows, cols); @@ -166,6 +248,29 @@ class deserializer { } } + /** + * Return an Eigen matrix of size `(rows, cols)` with complex inner type. + * @tparam Ret The type to return. + */ + template * = nullptr, + require_vt_complex* = nullptr> + auto read(Rows rows, Cols cols) { + if (rows == 0 || cols == 0) { + return Ret(map_matrix_t(nullptr, rows, cols)); + } else { + Ret ret(rows, cols); + for (Eigen::Index i = 0; i < rows * cols; ++i) { + ret.coeffRef(i) = std::complex(data_r_.coeffRef(pos_r_++), + data_r_.coeffRef(pos_r_++)); + } + } + } + + /** + * Return a `var_value` with inner Eigen type. + * @tparam Ret The type to return. + */ template * = nullptr, require_var_matrix_t* = nullptr> auto read(Sizes... sizes) { @@ -173,6 +278,10 @@ class deserializer { return stan::math::to_var_value(this->read(sizes...)); } + /** + * Return an Eigen type when the deserializers inner class is not var. + * @tparam Ret The type to return. + */ template * = nullptr, require_var_matrix_t* = nullptr> @@ -181,6 +290,14 @@ class deserializer { return this->read(sizes...); } + /** + * Return an `std::vector` + * @tparam Ret The type to return. + * @tparam Size an integral type. + * @tparam Sizes types of additional inner containers + * @param m The size of the vector. + * @param dims a possible set of inner container sizes passed to subsequent `read` functions. + */ template * = nullptr> inline auto read(Size m, Sizes... dims) { @@ -197,6 +314,20 @@ class deserializer { } } + /** + * Return the next object, checking that it's elements are + * greater than or equal to the specified lower bound. + * + *

See stan::math::check_greater_or_equal(T,double). + * + * @tparam Ret The type to return. + * @tparam LB Type of lower bound. + * @tparam Sizes A pack of possible sizes to construct the object from. + * @param lb Lower bound. + * @param sizes a pack of sizes to use to construct the return. + * @throw std::runtime_error if the scalar is less than the + * specified lower bound + */ template auto read_lb(const LB& lb, Sizes... sizes) { using stan::math::check_greater_or_equal; @@ -205,9 +336,24 @@ class deserializer { return ret; } + /** + * Return the next scalar transformed to have the specified + * lower bound, possibly incrementing the specified reference with the + * log of the absolute Jacobian determinant of the transform. + * + *

See stan::math::lb_constrain(T,double,T&). + * + * @tparam Ret The type to return. + * @tparam Jacobian Whether to increment the log of the absolute Jacobian determinant of the transform. + * @tparam LB Type of lower bound. + * @tparam LP Type of log prob. + * @param lb Lower bound on result. + * @param lp Reference to log probability variable to increment. + * @param sizes a pack of sizes to use to construct the return. + */ template - auto read_lb_constrain(const LB& lb, LP& lp, Sizes... sizes) { + auto read_lb(const LB& lb, LP& lp, Sizes... sizes) { if (Jacobian) { return stan::math::lb_constrain(this->read(sizes...), lb, lp); } else { @@ -215,6 +361,18 @@ class deserializer { } } + /** + * Return the next object, checking that it is + * less than or equal to the specified upper bound. + * + *

See stan::math::check_less_or_equal(T,double). + * + * @tparam Ret The type to return. + * @tparam UB Type of upper bound. + * @param ub Lower bound. + * @throw std::runtime_error if the scalar is less than the + * specified lower bound + */ template auto read_ub(const UB& ub, Sizes... sizes) { using stan::math::check_less_or_equal; @@ -223,9 +381,24 @@ class deserializer { return ret; } + /** + * Return the next object transformed to have the specified + * upper bound, possibly incrementing the specified reference with the + * log of the absolute Jacobian determinant of the transform. + * + *

See stan::math::ub_constrain(T,double,T&). + * + * @tparam Ret The type to return. + * @tparam Jacobian Whether to increment the log of the absolute Jacobian determinant of the transform. + * @tparam UB Type of upper bound. + * @tparam LP Type of log prob. + * @param ub Upper bound on result. + * @param lp Reference to log probability variable to increment. + * @param sizes a pack of sizes to use to construct the return. + */ template - auto read_ub_constrain(const UB& ub, LP& lp, Sizes... sizes) { + auto read_ub(const UB& ub, LP& lp, Sizes... sizes) { if (Jacobian) { return stan::math::ub_constrain(this->read(sizes...), ub, lp); } else { @@ -233,6 +406,20 @@ class deserializer { } } + /** + * Return the next object, checking that it's elements is between + * the specified lower and upper bound. + * + *

See stan::math::check_bounded(T, LB, UB). + * + * @tparam Ret The type to return. + * @tparam LB Type of lower bound. + * @tparam UB Type of upper bound. + * @param lb Lower bound. + * @param ub Upper bound. + * @throw std::runtime_error if the scalar is not between the specified + * lower and upper bounds. + */ template auto read_lub(const LB& lb, const UB& ub, Sizes... sizes) { using stan::math::check_bounded; @@ -242,9 +429,24 @@ class deserializer { return ret; } + /** + * Return the next object transformed to be between the + * the specified lower and upper bounds. + * + *

See stan::math::lub_constrain(T, double, double, T&). + * + * @tparam Ret The type to return. + * @tparam Jacobian Whether to increment the log of the absolute Jacobian determinant of the transform. + * @tparam T Type of scalar. + * @tparam LB Type of lower bound. + * @tparam UB Type of upper bound. + * @param lb Lower bound. + * @param ub Upper bound. + * @param lp Reference to log probability variable to increment. + */ template - auto read_lub_constrain(const LB& lb, const UB& ub, LP& lp, Sizes... sizes) { + auto read_lub(const LB& lb, const UB& ub, LP& lp, Sizes... sizes) { if (Jacobian) { return stan::math::lub_constrain(this->read(sizes...), lb, ub, lp); } else { @@ -255,10 +457,11 @@ class deserializer { template auto read_pos(const Sizes&... sizes) { auto ret = read(sizes...); - stan::math::check_positive("stan::io::deserializer", "Positive Constrained", + stan::math::check_positive("deserializer", "Positive Constrained", ret); return ret; } + template * = nullptr> auto read_pos(LP& lp, const Sizes&... sizes) { @@ -322,7 +525,7 @@ class deserializer { auto read_prob(const Sizes&... sizes) { auto ret = read(sizes...); stan::math::check_bounded( - "stan::io::deserializer", "Constrained probability", ret, 0, 1); + "deserializer", "Constrained probability", ret, 0, 1); return ret; } template (sizes...); stan::math::check_bounded( - "stan::io::deserializer", "Correlation value", ret, -1, 1); + "deserializer", "Correlation value", ret, -1, 1); return ret; } @@ -407,7 +610,7 @@ class deserializer { throw std::invalid_argument(msg); } auto ret = read(k); - stan::math::check_unit_vector("stan::io::deserializer", "Unit Vector", ret); + stan::math::check_unit_vector("deserializer", "Unit Vector", ret); return ret; } @@ -453,7 +656,7 @@ class deserializer { throw std::invalid_argument(msg); } auto ret = read(k); - stan::math::check_simplex("stan::io::deserializer", "Simplex", ret); + stan::math::check_simplex("deserializer", "Simplex", ret); return ret; } @@ -495,7 +698,7 @@ class deserializer { auto read_ordered(const Sizes&... sizes) { using stan::math::check_ordered; auto ret = read(sizes...); - check_ordered("stan::io::deserializer", "Ordered", ret); + check_ordered("deserializer", "Ordered", ret); return ret; } @@ -526,7 +729,7 @@ class deserializer { auto read_positive_ordered(const Sizes&... sizes) { using stan::math::check_positive_ordered; auto ret = read(sizes...); - check_positive_ordered("stan::io::deserializer", "Positive Ordered", ret); + check_positive_ordered("deserializer", "Positive Ordered", ret); return ret; } @@ -559,7 +762,7 @@ class deserializer { auto read_cholesky_factor_cov(size_t M, size_t N) { using stan::math::check_cholesky_factor; auto ret = read(M, N); - check_cholesky_factor("stan::io::deserializer", "Cholesky Factor Cov", ret); + check_cholesky_factor("deserializer", "Cholesky Factor Cov", ret); return ret; } @@ -602,11 +805,11 @@ class deserializer { // SDF template * = nullptr> - auto read_cholesky_factor_corr(size_t M, size_t N) { - using stan::math::check_cholesky_factor; - auto ret = read(M, N); - check_cholesky_factor_corr("stan::io::cholesky_factor_corr", - "Constrained matrix", ret); + auto read_cholesky_factor_corr(size_t K) { + using stan::math::check_cholesky_factor_corr; + auto ret = read(K, K); + check_cholesky_factor_corr("deserializer", + "Cholesky Factor Corr Matrix", ret); return ret; } diff --git a/src/test/unit/io/deserializer_test.cpp b/src/test/unit/io/deserializer_test.cpp index c9c3f87785d..0cfaf975638 100644 --- a/src/test/unit/io/deserializer_test.cpp +++ b/src/test/unit/io/deserializer_test.cpp @@ -33,17 +33,29 @@ TEST(deserializer, zeroSizeVecs) { EXPECT_EQ(0, deserializer.read>>(0, 0, 0, 0).size()); } -TEST(deserializer_scalar, read) { - std::vector theta_i; + +TEST(deserializer, eos_exception) { std::vector theta; theta.push_back(1.0); theta.push_back(2.0); + std::vector theta_i; + theta_i.push_back(1); stan::io::deserializer deserializer(theta, theta_i); - double x = deserializer.read(); - EXPECT_FLOAT_EQ(1.0, x); - double y = deserializer.read(); - EXPECT_FLOAT_EQ(2.0, y); - EXPECT_EQ(0U, deserializer.available()); + + EXPECT_EQ(2U, deserializer.available()); + EXPECT_EQ(1U, deserializer.available_i()); + + EXPECT_NO_THROW(deserializer.read()); + EXPECT_NO_THROW(deserializer.read()); + EXPECT_THROW(deserializer.read(), std::runtime_error); + + // should go back to working + EXPECT_NO_THROW(deserializer.read()); + EXPECT_THROW(deserializer.read(), std::runtime_error); + + // should keep throwing + EXPECT_THROW(deserializer.read(), std::runtime_error); + EXPECT_THROW(deserializer.read(), std::runtime_error); } TEST(deserializer_rowvector, read) { @@ -110,8 +122,20 @@ TEST(deserializer_stdvec, std_vector_std_vector_matrix) { } } -// lower bounds +// scalar bounds +TEST(deserializer_scalar, read) { + std::vector theta_i; + std::vector theta; + theta.push_back(1.0); + theta.push_back(2.0); + stan::io::deserializer deserializer(theta, theta_i); + double x = deserializer.read(); + EXPECT_FLOAT_EQ(1.0, x); + double y = deserializer.read(); + EXPECT_FLOAT_EQ(2.0, y); + EXPECT_EQ(0U, deserializer.available()); +} TEST(deserializer_scalar, read_lb) { std::vector theta_i; @@ -143,10 +167,10 @@ TEST(deserializer_scalar, read_lb_constrain) { theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); double lp = 0.0; - EXPECT_FLOAT_EQ(1.0 + exp(-2.0), (deserializer.read_lb_constrain(1.0, lp))); - EXPECT_FLOAT_EQ(5.0 + exp(3.0), (deserializer.read_lb_constrain(5.0, lp))); - EXPECT_FLOAT_EQ(-2.0 + exp(-1.0), (deserializer.read_lb_constrain(-2.0, lp))); - EXPECT_FLOAT_EQ(15.0 + exp(0.0), (deserializer.read_lb_constrain(15.0, lp))); + EXPECT_FLOAT_EQ(1.0 + exp(-2.0), (deserializer.read_lb(1.0, lp))); + EXPECT_FLOAT_EQ(5.0 + exp(3.0), (deserializer.read_lb(5.0, lp))); + EXPECT_FLOAT_EQ(-2.0 + exp(-1.0), (deserializer.read_lb(-2.0, lp))); + EXPECT_FLOAT_EQ(15.0 + exp(0.0), (deserializer.read_lb(15.0, lp))); } TEST(deserializer_scalar, read_lb_constrain_jacobian) { std::vector theta_i; @@ -157,10 +181,10 @@ TEST(deserializer_scalar, read_lb_constrain_jacobian) { theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); double lp = -1.5; - EXPECT_FLOAT_EQ(1.0 + exp(-2.0), (deserializer.read_lb_constrain(1.0, lp))); - EXPECT_FLOAT_EQ(5.0 + exp(3.0), (deserializer.read_lb_constrain(5.0, lp))); - EXPECT_FLOAT_EQ(-2.0 + exp(-1.0), (deserializer.read_lb_constrain(-2.0, lp))); - EXPECT_FLOAT_EQ(15.0 + exp(0.0), (deserializer.read_lb_constrain(15.0, lp))); + EXPECT_FLOAT_EQ(1.0 + exp(-2.0), (deserializer.read_lb(1.0, lp))); + EXPECT_FLOAT_EQ(5.0 + exp(3.0), (deserializer.read_lb(5.0, lp))); + EXPECT_FLOAT_EQ(-2.0 + exp(-1.0), (deserializer.read_lb(-2.0, lp))); + EXPECT_FLOAT_EQ(15.0 + exp(0.0), (deserializer.read_lb(15.0, lp))); EXPECT_FLOAT_EQ(-1.5 - 2.0 + 3.0 - 1.0, lp); } @@ -197,10 +221,10 @@ TEST(deserializer_scalar, read_ub_constrain) { theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); double lp = 0; - EXPECT_FLOAT_EQ(1.0 - exp(-2.0), (deserializer.read_ub_constrain(1.0, lp))); - EXPECT_FLOAT_EQ(5.0 - exp(3.0), (deserializer.read_ub_constrain(5.0, lp))); - EXPECT_FLOAT_EQ(-2.0 - exp(-1.0), (deserializer.read_ub_constrain(-2.0, lp))); - EXPECT_FLOAT_EQ(15.0 - exp(0.0), (deserializer.read_ub_constrain(15.0, lp))); + EXPECT_FLOAT_EQ(1.0 - exp(-2.0), (deserializer.read_ub(1.0, lp))); + EXPECT_FLOAT_EQ(5.0 - exp(3.0), (deserializer.read_ub(5.0, lp))); + EXPECT_FLOAT_EQ(-2.0 - exp(-1.0), (deserializer.read_ub(-2.0, lp))); + EXPECT_FLOAT_EQ(15.0 - exp(0.0), (deserializer.read_ub(15.0, lp))); } TEST(deserializer_scalar, read_ub_constrain_jacobian) { std::vector theta_i; @@ -211,10 +235,10 @@ TEST(deserializer_scalar, read_ub_constrain_jacobian) { theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); double lp = -12.9; - EXPECT_FLOAT_EQ(1.0 - exp(-2.0), (deserializer.read_ub_constrain(1.0, lp))); - EXPECT_FLOAT_EQ(5.0 - exp(3.0), (deserializer.read_ub_constrain(5.0, lp))); - EXPECT_FLOAT_EQ(-2.0 - exp(-1.0), (deserializer.read_ub_constrain(-2.0, lp))); - EXPECT_FLOAT_EQ(15.0 - exp(0.0), (deserializer.read_ub_constrain(15.0, lp))); + EXPECT_FLOAT_EQ(1.0 - exp(-2.0), (deserializer.read_ub(1.0, lp))); + EXPECT_FLOAT_EQ(5.0 - exp(3.0), (deserializer.read_ub(5.0, lp))); + EXPECT_FLOAT_EQ(-2.0 - exp(-1.0), (deserializer.read_ub(-2.0, lp))); + EXPECT_FLOAT_EQ(15.0 - exp(0.0), (deserializer.read_ub(15.0, lp))); EXPECT_FLOAT_EQ(-12.9 - 2.0 + 3.0 - 1.0, lp); } @@ -257,13 +281,13 @@ TEST(deserializer_scalar, read_lub_constrain) { theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); double lp = 0; - EXPECT_FLOAT_EQ(inv_logit_m2, (deserializer.read_lub_constrain(0.0, 1.0, lp))); + EXPECT_FLOAT_EQ(inv_logit_m2, (deserializer.read_lub(0.0, 1.0, lp))); EXPECT_FLOAT_EQ(3.0 + 2.0 * inv_logit_3, - (deserializer.read_lub_constrain(3.0, 5.0, lp))); + (deserializer.read_lub(3.0, 5.0, lp))); EXPECT_FLOAT_EQ(-3.0 + 5.0 * inv_logit_m1, - (deserializer.read_lub_constrain(-3.0, 2.0, lp))); + (deserializer.read_lub(-3.0, 2.0, lp))); EXPECT_FLOAT_EQ(-15.0 + 30.0 * inv_logit_0, - (deserializer.read_lub_constrain(-15.0, 15.0, lp))); + (deserializer.read_lub(-15.0, 15.0, lp))); } TEST(deserializer_scalar, read_lub_constrain_jacobian) { std::vector theta_i; @@ -275,13 +299,13 @@ TEST(deserializer_scalar, read_lub_constrain_jacobian) { stan::io::deserializer deserializer(theta, theta_i); double lp = -7.2; EXPECT_FLOAT_EQ(0.0 + 1.0 * inv_logit_m2, - (deserializer.read_lub_constrain(0.0, 1.0, lp))); + (deserializer.read_lub(0.0, 1.0, lp))); EXPECT_FLOAT_EQ(3.0 + 2.0 * inv_logit_3, - (deserializer.read_lub_constrain(3.0, 5.0, lp))); + (deserializer.read_lub(3.0, 5.0, lp))); EXPECT_FLOAT_EQ(-3.0 + 5.0 * inv_logit_m1, - (deserializer.read_lub_constrain(-3.0, 2.0, lp))); + (deserializer.read_lub(-3.0, 2.0, lp))); EXPECT_FLOAT_EQ(-15.0 + 30.0 * inv_logit_0, - (deserializer.read_lub_constrain(-15.0, 15.0, lp))); + (deserializer.read_lub(-15.0, 15.0, lp))); double expected_lp = -7.2 + log((1.0 - 0.0) * inv_logit_m2 * (1 - inv_logit_m2)) + log((5.0 - 3.0) * inv_logit_3 * (1 - inv_logit_3)) @@ -709,6 +733,249 @@ TEST(deserializer_matrix, read) { } +TEST(deserializer_matrix, matrix_lb) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (int i = 0; i < 7; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + double lb = -1.5; + Eigen::Matrix y + = deserializer.read_lb(lb, 3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(7.0, y(0, 0)); + EXPECT_FLOAT_EQ(8.0, y(1, 0)); + EXPECT_FLOAT_EQ(9.0, y(2, 0)); + EXPECT_FLOAT_EQ(10.0, y(0, 1)); + EXPECT_FLOAT_EQ(11.0, y(1, 1)); + EXPECT_FLOAT_EQ(12.0, y(2, 1)); + + double a = deserializer.read(); + EXPECT_FLOAT_EQ(13.0, a); +} + +TEST(deserializer_matrix, matrix_lb_constrain) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (int i = 0; i < 7; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + double lb = -1.5; + double lp = 0; + Eigen::Matrix y + = deserializer.read_lb(lb, lp, 3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(7.0, lb), y(0, 0)); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(8.0, lb), y(1, 0)); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(9.0, lb), y(2, 0)); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(10.0, lb), y(0, 1)); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(11.0, lb), y(1, 1)); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(12.0, lb), y(2, 1)); + + double a = deserializer.read(); + EXPECT_FLOAT_EQ(13.0, a); +} + +TEST(deserializer_matrix, matrix_lb_constrain_lp) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (int i = 0; i < 7; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + double lb = -1.5; + double lp = -5.0; + Eigen::Matrix y + = deserializer.read_lb(lb, lp, 3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(7.0, lb, lp), y(0, 0)); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(8.0, lb, lp), y(1, 0)); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(9.0, lb, lp), y(2, 0)); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(10.0, lb, lp), y(0, 1)); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(11.0, lb, lp), y(1, 1)); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(12.0, lb, lp), y(2, 1)); + + double a = deserializer.read(); + EXPECT_FLOAT_EQ(13.0, a); +} + +TEST(deserializer_matrix, matrix_ub) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (int i = 0; i < 7; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + double ub = 12.5; + Eigen::Matrix y + = deserializer.read_ub(ub, 3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(7.0, y(0, 0)); + EXPECT_FLOAT_EQ(8.0, y(1, 0)); + EXPECT_FLOAT_EQ(9.0, y(2, 0)); + EXPECT_FLOAT_EQ(10.0, y(0, 1)); + EXPECT_FLOAT_EQ(11.0, y(1, 1)); + EXPECT_FLOAT_EQ(12.0, y(2, 1)); + + double a = deserializer.read(); + EXPECT_FLOAT_EQ(13.0, a); +} + +TEST(deserializer_matrix, matrix_ub_constrain) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (int i = 0; i < 7; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + double ub = 14.1; + double lp = 0; + Eigen::Matrix y + = deserializer.read_ub(ub, lp, 3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(7.0, ub), y(0, 0)); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(8.0, ub), y(1, 0)); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(9.0, ub), y(2, 0)); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(10.0, ub), y(0, 1)); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(11.0, ub), y(1, 1)); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(12.0, ub), y(2, 1)); + + double a = deserializer.read(); + EXPECT_FLOAT_EQ(13.0, a); +} + +TEST(deserializer_matrix, matrix_ub_constrain_lp) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (int i = 0; i < 7; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + double ub = 12.1; + double lp = -5.0; + Eigen::Matrix y + = deserializer.read_ub(ub, lp, 3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(7.0, ub, lp), y(0, 0)); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(8.0, ub, lp), y(1, 0)); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(9.0, ub, lp), y(2, 0)); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(10.0, ub, lp), y(0, 1)); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(11.0, ub, lp), y(1, 1)); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(12.0, ub, lp), y(2, 1)); + + double a = deserializer.read(); + EXPECT_FLOAT_EQ(13.0, a); +} + +TEST(deserializer_matrix, matrix_lub) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (int i = 0; i < 7; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + double lb = 6.9; + double ub = 12.5; + Eigen::Matrix y + = deserializer.read_lub(lb, ub, 3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(7.0, y(0, 0)); + EXPECT_FLOAT_EQ(8.0, y(1, 0)); + EXPECT_FLOAT_EQ(9.0, y(2, 0)); + EXPECT_FLOAT_EQ(10.0, y(0, 1)); + EXPECT_FLOAT_EQ(11.0, y(1, 1)); + EXPECT_FLOAT_EQ(12.0, y(2, 1)); + + double a = deserializer.read(); + EXPECT_FLOAT_EQ(13.0, a); +} + +TEST(deserializer_matrix, matrix_lub_constrain) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (int i = 0; i < 7; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + double lb = 3.5; + double ub = 14.1; + double lp = 0; + Eigen::Matrix y + = deserializer.read_lub(lb, ub, lp, 3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(7.0, lb, ub), y(0, 0)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(8.0, lb, ub), y(1, 0)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(9.0, lb, ub), y(2, 0)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(10.0, lb, ub), y(0, 1)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(11.0, lb, ub), y(1, 1)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(12.0, lb, ub), y(2, 1)); + + double a = deserializer.read(); + EXPECT_FLOAT_EQ(13.0, a); +} + +TEST(deserializer_matrix, matrix_lub_constrain_lp) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (int i = 0; i < 7; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + double lb = 4.1; + double ub = 12.1; + double lp = -5.0; + Eigen::Matrix y + = deserializer.read_lub(lb, ub, lp, 3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(7.0, lb, ub, lp), y(0, 0)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(8.0, lb, ub, lp), y(1, 0)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(9.0, lb, ub, lp), y(2, 0)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(10.0, lb, ub, lp), y(0, 1)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(11.0, lb, ub, lp), y(1, 1)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(12.0, lb, ub, lp), y(2, 1)); + + double a = deserializer.read(); + EXPECT_FLOAT_EQ(13.0, a); +} + TEST(deserializer_matrix, corr_matrix) { std::vector theta_i; std::vector theta; @@ -801,6 +1068,295 @@ TEST(deserializer_matrix, corr_matrix_constrain_jacobian) { // FIXME: test jacobian } +TEST(deserializer_matrix, cov_matrix) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + theta[0] = 6.3295234356180128; + theta[1] = 0.6351775806192667; + theta[2] = 3.8081029582054304; + theta[3] = 0.6351775806192667; + theta[4] = 1.9293554162496527; + theta[5] = 0.5483126868366485; + theta[6] = 3.8081029582054304; + theta[7] = 0.5483126868366485; + theta[8] = 3.0827514661973088; + stan::io::deserializer deserializer(theta, theta_i); + Eigen::Matrix S + = deserializer.read_cov_matrix(3); + EXPECT_FLOAT_EQ(theta[0], S(0, 0)); + EXPECT_FLOAT_EQ(theta[1], S(1, 0)); + EXPECT_FLOAT_EQ(theta[7], S(2, 1)); + EXPECT_FLOAT_EQ(theta[8], S(2, 2)); +} +TEST(deserializer_matrix, cov_matrix_exception) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + theta[0] = 6.3; + theta[1] = 0.7; + theta[2] = 0.6; + theta[3] = 1.9; + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_THROW(deserializer.read_cov_matrix(2), std::domain_error); + EXPECT_THROW(deserializer.read_cov_matrix(0), std::invalid_argument); +} +TEST(deserializer_matrix, cov_matrix_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(-1.0); + theta.push_back(0.0); + theta.push_back(0.5); + theta.push_back(1.0); + theta.push_back(2.0); + theta.push_back(1.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0; + Eigen::Matrix S( + deserializer.read_cov_matrix(lp, 3U)); + EXPECT_EQ(3, S.rows()); + EXPECT_EQ(3, S.cols()); + EXPECT_EQ(9, S.size()); + EXPECT_EQ(1U, deserializer.available()); + for (size_t i = 0; i < 3U; ++i) + for (size_t j = i + 1; j < 3U; ++j) + EXPECT_FLOAT_EQ(S(i, j), S(j, i)); + Eigen::SelfAdjointEigenSolver< + Eigen::Matrix> + solver(S, Eigen::EigenvaluesOnly); + assert(solver.eigenvalues()[0] + > 1E-10); // check positive definite with smallest eigenvalue > 0 +} +TEST(deserializer_matrix, cov_matrix_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(-1.0); + theta.push_back(0.0); + theta.push_back(0.5); + theta.push_back(1.0); + theta.push_back(2.0); + theta.push_back(1.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = -3.1; + + Eigen::Matrix S( + deserializer.read_cov_matrix(lp, 3U)); + + EXPECT_EQ(3, S.rows()); + EXPECT_EQ(3, S.cols()); + EXPECT_EQ(9, S.size()); + EXPECT_EQ(1U, deserializer.available()); + for (size_t i = 0; i < 3U; ++i) + for (size_t j = i + 1; j < 3U; ++j) + EXPECT_FLOAT_EQ(S(i, j), S(j, i)); + Eigen::SelfAdjointEigenSolver< + Eigen::Matrix> + solver(S, Eigen::EigenvaluesOnly); + assert(solver.eigenvalues()[0] + > 1E-10); // check positive definite with smallest eigenvalue > 0 + // FIXME: test Jacobian +} + +TEST(deserializer_matrix, cholesky_factor_cov) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + // column major + theta[0] = 1; + theta[1] = 2; + theta[2] = 3; + + theta[3] = 0; + theta[4] = 4; + theta[5] = 5; + + theta[6] = 0; + theta[7] = 0; + theta[8] = 6; + stan::io::deserializer deserializer(theta, theta_i); + Eigen::Matrix S + = deserializer.read_cholesky_factor_cov(3, 3); + EXPECT_FLOAT_EQ(theta[0], S(0, 0)); + EXPECT_FLOAT_EQ(theta[1], S(1, 0)); + EXPECT_FLOAT_EQ(theta[7], S(1, 2)); + EXPECT_FLOAT_EQ(theta[8], S(2, 2)); +} +TEST(deserializer_matrix, cholesky_factor_cov_asymmetric) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + // column major + theta[0] = 1; + theta[1] = 2; + theta[2] = 3; + + theta[3] = 0; + theta[4] = 4; + theta[5] = 5; + + stan::io::deserializer deserializer(theta, theta_i); + Eigen::Matrix S + = deserializer.read_cholesky_factor_cov(3, 2); + EXPECT_FLOAT_EQ(theta[0], S(0, 0)); + EXPECT_FLOAT_EQ(theta[1], S(1, 0)); + EXPECT_FLOAT_EQ(theta[2], S(2, 0)); + + EXPECT_FLOAT_EQ(theta[3], S(0, 1)); + EXPECT_FLOAT_EQ(theta[4], S(1, 1)); + EXPECT_FLOAT_EQ(theta[5], S(2, 1)); +} + +TEST(deserializer_matrix, cholesky_factor_cov_exception) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + theta[0] = -6.3; + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_THROW(deserializer.read_cholesky_factor_cov(2, 2), std::domain_error); + EXPECT_THROW(deserializer.read_cholesky_factor_cov(0, 0), std::domain_error); + + theta[0] = 1; + EXPECT_THROW(deserializer.read_cholesky_factor_cov(2, 3), std::domain_error); +} +TEST(deserializer_matrix, cholesky_factor_cov_constrain) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 8; ++i) + theta.push_back(-static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0; + Eigen::Matrix L( + deserializer.read_cholesky_factor_cov(lp, 3U, 3U)); + EXPECT_NO_THROW(stan::math::check_cholesky_factor( + "test_cholesky_factor_constrain", "L", L)); + EXPECT_EQ(3, L.rows()); + EXPECT_EQ(3, L.cols()); + EXPECT_EQ(9, L.size()); + EXPECT_EQ(2U, deserializer.available()); +} + + +TEST(deserializer_matrix, cholesky_factor_cov_constrain_asymmetric) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 8; ++i) + theta.push_back(-static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0; + Eigen::Matrix L( + deserializer.read_cholesky_factor_cov(lp, 3U, 2U)); + EXPECT_NO_THROW(stan::math::check_cholesky_factor( + "test_cholesky_factor_constrain", "L", L)); + EXPECT_EQ(3, L.rows()); + EXPECT_EQ(2, L.cols()); + EXPECT_EQ(6, L.size()); + EXPECT_EQ(3U, deserializer.available()); +} +TEST(deserializer_matrix, cholesky_factor_cov_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 8; ++i) + theta.push_back(-static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 1.9; + Eigen::Matrix L( + deserializer.read_cholesky_factor_cov(lp, 3U, 3U)); + EXPECT_NO_THROW(stan::math::check_cholesky_factor( + "test_cholesky_factor_constrain", "L", L)); + EXPECT_EQ(3, L.rows()); + EXPECT_EQ(3, L.cols()); + EXPECT_EQ(9, L.size()); + EXPECT_EQ(2U, deserializer.available()); + EXPECT_EQ(1.9 + log(L(0, 0)) + log(L(1, 1)) + log(L(2, 2)), lp); +} +TEST(deserializer_matrix, cholesky_factor_cov_constrain_jacobian_asymmetric) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 12; ++i) + theta.push_back(-static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 1.9; + Eigen::Matrix L( + deserializer.read_cholesky_factor_cov(lp, 4U, 3U)); + EXPECT_NO_THROW(stan::math::check_cholesky_factor( + "test_cholesky_factor_constrain", "L", L)); + EXPECT_EQ(4, L.rows()); + EXPECT_EQ(3, L.cols()); + EXPECT_EQ(12, L.size()); + EXPECT_EQ(3U, deserializer.available()); + EXPECT_EQ(1.9 + log(L(0, 0)) + log(L(1, 1)) + log(L(2, 2)), lp); +} + +TEST(deserializer_matrix, cholesky_factor_corr) { + std::vector theta_i; + std::vector theta(9); + // column major + theta[0] = 1; + theta[1] = 0; + theta[2] = 0; + + theta[3] = 0; + theta[4] = 1; + theta[5] = 0; + + theta[6] = 0; + theta[7] = 0; + theta[8] = 1; + stan::io::deserializer deserializer(theta, theta_i); + Eigen::Matrix S + = deserializer.read_cholesky_factor_corr(3); + EXPECT_FLOAT_EQ(theta[0], S(0, 0)); + EXPECT_FLOAT_EQ(theta[1], S(1, 0)); + EXPECT_FLOAT_EQ(theta[4], S(1, 1)); + EXPECT_FLOAT_EQ(theta[7], S(1, 2)); + EXPECT_FLOAT_EQ(theta[8], S(2, 2)); +} + +TEST(deserializer_matrix, cholesky_factor_corr_exception) { + std::vector theta_i; + std::vector theta(9); + Eigen::Matrix S; + + // non lower-triangular matrix (column major) + // the rest of these tests are with check_cholesky_factor_corr + theta[0] = 1; + theta[1] = 0; + theta[2] = 0; + + theta[3] = 0.5; + theta[4] = 1; + theta[5] = 0; + + theta[6] = 0; + theta[7] = 0; + theta[8] = 1; + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_THROW(deserializer.read_cholesky_factor_corr(3), std::domain_error); +} +TEST(deserializer_matrix, cholesky_factor_corr_constrain) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 8; ++i) + theta.push_back(-static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0; + Eigen::Matrix L( + deserializer.read_cholesky_factor_corr(lp, 3U)); + EXPECT_NO_THROW(stan::math::check_cholesky_factor_corr( + "test_cholesky_factor_corr_constrain", "L", L)); + EXPECT_EQ(3, L.rows()); + EXPECT_EQ(3, L.cols()); + EXPECT_EQ(9, L.size()); + EXPECT_EQ(5U, deserializer.available()); +} + // var matrix From 47f58f396b0d97ec09a595b81053272816f93c5c Mon Sep 17 00:00:00 2001 From: Steve Bronder Date: Tue, 23 Feb 2021 19:29:09 -0500 Subject: [PATCH 07/29] adds base docs for deserializer --- src/stan/io/deserializer.hpp | 435 ++++++++++++++++++++++++++++++++++- 1 file changed, 431 insertions(+), 4 deletions(-) diff --git a/src/stan/io/deserializer.hpp b/src/stan/io/deserializer.hpp index 6dcc2199a97..37e5a9ea841 100644 --- a/src/stan/io/deserializer.hpp +++ b/src/stan/io/deserializer.hpp @@ -454,6 +454,14 @@ class deserializer { } } + /** + * Return the next object, checking that it's elements are positive. + * + *

See stan::math::check_positive(T). + * + * @return Next positive scalar. + * @throw std::runtime_error if x is not positive + */ template auto read_pos(const Sizes&... sizes) { auto ret = read(sizes...); @@ -462,6 +470,15 @@ class deserializer { return ret; } + /** + * Return the next object transformed to be positive, possibly + * incrementing the specified reference with the log absolute + * determinant of the Jacobian. + * + *

See stan::math::positive_constrain(T,T&). + * + * @param lp Reference to log probability variable to increment. + */ template * = nullptr> auto read_pos(LP& lp, const Sizes&... sizes) { @@ -472,6 +489,10 @@ class deserializer { } } + /** + * Specialization for `std::vector` that calls itself recursivly for + * each element. + */ template * = nullptr> auto read_pos(LP& lp, const size_t vecsize, const Sizes&... sizes) { @@ -484,12 +505,29 @@ class deserializer { return ret; } + /** + * This is just returns the requested type as there's nothing to check. + */ template auto read_offset_multiplier(const Offset& offset, const Mult& multiplier, const Sizes&... sizes) { return read(sizes...); } + /** + * Return the next scalar transformed to have the specified offset and + * multiplier. + * + *

See stan::math::offset_multiplier_constrain(T, double, + * double). + * + * @tparam TL Type of offset. + * @tparam TS Type of multiplier. + * @param offset Offset. + * @param multiplier Multiplier. + * @return Next scalar transformed to fall between the specified + * bounds. + */ template * = nullptr> @@ -505,6 +543,20 @@ class deserializer { } } + /** + * Return the next scalar transformed to have the specified offset and + * multiplier. + * + *

See stan::math::offset_multiplier_constrain(T, double, + * double). + * + * @tparam TL Type of offset. + * @tparam TS Type of multiplier. + * @param offset Offset. + * @param multiplier Multiplier. + * @return Next scalar transformed to fall between the specified + * bounds. + */ template * = nullptr> @@ -521,6 +573,14 @@ class deserializer { return ret; } + /** + * Return the next scalar, checking that it is a valid value for + * a probability, between 0 (inclusive) and 1 (inclusive). + * + *

See stan::math::check_bounded(T). + * + * @return Next probability value. + */ template auto read_prob(const Sizes&... sizes) { auto ret = read(sizes...); @@ -528,6 +588,17 @@ class deserializer { "deserializer", "Constrained probability", ret, 0, 1); return ret; } + + /** + * Return the next scalar transformed to be a probability + * between 0 and 1, incrementing the specified reference with + * the log of the absolute Jacobian determinant. + * + *

See stan::math::prob_constrain(T). + * + * @param lp Reference to log probability variable to increment. + * @return The next scalar transformed to a probability. + */ template * = nullptr> auto read_prob(LP& lp, const Sizes&... sizes) { @@ -538,6 +609,17 @@ class deserializer { } } + + /** + * Return the next scalar transformed to be a probability + * between 0 and 1, incrementing the specified reference with + * the log of the absolute Jacobian determinant. + * + *

See stan::math::prob_constrain(T). + * + * @param lp Reference to log probability variable to increment. + * @return The next scalar transformed to a probability. + */ template * = nullptr> auto read_prob(LP& lp, const size_t vecsize, const Sizes&... sizes) { @@ -550,6 +632,17 @@ class deserializer { return ret; } + /** + * Return the next scalar, checking that it is a valid + * value for a correlation, between -1 (inclusive) and + * 1 (inclusive). + * + *

See stan::math::check_bounded(T). + * + * @return Next correlation value. + * @throw std::runtime_error if the value is not valid + * for a correlation + */ template * = nullptr> auto read_corr(const Sizes&... sizes) { @@ -559,6 +652,15 @@ class deserializer { return ret; } + /** + * Returns the next correlation matrix of the specified dimensionality. + * + *

See stan::math::check_corr_matrix(Matrix). + * + * @param k Dimensionality of correlation matrix. + * @return Next correlation matrix of the specified dimensionality. + * @throw std::runtime_error if the matrix is not a correlation matrix + */ template * = nullptr> auto read_corr(size_t k) { using stan::math::check_corr_matrix; @@ -567,6 +669,17 @@ class deserializer { return ret; } + /** + * Return the next scalar transformed to be a (partial) + * correlation between -1 and 1, incrementing the specified + * reference with the log of the absolute Jacobian determinant. + * + *

See stan::math::corr_constrain(T,T&). + * + * @param lp The reference to the variable holding the log + * probability to increment. + * @return The next scalar transformed to a correlation. + */ template * = nullptr, require_not_matrix_t* = nullptr> @@ -579,6 +692,17 @@ class deserializer { } } + /** + * Return the next correlation matrix of the specified dimensionality, + * incrementing the specified reference with the log absolute Jacobian + * determinant. + * + *

See stan::math::corr_matrix_constrain(Matrix,T&). + * + * @param k Dimensionality of the (square) correlation matrix. + * @param lp Log probability reference to increment. + * @return The next correlation matrix of the specified dimensionality. + */ template * = nullptr, require_matrix_t* = nullptr> @@ -592,6 +716,17 @@ class deserializer { } } + /** + * Return the next scalar transformed to be a (partial) + * correlation between -1 and 1, incrementing the specified + * reference with the log of the absolute Jacobian determinant. + * + *

See stan::math::corr_constrain(T,T&). + * + * @param lp The reference to the variable holding the log + * probability to increment. + * @return The next scalar transformed to a correlation. + */ template * = nullptr> auto read_corr(LP& lp, const size_t vecsize, const Sizes&... sizes) { @@ -603,6 +738,17 @@ class deserializer { return ret; } + /** + * Return a unit_vector of the specified size made up of the + * next scalars. + * + *

See stan::math::check_unit_vector. + * + * @param k Size of returned unit_vector + * @return unit_vector read from the specified size number of scalars + * @throw std::runtime_error if the next k values is not a unit_vector + * @throw std::invalid_argument if k is zero + */ template * = nullptr> auto read_unit_vector(size_t k) { if (unlikely(k == 0)) { @@ -614,6 +760,17 @@ class deserializer { return ret; } + /** + * Return a unit_vector of the specified size made up of the + * next scalars. + * + *

See stan::math::check_unit_vector. + * + * @param k Size of returned unit_vector + * @return unit_vector read from the specified size number of scalars + * @throw std::runtime_error if the next k values is not a unit_vector + * @throw std::invalid_argument if k is zero + */ template * = nullptr> auto read_unit_vector(size_t vecsize, Sizes... sizes) { @@ -625,6 +782,19 @@ class deserializer { return ret; } + /** + * Return the next unit_vector of the specified size (using one fewer + * unconstrained scalars), incrementing the specified reference with the + * log absolute Jacobian determinant. + * + *

See stan::math::unit_vector_constrain(Eigen::Matrix,T&). + * + * @param k Size of unit_vector. + * @param lp Log probability to increment with log absolute + * Jacobian determinant. + * @return The next unit_vector of the specified size. + * @throw std::invalid_argument if k is zero + */ template * = nullptr> auto read_unit_vector(LP& lp, const Sizes&... sizes) { @@ -636,6 +806,19 @@ class deserializer { } } + /** + * Return the next unit_vector of the specified size (using one fewer + * unconstrained scalars), incrementing the specified reference with the + * log absolute Jacobian determinant. + * + *

See stan::math::unit_vector_constrain(Eigen::Matrix,T&). + * + * @param k Size of unit_vector. + * @param lp Log probability to increment with log absolute + * Jacobian determinant. + * @return The next unit_vector of the specified size. + * @throw std::invalid_argument if k is zero + */ template * = nullptr> auto read_unit_vector(LP& lp, const size_t vecsize, const Sizes&... sizes) { @@ -649,6 +832,17 @@ class deserializer { return ret; } + /** + * Return a simplex of the specified size made up of the + * next scalars. + * + *

See stan::math::check_simplex. + * + * @param k Size of returned simplex. + * @return Simplex read from the specified size number of scalars. + * @throw std::runtime_error if the k values is not a simplex. + * @throw std::invalid_argument if k is zero + */ template * = nullptr> auto read_simplex(size_t k) { if (unlikely(k == 0)) { @@ -660,6 +854,17 @@ class deserializer { return ret; } + /** + * Return a simplex of the specified size made up of the + * next scalars. + * + *

See stan::math::check_simplex. + * + * @param k Size of returned simplex. + * @return Simplex read from the specified size number of scalars. + * @throw std::runtime_error if the k values is not a simplex. + * @throw std::invalid_argument if k is zero + */ template * = nullptr> auto read_simplex(size_t vecsize, Sizes... sizes) { @@ -671,6 +876,19 @@ class deserializer { return ret; } + /** + * Return the next simplex of the specified size (using one fewer + * unconstrained scalars), incrementing the specified reference with the + * log absolute Jacobian determinant. + * + *

See stan::math::simplex_constrain(Eigen::Matrix,T&). + * + * @param k Size of simplex. + * @param lp Log probability to increment with log absolute + * Jacobian determinant. + * @return The next simplex of the specified size. + * @throws std::invalid_argument if number of dimensions (`k`) is zero + */ template * = nullptr> auto read_simplex(LP& lp, const Sizes&... sizes) { @@ -682,6 +900,19 @@ class deserializer { } } + /** + * Return the next simplex of the specified size (using one fewer + * unconstrained scalars), incrementing the specified reference with the + * log absolute Jacobian determinant. + * + *

See stan::math::simplex_constrain(Eigen::Matrix,T&). + * + * @param k Size of simplex. + * @param lp Log probability to increment with log absolute + * Jacobian determinant. + * @return The next simplex of the specified size. + * @throws std::invalid_argument if number of dimensions (`k`) is zero + */ template * = nullptr> auto read_simplex(LP& lp, const size_t vecsize, const Sizes&... sizes) { @@ -694,6 +925,16 @@ class deserializer { return ret; } + /** + * Return the next vector of specified size containing + * values in ascending order. + * + *

See stan::math::check_ordered(T) for + * behavior on failure. + * + * @param k Size of returned vector. + * @return Vector of positive values in ascending order. + */ template auto read_ordered(const Sizes&... sizes) { using stan::math::check_ordered; @@ -702,6 +943,17 @@ class deserializer { return ret; } + /** + * Return the next ordered vector of the specified + * size, incrementing the specified reference with the log + * absolute Jacobian of the determinant. + * + *

See stan::math::ordered_constrain(Matrix,T&). + * + * @param k Size of vector. + * @param lp Log probability reference to increment. + * @return Next ordered vector of the specified size. + */ template * = nullptr> auto read_ordered(LP& lp, const Sizes&... sizes) { @@ -713,6 +965,17 @@ class deserializer { } } + /** + * Return the next ordered vector of the specified + * size, incrementing the specified reference with the log + * absolute Jacobian of the determinant. + * + *

See stan::math::ordered_constrain(Matrix,T&). + * + * @param k Size of vector. + * @param lp Log probability reference to increment. + * @return Next ordered vector of the specified size. + */ template * = nullptr> auto read_ordered(LP& lp, const size_t vecsize, const Sizes&... sizes) { @@ -725,6 +988,16 @@ class deserializer { return ret; } + /** + * Return the next vector of specified size containing + * positive values in ascending order. + * + *

See stan::math::check_positive_ordered(T) for + * behavior on failure. + * + * @param k Size of returned vector. + * @return Vector of positive values in ascending order. + */ template auto read_positive_ordered(const Sizes&... sizes) { using stan::math::check_positive_ordered; @@ -733,6 +1006,17 @@ class deserializer { return ret; } + /** + * Return the next positive_ordered vector of the specified + * size, incrementing the specified reference with the log + * absolute Jacobian of the determinant. + * + *

See stan::math::positive_ordered_constrain(Matrix,T&). + * + * @param k Size of vector. + * @param lp Log probability reference to increment. + * @return Next positive_ordered vector of the specified size. + */ template * = nullptr> auto read_positive_ordered(LP& lp, const Sizes&... sizes) { @@ -744,6 +1028,17 @@ class deserializer { } } + /** + * Return the next positive_ordered vector of the specified + * size, incrementing the specified reference with the log + * absolute Jacobian of the determinant. + * + *

See stan::math::positive_ordered_constrain(Matrix,T&). + * + * @param k Size of vector. + * @param lp Log probability reference to increment. + * @return Next positive_ordered vector of the specified size. + */ template * = nullptr> auto read_positive_ordered(LP& lp, const size_t vecsize, @@ -758,6 +1053,16 @@ class deserializer { return ret; } + /** + * Return the next Cholesky factor with the specified + * dimensionality, reading it directly without transforms. + * + * @param M Rows of Cholesky factor + * @param N Columns of Cholesky factor + * @return Next Cholesky factor. + * @throw std::domain_error if the matrix is not a valid + * Cholesky factor. + */ template * = nullptr> auto read_cholesky_factor_cov(size_t M, size_t N) { using stan::math::check_cholesky_factor; @@ -766,6 +1071,16 @@ class deserializer { return ret; } + /** + * Return the next Cholesky factor with the specified + * dimensionality, reading it directly without transforms. + * + * @param M Rows of Cholesky factor + * @param N Columns of Cholesky factor + * @return Next Cholesky factor. + * @throw std::domain_error if the matrix is not a valid + * Cholesky factor. + */ template * = nullptr> auto read_cholesky_factor_cov(size_t vecsize, Sizes... sizes) { @@ -777,6 +1092,19 @@ class deserializer { return ret; } + /** + * Return the next Cholesky factor with the specified + * dimensionality, reading from an unconstrained vector of the + * appropriate size, and increment the log probability reference + * with the log Jacobian adjustment for the transform. + * + * @param M Rows of Cholesky factor + * @param N Columns of Cholesky factor + * @param[in,out] lp log probability + * @return Next Cholesky factor. + * @throw std::domain_error if the matrix is not a valid + * Cholesky factor. + */ template * = nullptr> auto read_cholesky_factor_cov(LP& lp, size_t M, size_t N) { @@ -789,6 +1117,19 @@ class deserializer { } } + /** + * Return the next Cholesky factor with the specified + * dimensionality, reading from an unconstrained vector of the + * appropriate size, and increment the log probability reference + * with the log Jacobian adjustment for the transform. + * + * @param M Rows of Cholesky factor + * @param N Columns of Cholesky factor + * @param[in,out] lp log probability + * @return Next Cholesky factor. + * @throw std::domain_error if the matrix is not a valid + * Cholesky factor. + */ template * = nullptr> auto read_cholesky_factor_cov(LP& lp, const size_t vecsize, @@ -802,8 +1143,16 @@ class deserializer { return ret; } - // SDF - + /** + * Return the next Cholesky factor for a correlation matrix with + * the specified dimensionality, reading it directly without + * transforms. + * + * @param K Rows and columns of Cholesky factor + * @return Next Cholesky factor for a correlation matrix. + * @throw std::domain_error if the matrix is not a valid + * Cholesky factor for a correlation matrix. + */ template * = nullptr> auto read_cholesky_factor_corr(size_t K) { using stan::math::check_cholesky_factor_corr; @@ -813,6 +1162,16 @@ class deserializer { return ret; } + /** + * Return the next Cholesky factor for a correlation matrix with + * the specified dimensionality, reading it directly without + * transforms. + * + * @param K Rows and columns of Cholesky factor + * @return Next Cholesky factor for a correlation matrix. + * @throw std::domain_error if the matrix is not a valid + * Cholesky factor for a correlation matrix. + */ template * = nullptr> auto read_cholesky_factor_corr(size_t vecsize, Sizes... sizes) { @@ -824,6 +1183,19 @@ class deserializer { return ret; } + /** + * Return the next Cholesky factor for a correlation matrix with + * the specified dimensionality, reading from an unconstrained + * vector of the appropriate size, and increment the log + * probability reference with the log Jacobian adjustment for + * the transform. + * + * @param K Rows and columns of Cholesky factor + * @param lp Log probability reference to increment. + * @return Next Cholesky factor for a correlation matrix. + * @throw std::domain_error if the matrix is not a valid + * Cholesky factor for a correlation matrix. + */ template * = nullptr> auto read_cholesky_factor_corr(LP& lp, size_t K) { @@ -837,6 +1209,19 @@ class deserializer { } } + /** + * Return the next Cholesky factor for a correlation matrix with + * the specified dimensionality, reading from an unconstrained + * vector of the appropriate size, and increment the log + * probability reference with the log Jacobian adjustment for + * the transform. + * + * @param K Rows and columns of Cholesky factor + * @param lp Log probability reference to increment. + * @return Next Cholesky factor for a correlation matrix. + * @throw std::domain_error if the matrix is not a valid + * Cholesky factor for a correlation matrix. + */ template * = nullptr> auto read_cholesky_factor_corr(LP& lp, const size_t vecsize, @@ -850,8 +1235,17 @@ class deserializer { return ret; } - // cov matrix - + /** + * Return the next covariance matrix with the specified + * dimensionality. + * + *

See stan::math::check_cov_matrix(Matrix). + * + * @param k Dimensionality of covariance matrix. + * @return Next covariance matrix of the specified dimensionality. + * @throw std::runtime_error if the matrix is not a valid + * covariance matrix + */ template * = nullptr> auto read_cov_matrix(size_t k) { using stan::math::check_cov_matrix; @@ -860,6 +1254,17 @@ class deserializer { return ret; } + /** + * Return the next covariance matrix with the specified + * dimensionality. + * + *

See stan::math::check_cov_matrix(Matrix). + * + * @param k Dimensionality of covariance matrix. + * @return Next covariance matrix of the specified dimensionality. + * @throw std::runtime_error if the matrix is not a valid + * covariance matrix + */ template * = nullptr> auto read_cov_matrix(size_t vecsize, Sizes... sizes) { @@ -871,6 +1276,17 @@ class deserializer { return ret; } + /** + * Return the next covariance matrix of the specified dimensionality, + * incrementing the specified reference with the log absolute Jacobian + * determinant. + * + *

See stan::math::cov_matrix_constrain(Matrix,T&). + * + * @param k Dimensionality of the (square) covariance matrix. + * @param lp Log probability reference to increment. + * @return The next covariance matrix of the specified dimensionality. + */ template * = nullptr> auto read_cov_matrix(LP& lp, size_t k) { @@ -884,6 +1300,17 @@ class deserializer { } } + /** + * Return the next covariance matrix of the specified dimensionality, + * incrementing the specified reference with the log absolute Jacobian + * determinant. + * + *

See stan::math::cov_matrix_constrain(Matrix,T&). + * + * @param k Dimensionality of the (square) covariance matrix. + * @param lp Log probability reference to increment. + * @return The next covariance matrix of the specified dimensionality. + */ template * = nullptr> auto read_cov_matrix(LP& lp, const size_t vecsize, const Sizes&... sizes) { From 1a58745953a13bf49d53cb4081dfe64aceb32bf1 Mon Sep 17 00:00:00 2001 From: Steve Bronder Date: Fri, 26 Feb 2021 09:56:47 -0500 Subject: [PATCH 08/29] update docs --- src/stan/io/deserializer.hpp | 1101 +++++++++--- .../unit/io/deserializer_stdvector_test.cpp | 1506 +++++++++++++++++ src/test/unit/io/deserializer_test.cpp | 904 ---------- src/test/unit/io/deserializer_varmat_test.cpp | 862 ++++++++++ 4 files changed, 3241 insertions(+), 1132 deletions(-) create mode 100644 src/test/unit/io/deserializer_stdvector_test.cpp create mode 100644 src/test/unit/io/deserializer_varmat_test.cpp diff --git a/src/stan/io/deserializer.hpp b/src/stan/io/deserializer.hpp index 37e5a9ea841..35a7407de06 100644 --- a/src/stan/io/deserializer.hpp +++ b/src/stan/io/deserializer.hpp @@ -31,12 +31,12 @@ namespace io { template class deserializer { private: - Eigen::Map> data_r_; // map of reals. - Eigen::Map> data_i_; // map of integers. - size_t r_size_{0}; // size of reals available. - size_t i_size_{0}; // size of integers available. - size_t pos_r_{0}; // current position in map of reals. - size_t pos_i_{0}; // current position in map of integers. + Eigen::Map> data_r_; // map of reals. + Eigen::Map> data_i_; // map of integers. + size_t r_size_{0}; // size of reals available. + size_t i_size_{0}; // size of integers available. + size_t pos_r_{0}; // current position in map of reals. + size_t pos_i_{0}; // current position in map of integers. /** * Return pointer to current scalar. */ @@ -65,7 +65,7 @@ class deserializer { return data_i_.coeffRef(pos_i_ - m); } /** - * The that there is anything left to read for scalars. + * Check if there is anything left to read for scalars. */ void check_r_capacity() const { if (pos_r_ >= r_size_) { @@ -76,7 +76,7 @@ class deserializer { } /** - * The that there is anything left to read for integers. + * Check if there is anything left to read for integers. */ void check_i_capacity() const { if (pos_i_ >= i_size_) { @@ -86,14 +86,23 @@ class deserializer { } } + template + using conditional_var_val_t + = std::conditional_t::value && is_var::value, + return_var_matrix_t, K>; + + template + using is_fp_or_ad = bool_constant::value + || is_autodiff::value>; + public: using matrix_t = Eigen::Matrix; using vector_t = Eigen::Matrix; using row_vector_t = Eigen::Matrix; - using map_matrix_t = Eigen::Map; - using map_vector_t = Eigen::Map; - using map_row_vector_t = Eigen::Map; + using map_matrix_t = Eigen::Map; + using map_vector_t = Eigen::Map; + using map_row_vector_t = Eigen::Map; using var_matrix_t = stan::math::var_value< Eigen::Matrix>; @@ -136,12 +145,11 @@ class deserializer { inline size_t available_i() const noexcept { return i_size_ - pos_i_; } /** - * Return the next scalar in the sequence. + * Return the next object in the sequence. * * @return Next scalar value. */ - template , - is_autodiff>* = nullptr> + template >* = nullptr> auto read() { check_r_capacity(); return data_r_.coeffRef(pos_r_++); @@ -167,7 +175,9 @@ class deserializer { /** * Return an Eigen column vector of size `m`. + * @tparam Size an integral type * @tparam Ret The type to return. + * @param m Size of column vector. */ template * = nullptr, @@ -182,7 +192,9 @@ class deserializer { /** * Return an Eigen column vector of size `m` with inner complex type. + * @tparam Size an integral type * @tparam Ret The type to return. + * @param m Size of column vector. */ template * = nullptr, @@ -194,14 +206,16 @@ class deserializer { Ret ret(m); for (Eigen::Index i = 0; i < m; ++i) { ret.coeffRef(i) = std::complex(data_r_.coeffRef(pos_r_++), - data_r_.coeffRef(pos_r_++)); + data_r_.coeffRef(pos_r_++)); } } } /** * Return an Eigen row vector of size `m`. + * @tparam Size an integral type * @tparam Ret The type to return. + * @param m Size of row vector. */ template * = nullptr, @@ -216,7 +230,9 @@ class deserializer { /** * Return an Eigen row vector of size `m` with inner complex type. + * @tparam Size an integral type * @tparam Ret The type to return. + * @param m Size of row vector. */ template * = nullptr, @@ -228,14 +244,18 @@ class deserializer { Ret ret(m); for (Eigen::Index i = 0; i < m; ++i) { ret.coeffRef(i) = std::complex(data_r_.coeffRef(pos_r_++), - data_r_.coeffRef(pos_r_++)); + data_r_.coeffRef(pos_r_++)); } } } /** * Return an Eigen matrix of size `(rows, cols)`. + * @tparam Rows Integral type. + * @tparam Cols Integral type. * @tparam Ret The type to return. + * @param rows The size of the rows of the matrix. + * @param cols The size of the cols of the matrix. */ template * = nullptr, @@ -250,7 +270,11 @@ class deserializer { /** * Return an Eigen matrix of size `(rows, cols)` with complex inner type. + * @tparam Rows Integral type. + * @tparam Cols Integral type. * @tparam Ret The type to return. + * @param rows The size of the rows of the matrix. + * @param cols The size of the cols of the matrix. */ template * = nullptr, @@ -262,7 +286,7 @@ class deserializer { Ret ret(rows, cols); for (Eigen::Index i = 0; i < rows * cols; ++i) { ret.coeffRef(i) = std::complex(data_r_.coeffRef(pos_r_++), - data_r_.coeffRef(pos_r_++)); + data_r_.coeffRef(pos_r_++)); } } } @@ -270,23 +294,34 @@ class deserializer { /** * Return a `var_value` with inner Eigen type. * @tparam Ret The type to return. + * @tparam T_ Should never be set by user, set to default value of `T` for + * performing deduction on the class's inner type. + * @tparam Sizes A parameter pack of integral types. + * @param sizes A parameter pack of integral types representing the + * dimensions of the `var_value` matrix or vector. */ template * = nullptr, require_var_matrix_t* = nullptr> auto read(Sizes... sizes) { - using value_t = typename Ret::value_type; - return stan::math::to_var_value(this->read(sizes...)); + using value_t = typename std::decay_t::value_type; + using var_v_t = stan::math::promote_scalar_t; + return stan::math::to_var_value(this->read(sizes...)); } /** * Return an Eigen type when the deserializers inner class is not var. * @tparam Ret The type to return. + * @tparam T_ Should never be set by user, set to default value of `T` for + * performing deduction on the class's inner type. + * @tparam Sizes A parameter pack of integral types. + * @param sizes A parameter pack of integral types representing the + * dimensions of the `var_value` matrix or vector. */ template * = nullptr, require_var_matrix_t* = nullptr> auto read(Sizes... sizes) { - using value_t = typename Ret::value_type; + using value_t = typename std::decay_t::value_type; return this->read(sizes...); } @@ -294,9 +329,10 @@ class deserializer { * Return an `std::vector` * @tparam Ret The type to return. * @tparam Size an integral type. - * @tparam Sizes types of additional inner containers + * @tparam Sizes integral types. * @param m The size of the vector. - * @param dims a possible set of inner container sizes passed to subsequent `read` functions. + * @param dims a possible set of inner container sizes passed to subsequent + * `read` functions. */ template * = nullptr> @@ -304,11 +340,10 @@ class deserializer { if (unlikely(m == 0)) { return Ret(); } else { - using ret_value_type = value_type_t; - Ret ret_vec; + std::decay_t ret_vec; ret_vec.reserve(m); for (Size i = 0; i < m; ++i) { - ret_vec.emplace_back(this->read(dims...)); + ret_vec.emplace_back(this->read>(dims...)); } return ret_vec; } @@ -328,25 +363,72 @@ class deserializer { * @throw std::runtime_error if the scalar is less than the * specified lower bound */ - template + template * = nullptr> auto read_lb(const LB& lb, Sizes... sizes) { - using stan::math::check_greater_or_equal; auto ret = this->read(sizes...); - check_greater_or_equal("io deserializer", "Lower Bound", ret, lb); + using stan::math::check_greater_or_equal; + using stan::math::value_of; + check_greater_or_equal("io deserializer", "Lower Bound", value_of(ret), + value_of(lb)); + return ret; + } + + /** + * Overload for `std::vector` return type and a non-`std::vector` lower bound. + * @tparam Ret The type to return. + * @tparam LB Type of lower bound. + * @tparam Sizes A pack of possible sizes to construct the object from. + * @param lb Lower bound. + * @param sizes a pack of sizes to use to construct the return. + * @throw std::runtime_error if the scalar is less than the + * specified lower bound + */ + template * = nullptr> + auto read_lb(const LB& lb, size_t vecsize, Sizes... sizes) { + std::decay_t ret; + ret.reserve(vecsize); + for (size_t i = 0; i < vecsize; ++i) { + ret.emplace_back(this->read_lb>(lb, sizes...)); + } + return ret; + } + + /** + * Overload for `std::vector` return type and a `std::vector` lower bound. + * @tparam Ret The type to return. + * @tparam LB Type of lower bound. + * @tparam Sizes A pack of possible sizes to construct the object from. + * @param lb Lower bound. + * @param sizes a pack of sizes to use to construct the return. + * @throw std::runtime_error if the scalar is less than the + * specified lower bound + */ + template * = nullptr> + auto read_lb(const std::vector& lb, size_t vecsize, Sizes... sizes) { + std::decay_t ret; + ret.reserve(vecsize); + for (size_t i = 0; i < vecsize; ++i) { + ret.emplace_back(this->read_lb>(lb[i], sizes...)); + } return ret; } /** - * Return the next scalar transformed to have the specified + * Return the next object transformed to have the specified * lower bound, possibly incrementing the specified reference with the * log of the absolute Jacobian determinant of the transform. * *

See stan::math::lb_constrain(T,double,T&). * * @tparam Ret The type to return. - * @tparam Jacobian Whether to increment the log of the absolute Jacobian determinant of the transform. + * @tparam Jacobian Whether to increment the log of the absolute Jacobian + * determinant of the transform. * @tparam LB Type of lower bound. * @tparam LP Type of log prob. + * @tparam Sizes A pack of possible sizes to construct the object from. * @param lb Lower bound on result. * @param lp Reference to log probability variable to increment. * @param sizes a pack of sizes to use to construct the return. @@ -369,15 +451,66 @@ class deserializer { * * @tparam Ret The type to return. * @tparam UB Type of upper bound. + * @tparam Sizes A parameter pack of integral types. * @param ub Lower bound. + * @param sizes A parameter pack of dimensions. * @throw std::runtime_error if the scalar is less than the * specified lower bound */ - template + template * = nullptr> auto read_ub(const UB& ub, Sizes... sizes) { - using stan::math::check_less_or_equal; auto ret = this->read(sizes...); - check_less_or_equal("io deserializer", "Upper Bound", ret, ub); + using stan::math::check_less_or_equal; + using stan::math::value_of; + check_less_or_equal("io deserializer", "Upper Bound", value_of(ret), + value_of(ub)); + return ret; + } + + /** + * Specialization for `std::vector` return type and non-`std::vector` lower + * bound. + * @tparam Ret The type to return. + * @tparam UB Type of upper bound. + * @tparam Sizes A parameter pack of integral types. + * @param ub Lower bound. + * @param vecsize The size of the return `std::vector`. + * @param sizes A parameter pack of dimensions. + * @throw std::runtime_error if the scalar is less than the + * specified lower bound + */ + template * = nullptr> + auto read_ub(const UB& ub, size_t vecsize, Sizes... sizes) { + std::decay_t ret; + ret.reserve(vecsize); + for (size_t i = 0; i < vecsize; ++i) { + ret.emplace_back(this->read_ub>(ub, sizes...)); + } + return ret; + } + + /** + * Specialization for `std::vector` return type and an `std::vector` lower + * bound. + * @tparam Ret The type to return. + * @tparam UB Type of upper bound. + * @tparam Sizes A parameter pack of integral types. + * @param ub Lower bound. + * @param vecsize The size of the return `std::vector`. + * @param sizes A parameter pack of dimensions. + * @throw std::runtime_error if the scalar is less than the + * specified lower bound + */ + template * = nullptr> + auto read_ub(const std::vector& ub, size_t vecsize, Sizes... sizes) { + std::decay_t ret; + ret.reserve(vecsize); + for (size_t i = 0; i < vecsize; ++i) { + ret.emplace_back(this->read_ub>(ub[i], sizes...)); + } return ret; } @@ -389,7 +522,8 @@ class deserializer { *

See stan::math::ub_constrain(T,double,T&). * * @tparam Ret The type to return. - * @tparam Jacobian Whether to increment the log of the absolute Jacobian determinant of the transform. + * @tparam Jacobian Whether to increment the log of the absolute Jacobian + * determinant of the transform. * @tparam UB Type of upper bound. * @tparam LP Type of log prob. * @param ub Upper bound on result. @@ -415,17 +549,131 @@ class deserializer { * @tparam Ret The type to return. * @tparam LB Type of lower bound. * @tparam UB Type of upper bound. + * @tparam Sizes A parameter pack of integral types. * @param lb Lower bound. * @param ub Upper bound. + * @param sizes The dimensions for the inner type. * @throw std::runtime_error if the scalar is not between the specified * lower and upper bounds. */ - template + template * = nullptr> auto read_lub(const LB& lb, const UB& ub, Sizes... sizes) { - using stan::math::check_bounded; auto ret = this->read(sizes...); - check_bounded("io deserializer", "Upper and Lower Bound", ret, - lb, ub); + using stan::math::check_bounded; + using stan::math::value_of; + check_bounded( + "io deserializer", "Upper and Lower Bound", value_of(ret), value_of(lb), + value_of(ub)); + return ret; + } + + /** + * Specialization for `lub` constrain with an `std::vector` return type + * and non-`std::vector` lower and upper bounds. + * + * @tparam Ret The type to return. + * @tparam LB Type of lower bound. + * @tparam UB Type of upper bound. + * @tparam Sizes A parameter pack of integral types. + * @param lb Lower bound. + * @param ub Upper bound. + * @param vecsize The size of the return `std::vector` + * @param sizes The dimensions for the inner type. + * @throw std::runtime_error if the scalar is not between the specified + * lower and upper bounds. + */ + template * = nullptr> + auto read_lub(const LB& lb, const UB& ub, size_t vecsize, Sizes... sizes) { + std::decay_t ret; + ret.reserve(vecsize); + for (size_t i = 0; i < vecsize; ++i) { + ret.emplace_back(this->read_lub>(lb, ub, sizes...)); + } + return ret; + } + + /** + * Specialization for `lub` constrain with an `std::vector` return type + * with `std::vector` lower bound and non-`std::vector` upper bound. + * + * @tparam Ret The type to return. + * @tparam LB Type of lower bound. + * @tparam UB Type of upper bound. + * @tparam Sizes A parameter pack of integral types. + * @param lb Lower bound. + * @param ub Upper bound. + * @param vecsize The size of the return `std::vector` + * @param sizes The dimensions for the inner type. + * @throw std::runtime_error if the scalar is not between the specified + * lower and upper bounds. + */ + template * = nullptr> + auto read_lub(const std::vector& lb, const UB& ub, size_t vecsize, + Sizes... sizes) { + std::decay_t ret; + ret.reserve(vecsize); + for (size_t i = 0; i < vecsize; ++i) { + ret.emplace_back(this->read_lub>(lb[i], ub, sizes...)); + } + return ret; + } + + /** + * Specialization for `lub` constrain with an `std::vector` return type + * with a non-`std::vector` lower bound and an `std::vector` upper bound. + * + * @tparam Ret The type to return. + * @tparam LB Type of lower bound. + * @tparam UB Type of upper bound. + * @tparam Sizes A parameter pack of integral types. + * @param lb Lower bound. + * @param ub Upper bound. + * @param vecsize The size of the return `std::vector` + * @param sizes The dimensions for the inner type. + * @throw std::runtime_error if the scalar is not between the specified + * lower and upper bounds. + */ + template * = nullptr> + auto read_lub(const LB& lb, const std::vector& ub, size_t vecsize, + Sizes... sizes) { + std::decay_t ret; + ret.reserve(vecsize); + for (size_t i = 0; i < vecsize; ++i) { + ret.emplace_back(this->read_lub>(lb, ub[i], sizes...)); + } + return ret; + } + + /** + * Specialization for `lub` constrain with an `std::vector` return type + * with `std::vector` lower bound and upper bound. + * + * @tparam Ret The type to return. + * @tparam LB Type of lower bound. + * @tparam UB Type of upper bound. + * @tparam Sizes A parameter pack of integral types. + * @param lb Lower bound. + * @param ub Upper bound. + * @param vecsize The size of the return `std::vector` + * @param sizes The dimensions for the inner type. + * @throw std::runtime_error if the scalar is not between the specified + * lower and upper bounds. + */ + template * = nullptr> + auto read_lub(const std::vector& lb, const std::vector& ub, + size_t vecsize, Sizes... sizes) { + std::decay_t ret; + ret.reserve(vecsize); + for (size_t i = 0; i < vecsize; ++i) { + ret.emplace_back( + this->read_lub>(lb[i], ub[i], sizes...)); + } return ret; } @@ -436,13 +684,16 @@ class deserializer { *

See stan::math::lub_constrain(T, double, double, T&). * * @tparam Ret The type to return. - * @tparam Jacobian Whether to increment the log of the absolute Jacobian determinant of the transform. - * @tparam T Type of scalar. + * @tparam Jacobian Whether to increment the log of the absolute Jacobian + * determinant of the transform. * @tparam LB Type of lower bound. * @tparam UB Type of upper bound. + * @tparam LP Type of log probability. + * @tparam Sizes A parameter pack of integral types. * @param lb Lower bound. * @param ub Upper bound. * @param lp Reference to log probability variable to increment. + * @param sizes Pack of integrals to use to construct the return's type. */ template @@ -459,14 +710,18 @@ class deserializer { * *

See stan::math::check_positive(T). * - * @return Next positive scalar. + * @tparam Ret The type to return. + * @tparam Sizes A parameter pack of integral types. + * @param sizes Pack of integrals to use to construct the return's type. + * * @throw std::runtime_error if x is not positive */ template - auto read_pos(const Sizes&... sizes) { + auto read_pos(Sizes... sizes) { auto ret = read(sizes...); - stan::math::check_positive("deserializer", "Positive Constrained", - ret); + using stan::math::check_positive; + using stan::math::value_of; + check_positive("deserializer", "Positive Constrained", value_of(ret)); return ret; } @@ -477,11 +732,17 @@ class deserializer { * *

See stan::math::positive_constrain(T,T&). * + * @tparam Ret The type to return. + * @tparam Jacobian Whether to increment the log of the absolute Jacobian + * determinant of the transform. + * @tparam LP Type of log probability. + * @tparam Sizes A parameter pack of integral types. * @param lp Reference to log probability variable to increment. + * @param sizes Pack of integrals to use to construct the return's type. */ template * = nullptr> - auto read_pos(LP& lp, const Sizes&... sizes) { + auto read_pos(LP& lp, Sizes... sizes) { if (Jacobian) { return stan::math::positive_constrain(this->read(sizes...), lp); } else { @@ -492,47 +753,71 @@ class deserializer { /** * Specialization for `std::vector` that calls itself recursivly for * each element. + * @tparam Ret The type to return. + * @tparam Jacobian Whether to increment the log of the absolute Jacobian + * determinant of the transform. + * @tparam LP Type of log probability. + * @tparam Sizes A parameter pack of integral types. + * @param vecsize Size of the return vector. + * @param lp Reference to log probability variable to increment. + * @param sizes Pack of integrals to use to construct the return's type. */ template * = nullptr> - auto read_pos(LP& lp, const size_t vecsize, const Sizes&... sizes) { - using stan::math::positive_constrain; - using ret_value_t = value_type_t; + auto read_pos(LP& lp, const size_t vecsize, Sizes... sizes) { std::decay_t ret; + ret.reserve(vecsize); for (size_t i = 0; i < vecsize; ++i) { - ret.emplace_back(this->read_pos(lp, sizes...)); + ret.emplace_back( + this->read_pos, Jacobian>(lp, sizes...)); } return ret; } /** * This is just returns the requested type as there's nothing to check. + * @tparam Ret The type to return. + * @tparam Jacobian Whether to increment the log of the absolute Jacobian + * determinant of the transform. + * @tparam Offset Type of offset. + * @tparam Mult Type of multiplier. + * @tparam Sizes A parameter pack of integral types. + * @param offset Offset. + * @param multiplier Multiplier. + * @param sizes Pack of integrals to use to construct the return's type. */ template auto read_offset_multiplier(const Offset& offset, const Mult& multiplier, - const Sizes&... sizes) { + Sizes... sizes) { return read(sizes...); } /** - * Return the next scalar transformed to have the specified offset and + * Return the next object transformed to have the specified offset and * multiplier. * *

See stan::math::offset_multiplier_constrain(T, double, * double). * - * @tparam TL Type of offset. - * @tparam TS Type of multiplier. + * @tparam Ret The type to return. + * @tparam Jacobian Whether to increment the log of the absolute Jacobian + * determinant of the transform. + * @tparam Offset Type of offset. + * @tparam Mult Type of multiplier. + * @tparam LP Type of log probability. + * @tparam Sizes A parameter pack of integral types. * @param offset Offset. * @param multiplier Multiplier. - * @return Next scalar transformed to fall between the specified + * @param lp Reference to log probability variable to increment. + * @param sizes Pack of integrals to use to construct the return's type. + * @return Next object transformed to fall between the specified * bounds. */ template * = nullptr> - auto read_offset_multiplier(const Offset& offset, const Mult& multiplier, LP& lp, - const Sizes&... sizes) { + auto read_offset_multiplier(const Offset& offset, const Mult& multiplier, + LP& lp, Sizes... sizes) { using stan::math::offset_multiplier_constrain; if (Jacobian) { return offset_multiplier_constrain(this->read(sizes...), offset, @@ -544,64 +829,192 @@ class deserializer { } /** - * Return the next scalar transformed to have the specified offset and - * multiplier. + * Specialization of offset multiplier for `std::vector` with + * non-`std::vector` offset and multiplier. * *

See stan::math::offset_multiplier_constrain(T, double, * double). * - * @tparam TL Type of offset. - * @tparam TS Type of multiplier. + * @tparam Ret The type to return. + * @tparam Jacobian Whether to increment the log of the absolute Jacobian + * determinant of the transform. + * @tparam Offset Type of offset. + * @tparam Mult Type of multiplier. + * @tparam LP Type of log probability. + * @tparam Sizes A parameter pack of integral types. * @param offset Offset. * @param multiplier Multiplier. - * @return Next scalar transformed to fall between the specified + * @param lp Reference to log probability variable to increment. + * @param vecsize The size of the return vector. + * @param sizes Pack of integrals to use to construct the return's type. * bounds. */ template * = nullptr> auto read_offset_multiplier(const Offset& offset, const Mult& multiplier, - LP& lp, const size_t vecsize, - const Sizes&... sizes) { - using stan::math::offset_multiplier_constrain; - using ret_value_t = value_type_t; + LP& lp, const size_t vecsize, Sizes... sizes) { + std::decay_t ret; + ret.reserve(vecsize); + for (size_t i = 0; i < vecsize; ++i) { + ret.emplace_back( + this->read_offset_multiplier, Jacobian>( + offset, multiplier, lp, sizes...)); + } + return ret; + } + + /** + * Specialization of offset multiplier for `std::vector` with `std::vector` + * offset and multiplier. + * + *

See stan::math::offset_multiplier_constrain(T, double, + * double). + * + * @tparam Ret The type to return. + * @tparam Jacobian Whether to increment the log of the absolute Jacobian + * determinant of the transform. + * @tparam Offset Type of offset. + * @tparam Mult Type of multiplier. + * @tparam LP Type of log probability. + * @tparam Sizes A parameter pack of integral types. + * @param offset Offset. + * @param multiplier Multiplier. + * @param lp Reference to log probability variable to increment. + * @param vecsize The size of the return vector. + * @param sizes Pack of integrals to use to construct the return's type. + * bounds. + */ + template * = nullptr> + auto read_offset_multiplier(const std::vector& offset, + const std::vector& multiplier, LP& lp, + const size_t vecsize, Sizes... sizes) { + std::decay_t ret; + ret.reserve(vecsize); + for (size_t i = 0; i < vecsize; ++i) { + ret.emplace_back( + this->read_offset_multiplier, Jacobian>( + offset[i], multiplier[i], lp, sizes...)); + } + return ret; + } + + /** + * Specialization of offset multiplier for `std::vector` with `std::vector` + * offset and non-`std::vector` multiplier. + * + *

See stan::math::offset_multiplier_constrain(T, double, + * double). + * + * @tparam Ret The type to return. + * @tparam Jacobian Whether to increment the log of the absolute Jacobian + * determinant of the transform. + * @tparam Offset Type of offset. + * @tparam Mult Type of multiplier. + * @tparam LP Type of log probability. + * @tparam Sizes A parameter pack of integral types. + * @param offset Offset. + * @param multiplier Multiplier. + * @param lp Reference to log probability variable to increment. + * @param vecsize The size of the return vector. + * @param sizes Pack of integrals to use to construct the return's type. + * bounds. + */ + template * = nullptr> + auto read_offset_multiplier(const std::vector& offset, + const Mult& multiplier, LP& lp, + const size_t vecsize, Sizes... sizes) { std::decay_t ret; + ret.reserve(vecsize); for (size_t i = 0; i < vecsize; ++i) { - ret.emplace_back(this->read_offset_multiplier( - offset, multiplier, lp, sizes...)); + ret.emplace_back( + this->read_offset_multiplier, Jacobian>( + offset[i], multiplier, lp, sizes...)); } return ret; } /** - * Return the next scalar, checking that it is a valid value for + * Specialization of offset multiplier for `std::vector` with + * non-`std::vector` offset and `std::vector` multiplier. + * + *

See stan::math::offset_multiplier_constrain(T, double, + * double). + * + * @tparam Ret The type to return. + * @tparam Jacobian Whether to increment the log of the absolute Jacobian + * determinant of the transform. + * @tparam Offset Type of offset. + * @tparam Mult Type of multiplier. + * @tparam LP Type of log probability. + * @tparam Sizes A parameter pack of integral types. + * @param offset Offset. + * @param multiplier Multiplier. + * @param lp Reference to log probability variable to increment. + * @param vecsize The size of the return vector. + * @param sizes Pack of integrals to use to construct the return's type. + * bounds. + */ + template * = nullptr> + auto read_offset_multiplier(const Offset& offset, + const std::vector& multiplier, LP& lp, + const size_t vecsize, Sizes... sizes) { + std::decay_t ret; + ret.reserve(vecsize); + for (size_t i = 0; i < vecsize; ++i) { + ret.emplace_back( + this->read_offset_multiplier, Jacobian>( + offset, multiplier[i], lp, sizes...)); + } + return ret; + } + + /** + * Return the next object, checking that it is a valid value for * a probability, between 0 (inclusive) and 1 (inclusive). * *

See stan::math::check_bounded(T). * + * @tparam Ret The type to return. + * @tparam Sizes A parameter pack of integral types. + * @param sizes Pack of integrals to use to construct the return's type. * @return Next probability value. */ template - auto read_prob(const Sizes&... sizes) { + auto read_prob(Sizes... sizes) { auto ret = read(sizes...); - stan::math::check_bounded( - "deserializer", "Constrained probability", ret, 0, 1); + using stan::math::check_bounded; + using stan::math::value_of; + check_bounded( + "deserializer", "Constrained probability", value_of(ret), 0, 1); return ret; } /** - * Return the next scalar transformed to be a probability + * Return the next object transformed to be a probability * between 0 and 1, incrementing the specified reference with * the log of the absolute Jacobian determinant. * *

See stan::math::prob_constrain(T). * + * @tparam Ret The type to return. + * @tparam Jacobian Whether to increment the log of the absolute Jacobian + * determinant of the transform. + * @tparam LP Type of log probability. + * @tparam Sizes A parameter pack of integral types. * @param lp Reference to log probability variable to increment. + * @param sizes Pack of integrals to use to construct the return's type. * @return The next scalar transformed to a probability. */ template * = nullptr> - auto read_prob(LP& lp, const Sizes&... sizes) { + auto read_prob(LP& lp, Sizes... sizes) { if (Jacobian) { return stan::math::prob_constrain(this->read(sizes...), lp); } else { @@ -609,73 +1022,108 @@ class deserializer { } } - /** - * Return the next scalar transformed to be a probability - * between 0 and 1, incrementing the specified reference with - * the log of the absolute Jacobian determinant. + * Specialization of `read_prob` for returning an `std::vector`. * *

See stan::math::prob_constrain(T). * + * @tparam Ret The type to return. + * @tparam Jacobian Whether to increment the log of the absolute Jacobian + * determinant of the transform. + * @tparam LP Type of log probability. + * @tparam Sizes A parameter pack of integral types. * @param lp Reference to log probability variable to increment. + * @param sizes Pack of integrals to use to construct the return's type. * @return The next scalar transformed to a probability. */ template * = nullptr> - auto read_prob(LP& lp, const size_t vecsize, const Sizes&... sizes) { - using stan::math::prob_constrain; - using ret_value_t = value_type_t; + auto read_prob(LP& lp, const size_t vecsize, Sizes... sizes) { std::decay_t ret; + ret.reserve(vecsize); for (size_t i = 0; i < vecsize; ++i) { - ret.emplace_back(this->read_prob(lp, sizes...)); + ret.emplace_back( + this->read_prob, Jacobian>(lp, sizes...)); } return ret; } /** - * Return the next scalar, checking that it is a valid + * Return the next object, checking that it is a valid * value for a correlation, between -1 (inclusive) and * 1 (inclusive). * *

See stan::math::check_bounded(T). * + * @tparam Ret The type to return. + * @tparam Sizes A parameter pack of integral types. + * @param sizes Pack of integrals to use to construct the return's type. * @return Next correlation value. * @throw std::runtime_error if the value is not valid * for a correlation */ template * = nullptr> - auto read_corr(const Sizes&... sizes) { + require_not_matrix_t* = nullptr, + require_not_std_vector_t* = nullptr> + auto read_corr(Sizes... sizes) { auto ret = read(sizes...); - stan::math::check_bounded( - "deserializer", "Correlation value", ret, -1, 1); + using stan::math::check_bounded; + using stan::math::value_of; + check_bounded( + "deserializer", "Correlation value", value_of(ret), -1, 1); return ret; } /** - * Returns the next correlation matrix of the specified dimensionality. - * - *

See stan::math::check_corr_matrix(Matrix). - * - * @param k Dimensionality of correlation matrix. - * @return Next correlation matrix of the specified dimensionality. - * @throw std::runtime_error if the matrix is not a correlation matrix + * Specialization of `read_corr` for `std::vector` returns + * @tparam Ret The type to return. + * @tparam Sizes A parameter pack of integral types. + * @param sizes Pack of integrals to use to construct the return's type. + * @return Next correlation value. + * @throw std::runtime_error if the value is not valid + * for a correlation + */ + template * = nullptr> + auto read_corr(size_t vecsize, Sizes... sizes) { + std::decay_t ret; + ret.reserve(vecsize); + for (size_t i = 0; i < vecsize; ++i) { + ret.emplace_back(this->read_corr>(sizes...)); + } + return ret; + } + + /** + * Specialization of `read_corr` for matrix returns + * @tparam Ret The type to return. + * @param k the rows and column size of the return matrix. + * @throw std::runtime_error if the value is not valid + * for a correlation */ template * = nullptr> auto read_corr(size_t k) { - using stan::math::check_corr_matrix; auto ret = read(k, k); - check_corr_matrix("stan::math::corr_matrix", "Constrained matrix", ret); + using stan::math::check_corr_matrix; + using stan::math::value_of; + check_corr_matrix("stan::math::corr_matrix", "Constrained matrix", + value_of(ret)); return ret; } /** - * Return the next scalar transformed to be a (partial) + * Return the next object transformed to be a (partial) * correlation between -1 and 1, incrementing the specified * reference with the log of the absolute Jacobian determinant. * *

See stan::math::corr_constrain(T,T&). * + * @tparam Ret The type to return. + * @tparam Jacobian Whether to increment the log of the absolute Jacobian + * determinant of the transform. + * @tparam LP Type of log probability. + * @tparam Sizes A parameter pack of integral types. + * @param sizes Pack of integrals to use to construct the return's type. * @param lp The reference to the variable holding the log * probability to increment. * @return The next scalar transformed to a correlation. @@ -683,7 +1131,7 @@ class deserializer { template * = nullptr, require_not_matrix_t* = nullptr> - auto read_corr(LP& lp, const Sizes&... sizes) { + auto read_corr(LP& lp, Sizes... sizes) { using stan::math::corr_constrain; if (Jacobian) { return corr_constrain(this->read(sizes...), lp); @@ -693,15 +1141,19 @@ class deserializer { } /** - * Return the next correlation matrix of the specified dimensionality, - * incrementing the specified reference with the log absolute Jacobian - * determinant. + * Return the next object transformed to be a (partial) + * correlation between -1 and 1, incrementing the specified + * reference with the log of the absolute Jacobian determinant. * - *

See stan::math::corr_matrix_constrain(Matrix,T&). + *

See stan::math::corr_constrain(T,T&). * - * @param k Dimensionality of the (square) correlation matrix. - * @param lp Log probability reference to increment. - * @return The next correlation matrix of the specified dimensionality. + * @tparam Ret The type to return. + * @tparam Jacobian Whether to increment the log of the absolute Jacobian + * determinant of the transform. + * @tparam LP Type of log probability. + * @param k Dimensions of matrix return type. + * @param lp The reference to the variable holding the log + * probability to increment. */ template * = nullptr, @@ -709,31 +1161,40 @@ class deserializer { auto read_corr(LP& lp, size_t k) { using stan::math::corr_matrix_constrain; if (Jacobian) { - return corr_matrix_constrain(this->read((k * (k - 1)) / 2), k, - lp); + return corr_matrix_constrain( + this->read>((k * (k - 1)) / 2), + k, lp); } else { - return corr_matrix_constrain(this->read((k * (k - 1)) / 2), k); + return corr_matrix_constrain( + this->read>((k * (k - 1)) / 2), + k); } } /** - * Return the next scalar transformed to be a (partial) - * correlation between -1 and 1, incrementing the specified - * reference with the log of the absolute Jacobian determinant. + * Specialization of `read_corr` for `std::vector` return types. * *

See stan::math::corr_constrain(T,T&). * + * @tparam Ret The type to return. + * @tparam Jacobian Whether to increment the log of the absolute Jacobian + * determinant of the transform. + * @tparam LP Type of log probability. + * @tparam Sizes A parameter pack of integral types. * @param lp The reference to the variable holding the log + * @param vecsize The size of the return vector. + * @param sizes Pack of integrals to use to construct the return's type. * probability to increment. * @return The next scalar transformed to a correlation. */ template * = nullptr> - auto read_corr(LP& lp, const size_t vecsize, const Sizes&... sizes) { - using ret_value_t = value_type_t; + auto read_corr(LP& lp, const size_t vecsize, Sizes... sizes) { std::decay_t ret; + ret.reserve(vecsize); for (size_t i = 0; i < vecsize; ++i) { - ret.emplace_back(this->read_corr(lp, sizes...)); + ret.emplace_back( + this->read_corr, Jacobian>(lp, sizes...)); } return ret; } @@ -744,6 +1205,7 @@ class deserializer { * *

See stan::math::check_unit_vector. * + * @tparam Ret The type to return. * @param k Size of returned unit_vector * @return unit_vector read from the specified size number of scalars * @throw std::runtime_error if the next k values is not a unit_vector @@ -752,21 +1214,27 @@ class deserializer { template * = nullptr> auto read_unit_vector(size_t k) { if (unlikely(k == 0)) { - std::string msg = "deserializer: unit vectors cannot be size 0."; - throw std::invalid_argument(msg); + []() STAN_COLD_PATH { + std::string msg = "deserializer: unit vectors cannot be size 0."; + throw std::invalid_argument(msg); + }(); } auto ret = read(k); - stan::math::check_unit_vector("deserializer", "Unit Vector", ret); + using stan::math::check_unit_vector; + using stan::math::value_of; + check_unit_vector("deserializer", "Unit Vector", value_of(ret)); return ret; } /** - * Return a unit_vector of the specified size made up of the - * next scalars. + * Specialization of `read_unit_vector` for an `std::vector` of unit vectors. * *

See stan::math::check_unit_vector. * - * @param k Size of returned unit_vector + * @tparam Ret The type to return. + * @tparam Sizes A parameter pack of integral types. + * @param sizes Pack of integrals to use to construct the return's type. + * @param vecsize The size of the return vector. * @return unit_vector read from the specified size number of scalars * @throw std::runtime_error if the next k values is not a unit_vector * @throw std::invalid_argument if k is zero @@ -774,10 +1242,10 @@ class deserializer { template * = nullptr> auto read_unit_vector(size_t vecsize, Sizes... sizes) { - using ret_value_t = value_type_t; std::decay_t ret; + ret.reserve(vecsize); for (size_t i = 0; i < vecsize; ++i) { - ret.emplace_back(this->read_unit_vector(sizes...)); + ret.emplace_back(this->read_unit_vector>(sizes...)); } return ret; } @@ -789,15 +1257,20 @@ class deserializer { * *

See stan::math::unit_vector_constrain(Eigen::Matrix,T&). * - * @param k Size of unit_vector. - * @param lp Log probability to increment with log absolute - * Jacobian determinant. + * @tparam Ret The type to return. + * @tparam Jacobian Whether to increment the log of the absolute Jacobian + * determinant of the transform. + * @tparam LP Type of log probability. + * @tparam Sizes A parameter pack of integral types. + * @param lp The reference to the variable holding the log + * @param sizes Pack of integrals to use to construct the return's type. + * probability to increment. * @return The next unit_vector of the specified size. * @throw std::invalid_argument if k is zero */ template * = nullptr> - auto read_unit_vector(LP& lp, const Sizes&... sizes) { + auto read_unit_vector(LP& lp, Sizes... sizes) { using stan::math::unit_vector_constrain; if (Jacobian) { return unit_vector_constrain(this->read(sizes...), lp); @@ -813,21 +1286,26 @@ class deserializer { * *

See stan::math::unit_vector_constrain(Eigen::Matrix,T&). * - * @param k Size of unit_vector. - * @param lp Log probability to increment with log absolute - * Jacobian determinant. + * @tparam Ret The type to return. + * @tparam Jacobian Whether to increment the log of the absolute Jacobian + * determinant of the transform. + * @tparam LP Type of log probability. + * @tparam Sizes A parameter pack of integral types. + * @param lp The reference to the variable holding the log + * @param vecsize The size of the return vector. + * @param sizes Pack of integrals to use to construct the return's type. + * probability to increment. * @return The next unit_vector of the specified size. * @throw std::invalid_argument if k is zero */ template * = nullptr> - auto read_unit_vector(LP& lp, const size_t vecsize, const Sizes&... sizes) { - using stan::math::unit_vector_constrain; - using ret_value_t = value_type_t; + auto read_unit_vector(LP& lp, const size_t vecsize, Sizes... sizes) { std::decay_t ret; + ret.reserve(vecsize); for (size_t i = 0; i < vecsize; ++i) { ret.emplace_back( - this->read_unit_vector(lp, sizes...)); + this->read_unit_vector, Jacobian>(lp, sizes...)); } return ret; } @@ -838,19 +1316,25 @@ class deserializer { * *

See stan::math::check_simplex. * + * @tparam Ret The type to return. * @param k Size of returned simplex. * @return Simplex read from the specified size number of scalars. * @throw std::runtime_error if the k values is not a simplex. * @throw std::invalid_argument if k is zero */ - template * = nullptr> + template * = nullptr, + require_not_std_vector_t* = nullptr> auto read_simplex(size_t k) { if (unlikely(k == 0)) { - std::string msg = "deserializer: simplex vectors cannot be size 0."; - throw std::invalid_argument(msg); + []() STAN_COLD_PATH { + std::string msg = "deserializer: simplex vectors cannot be size 0."; + throw std::invalid_argument(msg); + }(); } auto ret = read(k); - stan::math::check_simplex("deserializer", "Simplex", ret); + using stan::math::check_simplex; + using stan::math::value_of; + check_simplex("deserializer", "Simplex", value_of(ret)); return ret; } @@ -860,7 +1344,11 @@ class deserializer { * *

See stan::math::check_simplex. * - * @param k Size of returned simplex. + * @tparam Ret The type to return. + * @tparam Sizes A parameter pack of integral types. + * @param vecsize The size of the return vector. + * @param sizes Pack of integrals to use to construct the return's type. + * probability to increment. * @return Simplex read from the specified size number of scalars. * @throw std::runtime_error if the k values is not a simplex. * @throw std::invalid_argument if k is zero @@ -868,10 +1356,10 @@ class deserializer { template * = nullptr> auto read_simplex(size_t vecsize, Sizes... sizes) { - using ret_value_t = value_type_t; std::decay_t ret; + ret.reserve(vecsize); for (size_t i = 0; i < vecsize; ++i) { - ret.emplace_back(this->read_simplex(sizes...)); + ret.emplace_back(this->read_simplex>(sizes...)); } return ret; } @@ -883,15 +1371,20 @@ class deserializer { * *

See stan::math::simplex_constrain(Eigen::Matrix,T&). * - * @param k Size of simplex. - * @param lp Log probability to increment with log absolute - * Jacobian determinant. + * @tparam Ret The type to return. + * @tparam Jacobian Whether to increment the log of the absolute Jacobian + * determinant of the transform. + * @tparam LP Type of log probability. + * @tparam Sizes A parameter pack of integral types. + * @param lp The reference to the variable holding the log + * @param sizes Pack of integrals to use to construct the return's type. + * probability to increment. * @return The next simplex of the specified size. * @throws std::invalid_argument if number of dimensions (`k`) is zero */ template * = nullptr> - auto read_simplex(LP& lp, const Sizes&... sizes) { + auto read_simplex(LP& lp, Sizes... sizes) { using stan::math::simplex_constrain; if (Jacobian) { return simplex_constrain(this->read(sizes...), lp); @@ -907,20 +1400,26 @@ class deserializer { * *

See stan::math::simplex_constrain(Eigen::Matrix,T&). * - * @param k Size of simplex. - * @param lp Log probability to increment with log absolute - * Jacobian determinant. + * @tparam Ret The type to return. + * @tparam Jacobian Whether to increment the log of the absolute Jacobian + * determinant of the transform. + * @tparam LP Type of log probability. + * @tparam Sizes A parameter pack of integral types. + * @param lp The reference to the variable holding the log + * @param vecsize The size of the return vector. + * @param sizes Pack of integrals to use to construct the return's type. + * probability to increment. * @return The next simplex of the specified size. * @throws std::invalid_argument if number of dimensions (`k`) is zero */ template * = nullptr> - auto read_simplex(LP& lp, const size_t vecsize, const Sizes&... sizes) { - using stan::math::simplex_constrain; - using ret_value_t = value_type_t; + auto read_simplex(LP& lp, const size_t vecsize, Sizes... sizes) { std::decay_t ret; + ret.reserve(vecsize); for (size_t i = 0; i < vecsize; ++i) { - ret.emplace_back(this->read_simplex(lp, sizes...)); + ret.emplace_back( + this->read_simplex, Jacobian>(lp, sizes...)); } return ret; } @@ -932,14 +1431,44 @@ class deserializer { *

See stan::math::check_ordered(T) for * behavior on failure. * - * @param k Size of returned vector. + * @tparam Ret The type to return. + * @tparam Sizes A parameter pack of integral types. + * @param sizes Pack of integrals to use to construct the return's type. + * probability to increment. * @return Vector of positive values in ascending order. */ - template - auto read_ordered(const Sizes&... sizes) { - using stan::math::check_ordered; + template * = nullptr> + auto read_ordered(Sizes... sizes) { auto ret = read(sizes...); - check_ordered("deserializer", "Ordered", ret); + using stan::math::check_ordered; + using stan::math::value_of; + check_ordered("deserializer", "Ordered", value_of(ret)); + return ret; + } + + /** + * Return the next vector of specified size containing + * values in ascending order. + * + *

See stan::math::check_ordered(T) for + * behavior on failure. + * + * @tparam Ret The type to return. + * @tparam Sizes A parameter pack of integral types. + * @param vecsize The size of the return vector. + * @param sizes Pack of integrals to use to construct the return's type. + * probability to increment. + * @return Vector of positive values in ascending order. + */ + template * = nullptr> + auto read_ordered(size_t vecsize, Sizes... sizes) { + std::decay_t ret; + ret.reserve(vecsize); + for (size_t i = 0; i < vecsize; ++i) { + ret.emplace_back(this->read_ordered>(sizes...)); + } return ret; } @@ -950,13 +1479,19 @@ class deserializer { * *

See stan::math::ordered_constrain(Matrix,T&). * - * @param k Size of vector. - * @param lp Log probability reference to increment. + * @tparam Ret The type to return. + * @tparam Jacobian Whether to increment the log of the absolute Jacobian + * determinant of the transform. + * @tparam LP Type of log probability. + * @tparam Sizes A parameter pack of integral types. + * @param lp The reference to the variable holding the log + * @param sizes Pack of integrals to use to construct the return's type. + * probability to increment. * @return Next ordered vector of the specified size. */ template * = nullptr> - auto read_ordered(LP& lp, const Sizes&... sizes) { + auto read_ordered(LP& lp, Sizes... sizes) { using stan::math::ordered_constrain; if (Jacobian) { return ordered_constrain(this->read(sizes...), lp); @@ -972,18 +1507,25 @@ class deserializer { * *

See stan::math::ordered_constrain(Matrix,T&). * - * @param k Size of vector. - * @param lp Log probability reference to increment. + * @tparam Ret The type to return. + * @tparam Jacobian Whether to increment the log of the absolute Jacobian + * determinant of the transform. + * @tparam Sizes A parameter pack of integral types. + * @tparam LP Type of log probability. + * @param lp The reference to the variable holding the log + * @param vecsize The size of the return vector. + * @param sizes Pack of integrals to use to construct the return's type. + * probability to increment. * @return Next ordered vector of the specified size. */ template * = nullptr> - auto read_ordered(LP& lp, const size_t vecsize, const Sizes&... sizes) { - using stan::math::ordered_constrain; - using ret_value_t = value_type_t; + auto read_ordered(LP& lp, const size_t vecsize, Sizes... sizes) { std::decay_t ret; + ret.reserve(vecsize); for (size_t i = 0; i < vecsize; ++i) { - ret.emplace_back(this->read_ordered(lp, sizes...)); + ret.emplace_back( + this->read_ordered, Jacobian>(lp, sizes...)); } return ret; } @@ -995,14 +1537,45 @@ class deserializer { *

See stan::math::check_positive_ordered(T) for * behavior on failure. * - * @param k Size of returned vector. + * @tparam Ret The type to return. + * @tparam Sizes A parameter pack of integral types. + * @param sizes Pack of integrals to use to construct the return's type. + * probability to increment. * @return Vector of positive values in ascending order. */ - template - auto read_positive_ordered(const Sizes&... sizes) { - using stan::math::check_positive_ordered; + template * = nullptr> + auto read_positive_ordered(Sizes... sizes) { auto ret = read(sizes...); - check_positive_ordered("deserializer", "Positive Ordered", ret); + using stan::math::check_positive_ordered; + using stan::math::value_of; + check_positive_ordered("deserializer", "Positive Ordered", value_of(ret)); + return ret; + } + + /** + * Return the next vector of specified size containing + * positive values in ascending order. + * + *

See stan::math::check_positive_ordered(T) for + * behavior on failure. + * + * @tparam Ret The type to return. + * @tparam Sizes A parameter pack of integral types. + * @param vecsize The size of the return vector. + * @param sizes Pack of integrals to use to construct the return's type. + * probability to increment. + * @return Vector of positive values in ascending order. + */ + template * = nullptr> + auto read_positive_ordered(size_t vecsize, Sizes... sizes) { + std::decay_t ret; + ret.reserve(vecsize); + for (size_t i = 0; i < vecsize; ++i) { + ret.emplace_back( + this->read_positive_ordered>(sizes...)); + } return ret; } @@ -1013,13 +1586,20 @@ class deserializer { * *

See stan::math::positive_ordered_constrain(Matrix,T&). * - * @param k Size of vector. - * @param lp Log probability reference to increment. + * @tparam Ret The type to return. + * @tparam Jacobian Whether to increment the log of the absolute Jacobian + * determinant of the transform. + * @tparam Sizes A parameter pack of integral types. + * @tparam LP Type of log probability. + * @param lp The reference to the variable holding the log + * @param vecsize The size of the return vector. + * @param sizes Pack of integrals to use to construct the return's type. + * probability to increment. * @return Next positive_ordered vector of the specified size. */ template * = nullptr> - auto read_positive_ordered(LP& lp, const Sizes&... sizes) { + auto read_positive_ordered(LP& lp, Sizes... sizes) { using stan::math::positive_ordered_constrain; if (Jacobian) { return positive_ordered_constrain(this->read(sizes...), lp); @@ -1035,20 +1615,25 @@ class deserializer { * *

See stan::math::positive_ordered_constrain(Matrix,T&). * - * @param k Size of vector. - * @param lp Log probability reference to increment. + * @tparam Ret The type to return. + * @tparam Jacobian Whether to increment the log of the absolute Jacobian + * determinant of the transform. + * @tparam Sizes A parameter pack of integral types. + * @tparam LP Type of log probability. + * @param lp The reference to the variable holding the log + * @param vecsize The size of the return vector. + * @param sizes Pack of integrals to use to construct the return's type. + * probability to increment. * @return Next positive_ordered vector of the specified size. */ template * = nullptr> - auto read_positive_ordered(LP& lp, const size_t vecsize, - const Sizes&... sizes) { - using stan::math::positive_ordered_constrain; - using ret_value_t = value_type_t; + auto read_positive_ordered(LP& lp, const size_t vecsize, Sizes... sizes) { std::decay_t ret; + ret.reserve(vecsize); for (size_t i = 0; i < vecsize; ++i) { - ret.emplace_back( - this->read_positive_ordered(lp, sizes...)); + ret.emplace_back(this->read_positive_ordered, Jacobian>( + lp, sizes...)); } return ret; } @@ -1057,6 +1642,7 @@ class deserializer { * Return the next Cholesky factor with the specified * dimensionality, reading it directly without transforms. * + * @tparam Ret The type to return. * @param M Rows of Cholesky factor * @param N Columns of Cholesky factor * @return Next Cholesky factor. @@ -1065,9 +1651,10 @@ class deserializer { */ template * = nullptr> auto read_cholesky_factor_cov(size_t M, size_t N) { - using stan::math::check_cholesky_factor; auto ret = read(M, N); - check_cholesky_factor("deserializer", "Cholesky Factor Cov", ret); + using stan::math::check_cholesky_factor; + using stan::math::value_of; + check_cholesky_factor("deserializer", "Cholesky Factor Cov", value_of(ret)); return ret; } @@ -1075,8 +1662,11 @@ class deserializer { * Return the next Cholesky factor with the specified * dimensionality, reading it directly without transforms. * - * @param M Rows of Cholesky factor - * @param N Columns of Cholesky factor + * @tparam Ret The type to return. + * @tparam Sizes A parameter pack of integral types. + * @param vecsize The size of the return vector. + * @param sizes Pack of integrals to use to construct the return's type. + * probability to increment. * @return Next Cholesky factor. * @throw std::domain_error if the matrix is not a valid * Cholesky factor. @@ -1084,10 +1674,11 @@ class deserializer { template * = nullptr> auto read_cholesky_factor_cov(size_t vecsize, Sizes... sizes) { - using ret_value_t = value_type_t; std::decay_t ret; + ret.reserve(vecsize); for (size_t i = 0; i < vecsize; ++i) { - ret.emplace_back(this->read_cholesky_factor_cov(sizes...)); + ret.emplace_back( + this->read_cholesky_factor_cov>(sizes...)); } return ret; } @@ -1098,9 +1689,13 @@ class deserializer { * appropriate size, and increment the log probability reference * with the log Jacobian adjustment for the transform. * + * @tparam Ret The type to return. + * @tparam Jacobian Whether to increment the log of the absolute Jacobian + * determinant of the transform. + * @tparam LP Type of log probability. + * @param lp The reference to the variable holding the log * @param M Rows of Cholesky factor * @param N Columns of Cholesky factor - * @param[in,out] lp log probability * @return Next Cholesky factor. * @throw std::domain_error if the matrix is not a valid * Cholesky factor. @@ -1110,10 +1705,14 @@ class deserializer { auto read_cholesky_factor_cov(LP& lp, size_t M, size_t N) { if (Jacobian) { return stan::math::cholesky_factor_constrain( - this->read((N * (N + 1)) / 2 + (M - N) * N), M, N, lp); + this->read>((N * (N + 1)) / 2 + + (M - N) * N), + M, N, lp); } else { return stan::math::cholesky_factor_constrain( - this->read((N * (N + 1)) / 2 + (M - N) * N), M, N); + this->read>((N * (N + 1)) / 2 + + (M - N) * N), + M, N); } } @@ -1123,22 +1722,28 @@ class deserializer { * appropriate size, and increment the log probability reference * with the log Jacobian adjustment for the transform. * - * @param M Rows of Cholesky factor - * @param N Columns of Cholesky factor - * @param[in,out] lp log probability + * @tparam Ret The type to return. + * @tparam Jacobian Whether to increment the log of the absolute Jacobian + * determinant of the transform. + * @tparam Sizes A parameter pack of integral types. + * @tparam LP Type of log probability. + * @param lp The reference to the variable holding the log + * @param vecsize The size of the return vector. + * @param sizes Pack of integrals to use to construct the return's type. + * probability to increment. * @return Next Cholesky factor. * @throw std::domain_error if the matrix is not a valid * Cholesky factor. */ template * = nullptr> - auto read_cholesky_factor_cov(LP& lp, const size_t vecsize, - const Sizes&... sizes) { - using ret_value_t = value_type_t; + auto read_cholesky_factor_cov(LP& lp, const size_t vecsize, Sizes... sizes) { std::decay_t ret; + ret.reserve(vecsize); for (size_t i = 0; i < vecsize; ++i) { ret.emplace_back( - this->read_cholesky_factor_cov(lp, sizes...)); + this->read_cholesky_factor_cov, Jacobian>( + lp, sizes...)); } return ret; } @@ -1155,10 +1760,11 @@ class deserializer { */ template * = nullptr> auto read_cholesky_factor_corr(size_t K) { - using stan::math::check_cholesky_factor_corr; auto ret = read(K, K); - check_cholesky_factor_corr("deserializer", - "Cholesky Factor Corr Matrix", ret); + using stan::math::check_cholesky_factor_corr; + using stan::math::value_of; + check_cholesky_factor_corr("deserializer", "Cholesky Factor Corr Matrix", + value_of(ret)); return ret; } @@ -1167,7 +1773,11 @@ class deserializer { * the specified dimensionality, reading it directly without * transforms. * - * @param K Rows and columns of Cholesky factor + * @tparam Ret The type to return. + * @tparam Sizes A parameter pack of integral types. + * @param vecsize The size of the return vector. + * @param sizes Pack of integrals to use to construct the return's type. + * probability to increment. * @return Next Cholesky factor for a correlation matrix. * @throw std::domain_error if the matrix is not a valid * Cholesky factor for a correlation matrix. @@ -1175,10 +1785,10 @@ class deserializer { template * = nullptr> auto read_cholesky_factor_corr(size_t vecsize, Sizes... sizes) { - using ret_value_t = value_type_t; std::decay_t ret; for (size_t i = 0; i < vecsize; ++i) { - ret.emplace_back(this->read_cholesky_factor_corr(sizes...)); + ret.emplace_back( + this->read_cholesky_factor_corr>(sizes...)); } return ret; } @@ -1190,8 +1800,12 @@ class deserializer { * probability reference with the log Jacobian adjustment for * the transform. * - * @param K Rows and columns of Cholesky factor + * @tparam Ret The type to return. + * @tparam Jacobian Whether to increment the log of the absolute Jacobian + * determinant of the transform. + * @tparam LP Type of log probability. * @param lp Log probability reference to increment. + * @param K Rows and columns of Cholesky factor * @return Next Cholesky factor for a correlation matrix. * @throw std::domain_error if the matrix is not a valid * Cholesky factor for a correlation matrix. @@ -1201,11 +1815,13 @@ class deserializer { auto read_cholesky_factor_corr(LP& lp, size_t K) { using stan::math::cholesky_corr_constrain; if (Jacobian) { - return cholesky_corr_constrain(this->read((K * (K - 1)) / 2), K, - lp); + return cholesky_corr_constrain( + this->read>((K * (K - 1)) / 2), + K, lp); } else { - return cholesky_corr_constrain(this->read((K * (K - 1)) / 2), - K); + return cholesky_corr_constrain( + this->read>((K * (K - 1)) / 2), + K); } } @@ -1216,21 +1832,28 @@ class deserializer { * probability reference with the log Jacobian adjustment for * the transform. * - * @param K Rows and columns of Cholesky factor - * @param lp Log probability reference to increment. + * @tparam Ret The type to return. + * @tparam Jacobian Whether to increment the log of the absolute Jacobian + * determinant of the transform. + * @tparam LP Type of log probability. + * @tparam Sizes A parameter pack of integral types. + * @param lp The reference to the variable holding the log + * @param vecsize The size of the return vector. + * @param sizes Pack of integrals to use to construct the return's type. + * probability to increment. * @return Next Cholesky factor for a correlation matrix. * @throw std::domain_error if the matrix is not a valid * Cholesky factor for a correlation matrix. */ template * = nullptr> - auto read_cholesky_factor_corr(LP& lp, const size_t vecsize, - const Sizes&... sizes) { - using ret_value_t = value_type_t; + auto read_cholesky_factor_corr(LP& lp, const size_t vecsize, Sizes... sizes) { std::decay_t ret; + ret.reserve(vecsize); for (size_t i = 0; i < vecsize; ++i) { ret.emplace_back( - this->read_cholesky_factor_corr(lp, sizes...)); + this->read_cholesky_factor_corr, Jacobian>( + lp, sizes...)); } return ret; } @@ -1241,6 +1864,7 @@ class deserializer { * *

See stan::math::check_cov_matrix(Matrix). * + * @tparam Ret The type to return. * @param k Dimensionality of covariance matrix. * @return Next covariance matrix of the specified dimensionality. * @throw std::runtime_error if the matrix is not a valid @@ -1248,9 +1872,11 @@ class deserializer { */ template * = nullptr> auto read_cov_matrix(size_t k) { - using stan::math::check_cov_matrix; auto ret = read(k, k); - check_cov_matrix("stan::io::cov_matrix", "Constrained matrix", ret); + using stan::math::check_cov_matrix; + using stan::math::value_of; + check_cov_matrix("stan::io::cov_matrix", "Constrained matrix", + value_of(ret)); return ret; } @@ -1260,7 +1886,11 @@ class deserializer { * *

See stan::math::check_cov_matrix(Matrix). * - * @param k Dimensionality of covariance matrix. + * @tparam Ret The type to return. + * @tparam Sizes A parameter pack of integral types. + * @param vecsize The size of the return vector. + * @param sizes Pack of integrals to use to construct the return's type. + * probability to increment. * @return Next covariance matrix of the specified dimensionality. * @throw std::runtime_error if the matrix is not a valid * covariance matrix @@ -1268,10 +1898,10 @@ class deserializer { template * = nullptr> auto read_cov_matrix(size_t vecsize, Sizes... sizes) { - using ret_value_t = value_type_t; std::decay_t ret; + ret.reserve(vecsize); for (size_t i = 0; i < vecsize; ++i) { - ret.emplace_back(this->read_cholesky_factor_corr(sizes...)); + ret.emplace_back(this->read_cov_matrix>(sizes...)); } return ret; } @@ -1283,8 +1913,12 @@ class deserializer { * *

See stan::math::cov_matrix_constrain(Matrix,T&). * + * @tparam Ret The type to return. + * @tparam Jacobian Whether to increment the log of the absolute Jacobian + * determinant of the transform. + * @tparam LP Type of log probability. + * @param lp The reference to the variable holding the log * @param k Dimensionality of the (square) covariance matrix. - * @param lp Log probability reference to increment. * @return The next covariance matrix of the specified dimensionality. */ template read(k + (k * (k - 1)) / 2), - k, lp); + return cov_matrix_constrain( + this->read>(k + + (k * (k - 1)) / 2), + k, lp); } else { - return cov_matrix_constrain(this->read(k + (k * (k - 1)) / 2), - k); + return cov_matrix_constrain( + this->read>(k + + (k * (k - 1)) / 2), + k); } } @@ -1307,18 +1945,25 @@ class deserializer { * *

See stan::math::cov_matrix_constrain(Matrix,T&). * - * @param k Dimensionality of the (square) covariance matrix. - * @param lp Log probability reference to increment. + * @tparam Ret The type to return. + * @tparam Jacobian Whether to increment the log of the absolute Jacobian + * determinant of the transform. + * @tparam LP Type of log probability. + * @tparam Sizes A parameter pack of integral types. + * @param lp The reference to the variable holding the log + * @param vecsize The size of the return vector. + * @param sizes Pack of integrals to use to construct the return's type. + * probability to increment. * @return The next covariance matrix of the specified dimensionality. */ template * = nullptr> - auto read_cov_matrix(LP& lp, const size_t vecsize, const Sizes&... sizes) { - using ret_value_t = value_type_t; + auto read_cov_matrix(LP& lp, const size_t vecsize, Sizes... sizes) { std::decay_t ret; + ret.reserve(vecsize); for (size_t i = 0; i < vecsize; ++i) { ret.emplace_back( - this->read_cov_matrix(lp, sizes...)); + this->read_cov_matrix, Jacobian>(lp, sizes...)); } return ret; } diff --git a/src/test/unit/io/deserializer_stdvector_test.cpp b/src/test/unit/io/deserializer_stdvector_test.cpp new file mode 100644 index 00000000000..784c9320f1b --- /dev/null +++ b/src/test/unit/io/deserializer_stdvector_test.cpp @@ -0,0 +1,1506 @@ +#include +#include + + +TEST(deserializer_rowvector, read) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100U; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (size_t i = 0; i < 7U; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + Eigen::Matrix y = deserializer.read(4); + EXPECT_EQ(4, y.cols()); + EXPECT_EQ(1, y.rows()); + EXPECT_EQ(4, y.size()); + EXPECT_FLOAT_EQ(7.0, y[0]); + EXPECT_FLOAT_EQ(8.0, y[1]); + EXPECT_FLOAT_EQ(9.0, y[2]); + EXPECT_FLOAT_EQ(10.0, y[3]); + + double z = deserializer.read(); + EXPECT_FLOAT_EQ(11.0, z); +} + +TEST(deserializer_stdvec, std_vector_vector) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100U; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + auto y = deserializer.read>(5, 4); + EXPECT_EQ(5, y.size()); + int sentinal = 0; + for (int i = 0; i < y.size(); ++i) { + EXPECT_EQ(4, y[i].rows()); + EXPECT_EQ(1, y[i].cols()); + for (int j = 0; j < 4; ++j) { + EXPECT_FLOAT_EQ(sentinal, y[i].coeff(j)); + sentinal++; + } + } +} + +TEST(deserializer_stdvec, std_vector_std_vector_matrix) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 120U; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + auto y = deserializer.read>>(5, 4, 3, 2); + EXPECT_EQ(5, y.size()); + int sentinal = 0; + for (int i = 0; i < y.size(); ++i) { + EXPECT_EQ(4, y[i].size()); + for (int j = 0; j < 4; ++j) { + EXPECT_EQ(3, y[i][j].rows()); + EXPECT_EQ(2, y[i][j].cols()); + for (int k = 0; k < 6; ++k) { + EXPECT_FLOAT_EQ(sentinal, y[i][j].coeff(k)); + sentinal++; + } + } + } +} + +// scalar bounds +TEST(deserializer_stdvec_scalar, read) { + std::vector theta_i; + std::vector theta; + theta.push_back(1.0); + theta.push_back(2.0); + stan::io::deserializer deserializer(theta, theta_i); + auto x = deserializer.read>(2); + EXPECT_FLOAT_EQ(1.0, x[0]); + EXPECT_FLOAT_EQ(2.0, x[1]); + EXPECT_EQ(0U, deserializer.available()); +} + +TEST(deserializer_stdvec_scalar, read_lb) { + std::vector theta_i; + std::vector theta; + theta.push_back(-1.0); + theta.push_back(2.0); + stan::io::deserializer deserializer(theta, theta_i); + auto x = deserializer.read_lb>(std::vector{-2.0, 1.0}, 2); + EXPECT_FLOAT_EQ(-1.0, x[0]); + EXPECT_FLOAT_EQ(2.0, x[1]); + EXPECT_EQ(0U, deserializer.available()); +} +TEST(deserializer_stdvec_scalar, read_lb_exception) { + std::vector theta_i; + std::vector theta; + theta.push_back(-1.0); + theta.push_back(2.0); + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_NO_THROW(deserializer.read_lb>(-1.0, 2)); + EXPECT_THROW(deserializer.read_lb>(3.0, 2), std::runtime_error); +} +TEST(deserializer_stdvec_scalar, read_lb_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0.0; + auto ret = deserializer.read_lb, false>(std::vector{1.0, 5, -2, 15}, lp, 4); + EXPECT_FLOAT_EQ(1.0 + exp(-2.0), ret[0]); + EXPECT_FLOAT_EQ(5.0 + exp(3.0), ret[1]); + EXPECT_FLOAT_EQ(-2.0 + exp(-1.0), ret[2]); + EXPECT_FLOAT_EQ(15.0 + exp(0.0), ret[3]); +} +TEST(deserializer_stdvec_scalar, read_lb_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = -1.5; + auto ret = deserializer.read_lb, true>(std::vector{1.0, 5.0, -2.0, 15.0}, lp, 4); + EXPECT_FLOAT_EQ(1.0 + exp(-2.0), ret[0]); + EXPECT_FLOAT_EQ(5.0 + exp(3.0), ret[1]); + EXPECT_FLOAT_EQ(-2.0 + exp(-1.0), ret[2]); + EXPECT_FLOAT_EQ(15.0 + exp(0.0), ret[3]); + EXPECT_FLOAT_EQ(-1.5 - 2.0 + 3.0 - 1.0, lp); +} + +// ub + +TEST(deserializer_stdvec_scalar, read_ub) { + std::vector theta_i; + std::vector theta; + theta.push_back(-1.0); + theta.push_back(3.0); + stan::io::deserializer deserializer(theta, theta_i); + auto x = deserializer.read_ub>(3.0, 2); + EXPECT_FLOAT_EQ(-1.0, x[0]); + EXPECT_FLOAT_EQ(3.0, x[1]); + EXPECT_EQ(0U, deserializer.available()); +} +TEST(deserializer_stdvec_scalar, read_ub_exception) { + std::vector theta_i; + std::vector theta; + theta.push_back(-1.0); + theta.push_back(2.0); + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_NO_THROW(deserializer.read_ub>(3.0, 2)); + EXPECT_THROW(deserializer.read_ub>(1.0, 2), std::runtime_error); +} +TEST(deserializer_stdvec_scalar, read_ub_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0; + auto ret = deserializer.read_ub, false>(std::vector{1.0, 5.0, -2, 15}, lp, 4); + EXPECT_FLOAT_EQ(1.0 - exp(-2.0), ret[0]); + EXPECT_FLOAT_EQ(5.0 - exp(3.0), ret[1]); + EXPECT_FLOAT_EQ(-2.0 - exp(-1.0), ret[2]); + EXPECT_FLOAT_EQ(15.0 - exp(0.0), ret[3]); +} +TEST(deserializer_stdvec_scalar, read_ub_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = -12.9; + auto ret = deserializer.read_ub, false>(std::vector{1.0, 5.0, -2, 15}, lp, 4); + EXPECT_FLOAT_EQ(1.0 - exp(-2.0), ret[0]); + EXPECT_FLOAT_EQ(5.0 - exp(3.0), ret[1]); + EXPECT_FLOAT_EQ(-2.0 - exp(-1.0), ret[2]); + EXPECT_FLOAT_EQ(15.0 - exp(0.0), ret[3]); + EXPECT_FLOAT_EQ(-12.9 - 2.0 + 3.0 - 1.0, lp); +} + +// lub + + +TEST(deserializer_stdvec_scalar, read_lub) { + std::vector theta_i; + std::vector theta; + theta.push_back(-1.0); + theta.push_back(2.0); + stan::io::deserializer deserializer(theta, theta_i); + auto x = deserializer.read_lub>(-3.0, 3.0, 2); + EXPECT_FLOAT_EQ(-1.0, x[0]); + EXPECT_FLOAT_EQ(2.0, x[1]); + + EXPECT_EQ(0U, deserializer.available()); +} +TEST(deserializer_stdvec_scalar, read_lub_exception) { + std::vector theta_i; + std::vector theta; + theta.push_back(-1.0); + theta.push_back(2.0); + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_NO_THROW(deserializer.read_lub>(-2.0, 2.0, 2)); + EXPECT_THROW(deserializer.read_lub>(-1.0, 1.0, 2), std::runtime_error); +} +const double inv_logit_m2 = 0.1192029; // stan::math::inv_logit(-2.0) +const double inv_logit_m1 = 0.2689414; // stan::math::inv_logit(-1.0) +const double inv_logit_0 = 0.5; // stan::math::inv_logit(0) +const double inv_logit_3 = 0.9525741; // stan::math::inv_logit(3.0) + +TEST(deserializer_stdvec_scalar, read_lub_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0; + std::vector lb{0.0, 3.0, -3.0, -15.0}; + std::vector ub{1.0, 5.0, 2.0, 15.0}; + auto ret = deserializer.read_lub, false>(lb, ub, lp, 4); + EXPECT_FLOAT_EQ(inv_logit_m2, ret[0]); + EXPECT_FLOAT_EQ(3.0 + 2.0 * inv_logit_3, ret[1]); + EXPECT_FLOAT_EQ(-3.0 + 5.0 * inv_logit_m1, ret[2]); + EXPECT_FLOAT_EQ(-15.0 + 30.0 * inv_logit_0, ret[3]); +} +TEST(deserializer_stdvec_scalar, read_lub_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = -7.2; + std::vector lb{0.0, 3.0, -3.0, -15.0}; + std::vector ub{1.0, 5.0, 2.0, 15.0}; + auto ret = deserializer.read_lub, true>(lb, ub, lp, 4); + EXPECT_FLOAT_EQ(0.0 + 1.0 * inv_logit_m2, ret[0]); + EXPECT_FLOAT_EQ(3.0 + 2.0 * inv_logit_3, ret[1]); + EXPECT_FLOAT_EQ(-3.0 + 5.0 * inv_logit_m1, ret[2]); + EXPECT_FLOAT_EQ(-15.0 + 30.0 * inv_logit_0, ret[3]); + double expected_lp = -7.2 + + log((1.0 - 0.0) * inv_logit_m2 * (1 - inv_logit_m2)) + + log((5.0 - 3.0) * inv_logit_3 * (1 - inv_logit_3)) + + log((2.0 - -3.0) * inv_logit_m1 * (1 - inv_logit_m1)) + + log((15.0 - -15.0) * inv_logit_0 * (1 - inv_logit_0)); + EXPECT_FLOAT_EQ(expected_lp, lp); +} + +// offset multiplier + +TEST(deserializer_stdvec_scalar, read_offset_multiplier) { + std::vector theta_i; + std::vector theta; + theta.push_back(-1.0); + theta.push_back(2.0); + stan::io::deserializer deserializer(theta, theta_i); + auto x = deserializer.read_offset_multiplier>(-3.0, 3.0, 2); + EXPECT_FLOAT_EQ(-1.0, x[0]); + EXPECT_FLOAT_EQ(2.0, x[1]); + + EXPECT_EQ(0U, deserializer.available()); +} +TEST(deserializer_stdvec_scalar, offset_multiplier_exception) { + std::vector theta_i; + std::vector theta; + theta.push_back(-1.0); + theta.push_back(2.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0; + EXPECT_NO_THROW(deserializer.read_offset_multiplier>(-2.0, -2.0, 2)); + EXPECT_THROW((deserializer.read_offset_multiplier, false>(-2.0, -2.0, lp, 2)), + std::runtime_error); +} + +TEST(deserializer_stdvec_scalar, offset_multiplier_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0; + std::vector offset{0, 3, -3, -15}; + std::vector mult{1.0, 5.0, 2.0, 15}; + auto ret = deserializer.read_offset_multiplier, false>(offset, mult, lp, 4); + EXPECT_FLOAT_EQ(-2.0, ret[0]); + EXPECT_FLOAT_EQ(3.0 + 5.0 * 3.0, ret[1]); + EXPECT_FLOAT_EQ(-3.0 + 2.0 * -1.0, ret[2]); + EXPECT_FLOAT_EQ(-15.0, ret[3]); +} +TEST(deserializer_stdvec_scalar, offset_multiplier_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = -7.2; + std::vector offset{0, 3, -3, -15}; + std::vector mult{1.0, 5.0, 2.0, 15}; + auto ret = deserializer.read_offset_multiplier, true>(offset, mult, lp, 4); + EXPECT_FLOAT_EQ(-2.0, ret[0]); + EXPECT_FLOAT_EQ(3.0 + 5.0 * 3.0, ret[1]); + EXPECT_FLOAT_EQ(-3.0 + 2.0 * -1.0, ret[2]); + EXPECT_FLOAT_EQ(-15.0, ret[3]); + double expected_lp = -7.2 + log(1.0) + log(5.0) + log(2.0) + log(15.0); + EXPECT_FLOAT_EQ(expected_lp, lp); +} + +// prob + +TEST(deserializer_stdvec_scalar, prob) { + std::vector theta_i; + std::vector theta; + theta.push_back(0.9); + theta.push_back(0.1); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + auto p1 = deserializer.read_prob>(3); + EXPECT_FLOAT_EQ(0.9, p1[0]); + EXPECT_FLOAT_EQ(0.1, p1[1]); + EXPECT_FLOAT_EQ(0.0, p1[2]); + EXPECT_EQ(0U, deserializer.available()); +} + +TEST(deserializer_stdvec_scalar, prob_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0; + auto ret = deserializer.read_prob, false>(lp, 4); + EXPECT_FLOAT_EQ(inv_logit_m2, ret[0]); + EXPECT_FLOAT_EQ(inv_logit_3, ret[1]); + EXPECT_FLOAT_EQ(inv_logit_m1, ret[2]); + EXPECT_FLOAT_EQ(inv_logit_0, ret[3]); +} + +TEST(deserializer_stdvec_scalar, prob_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = -0.88; + auto ret = deserializer.read_prob, true>(lp, 4); + EXPECT_FLOAT_EQ(inv_logit_m2, ret[0]); + EXPECT_FLOAT_EQ(inv_logit_3, ret[1]); + EXPECT_FLOAT_EQ(inv_logit_m1, ret[2]); + EXPECT_FLOAT_EQ(inv_logit_0, ret[3]); + double expected_lp = -0.88 + log(inv_logit_m2 * (1.0 - inv_logit_m2)) + + log(inv_logit_3 * (1.0 - inv_logit_3)) + + log(inv_logit_m1 * (1.0 - inv_logit_m1)) + + log(inv_logit_0 * (1.0 - inv_logit_0)); + EXPECT_FLOAT_EQ(expected_lp, lp); +} + +// corr + +TEST(deserializer_stdvec_scalar, corr) { + std::vector theta_i; + std::vector theta; + theta.push_back(-0.9); + theta.push_back(0.1); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + auto rho1 = deserializer.read_corr>(3); + EXPECT_FLOAT_EQ(-0.9, rho1[0]); + EXPECT_FLOAT_EQ(0.1, rho1[1]); + EXPECT_FLOAT_EQ(0.0, rho1[2]); + EXPECT_EQ(0U, deserializer.available()); +} +TEST(deserializer_stdvec_scalar, corr_exception) { + std::vector theta_i; + std::vector theta; + theta.push_back(-0.9); + theta.push_back(-1.1); + theta.push_back(1.1); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0; + EXPECT_NO_THROW((deserializer.read_corr, false>(lp, 3))); + EXPECT_THROW(deserializer.read_corr>(3), std::runtime_error); +} +TEST(deserializer_stdvec_scalar, corr_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0; + auto ret = deserializer.read_corr, false>(lp, 4); + EXPECT_FLOAT_EQ(tanh(-2.0), ret[0]); + EXPECT_FLOAT_EQ(tanh(3.0), ret[1]); + EXPECT_FLOAT_EQ(tanh(-1.0), ret[2]); + EXPECT_FLOAT_EQ(tanh(0.0), ret[3]); +} +TEST(deserializer_stdvec_scalar, corr_constrain_jacobian) { + using std::tanh; + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = -10.0; + auto ret = deserializer.read_corr, true>(lp, 4); + EXPECT_FLOAT_EQ(tanh(-2.0), ret[0]); + EXPECT_FLOAT_EQ(tanh(3.0), ret[1]); + EXPECT_FLOAT_EQ(tanh(-1.0), ret[2]); + EXPECT_FLOAT_EQ(tanh(0.0), ret[3]); + double expected_lp = -10.0 + log(1.0 - tanh(-2.0) * tanh(-2.0)) + + log(1.0 - tanh(3.0) * tanh(3.0)) + + log(1.0 - tanh(-1.0) * tanh(-1.0)) + + log(1.0 - tanh(0.0) * tanh(0.0)); + EXPECT_FLOAT_EQ(expected_lp, lp); +} + +// vectors + +TEST(deserializer_stdvec_vector, read) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100U; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (size_t i = 0; i < 7U; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + auto y = deserializer.read>(4, 4); + EXPECT_EQ(4, y.size()); + double sentinal = 7; + for (int i = 0; i < 4; ++i) { + EXPECT_EQ(4, y[i].rows()); + EXPECT_EQ(1, y[i].cols()); + for (int j = 0; j < 4; ++j) { + EXPECT_FLOAT_EQ(sentinal, y[i][j]); + ++sentinal; + } + } +} + +TEST(deserializer_stdvec_vector, unit_vector) { + std::vector theta_i(0); + std::vector theta(16, sqrt(0.25)); + stan::io::deserializer deserializer(theta, theta_i); + auto y = deserializer.read_unit_vector>(4, 4); + EXPECT_EQ(4, y.size()); + const double sqrt_qtr = sqrt(0.25); + for (int i = 0; i < 4; ++i) { + EXPECT_EQ(4, y[i].rows()); + EXPECT_EQ(1, y[i].cols()); + for (int j = 0; j < 4; ++j) { + EXPECT_FLOAT_EQ(sqrt_qtr, y[i][j]); + } + } +} + +TEST(deserializer_stdvec_vector, unit_vector_exception) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + theta[0] = 0.00; + theta[1] = -sqrt(0.29); + theta[2] = sqrt(0.70); + theta[3] = -sqrt(0.01); + theta[4] = sqrt(1.0); + theta[5] = sqrt(1.0); + EXPECT_NO_THROW(deserializer.read_unit_vector>(1, 4)); + EXPECT_THROW(deserializer.read_unit_vector>(1, 2), std::domain_error); + EXPECT_THROW(deserializer.read_unit_vector>(1, 0), std::invalid_argument); +} + +TEST(deserializer_stdvec_vector, simplex) { + std::vector theta_i(0); + std::vector theta(8, 0.25); + stan::io::deserializer deserializer(theta, theta_i); + auto y = deserializer.read_simplex>(2, 4); + EXPECT_EQ(2, y.size()); + for (int i = 0; i < 2; ++i) { + EXPECT_EQ(4, y[i].rows()); + EXPECT_EQ(1, y[i].cols()); + for (int j = 0; j < 4; ++j) { + EXPECT_FLOAT_EQ(0.25, y[i][j]); + } + } +} +TEST(deserializer_stdvec_vector, simplex_exception) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + theta[0] = 0.00; + theta[1] = 0.29; + theta[2] = 0.70; + theta[3] = 0.01; + theta[4] = 0.00; + theta[5] = 0.29; + theta[6] = 0.70; + theta[7] = 0.01; + theta[8] = 1.0; + theta[9] = 1.0; + EXPECT_NO_THROW(deserializer.read_simplex>(2, 4)); + EXPECT_THROW(deserializer.read_simplex>(2, 2), std::domain_error); + EXPECT_THROW(deserializer.read_simplex>(2, 0), std::invalid_argument); +} + +TEST(deserializer_stdvec_vector, ordered) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_FLOAT_EQ(0.0, deserializer.read()); // throw away theta[0] + auto y = deserializer.read_ordered>(5, 2); + EXPECT_EQ(5, y.size()); + double k = 1; + for (int i = 0; i < 5; ++i) { + EXPECT_EQ(2, y[i].rows()); + EXPECT_EQ(1, y[i].cols()); + for (int j = 0; j < 2; ++j) { + EXPECT_FLOAT_EQ(k, y[i][j]); + ++k; + } + } +} + +TEST(deserializer_stdvec_vector, ordered_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + double v0 = 3.0; + double v1 = v0 + exp(-1.0); + double v2 = v1 + exp(-2.0); + double v3 = v2 + exp(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0; + auto phi(deserializer.read_ordered, false>(lp, 2, 4)); + EXPECT_EQ(2, phi.size()); + for (int i = 0; i < 2; ++i) { + EXPECT_EQ(4, phi[i].rows()); + EXPECT_EQ(1, phi[i].cols()); + EXPECT_FLOAT_EQ(v0, phi[i][0]); + EXPECT_FLOAT_EQ(v1, phi[i][1]); + EXPECT_FLOAT_EQ(v2, phi[i][2]); + EXPECT_FLOAT_EQ(v3, phi[i][3]); + } +} +TEST(deserializer_stdvec_vector, ordered_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + double v0 = 3.0; + double v1 = v0 + exp(-1.0); + double v2 = v1 + exp(-2.0); + double v3 = v2 + exp(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = -101.1; + double expected_lp = lp - 1.0 - 2.0 + 0.0 - 1.0 - 2.0 + 0.0; + auto phi(deserializer.read_ordered, true>(lp, 2, 4)); + EXPECT_FLOAT_EQ(v0, phi[0][0]); + EXPECT_FLOAT_EQ(v1, phi[0][1]); + EXPECT_FLOAT_EQ(v2, phi[0][2]); + EXPECT_FLOAT_EQ(v3, phi[0][3]); + EXPECT_FLOAT_EQ(v0, phi[1][0]); + EXPECT_FLOAT_EQ(v1, phi[1][1]); + EXPECT_FLOAT_EQ(v2, phi[1][2]); + EXPECT_FLOAT_EQ(v3, phi[1][3]); + EXPECT_FLOAT_EQ(expected_lp, lp); +} + +TEST(deserializer_stdvec_vector, positive_ordered) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_FLOAT_EQ(0.0, deserializer.read()); // throw away theta[0] + auto y = deserializer.read_positive_ordered>(5, 2); + EXPECT_EQ(5, y.size()); + double sentinal = 1; + for (int i = 0; i < 5; ++i) { + EXPECT_EQ(y[i].rows(), 2); + EXPECT_EQ(y[i].cols(), 1); + for (int j = 0; j < 2; ++j) { + EXPECT_FLOAT_EQ(sentinal, y[i][j]); + ++sentinal; + } + } +} + +TEST(deserializer_stdvec_vector, positive_ordered_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + double v0 = exp(3.0); + double v1 = v0 + exp(-1.0); + double v2 = v1 + exp(-2.0); + double v3 = v2 + exp(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0; + auto phi(deserializer.read_positive_ordered, false>(lp, 2, 4)); + EXPECT_FLOAT_EQ(v0, phi[0][0]); + EXPECT_FLOAT_EQ(v1, phi[0][1]); + EXPECT_FLOAT_EQ(v2, phi[0][2]); + EXPECT_FLOAT_EQ(v3, phi[0][3]); + EXPECT_FLOAT_EQ(v0, phi[1][0]); + EXPECT_FLOAT_EQ(v1, phi[1][1]); + EXPECT_FLOAT_EQ(v2, phi[1][2]); + EXPECT_FLOAT_EQ(v3, phi[1][3]); +} + +TEST(deserializer_stdvec_vector, positive_ordered_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + double v0 = exp(3.0); + double v1 = v0 + exp(-1.0); + double v2 = v1 + exp(-2.0); + double v3 = v2 + exp(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = -101.1; + double expected_lp = lp + 3.0 - 1.0 - 2.0 + 0.0 + 3.0 - 1.0 - 2.0 + 0.0; + auto phi(deserializer.read_positive_ordered, true>(lp, 2, 4)); + EXPECT_FLOAT_EQ(v0, phi[0][0]); + EXPECT_FLOAT_EQ(v1, phi[0][1]); + EXPECT_FLOAT_EQ(v2, phi[0][2]); + EXPECT_FLOAT_EQ(v3, phi[0][3]); + EXPECT_FLOAT_EQ(v0, phi[1][0]); + EXPECT_FLOAT_EQ(v1, phi[1][1]); + EXPECT_FLOAT_EQ(v2, phi[1][2]); + EXPECT_FLOAT_EQ(v3, phi[1][3]); + EXPECT_FLOAT_EQ(expected_lp, lp); +} + +// matrix + +TEST(deserializer_stdvec_matrix, read) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (int i = 0; i < 7; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + using eig_mat = Eigen::Matrix; + auto y = deserializer.read>(2, 3, 2); + EXPECT_EQ(2, y.size()); + double sentinal = 7; + for (int i = 0; i < 2; ++i) { + EXPECT_EQ(3, y[i].rows()); + EXPECT_EQ(2, y[i].cols()); + for (int j = 0; j < y[i].size(); ++j) { + EXPECT_FLOAT_EQ(sentinal, y[i](j)); + ++sentinal; + } + } +} + + +TEST(deserializer_stdvec_matrix, matrix_lb) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (int i = 0; i < 7; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + double lb = -1.5; + auto y = deserializer.read_lb>(lb, 2, 3, 2); + EXPECT_EQ(2, y.size()); + double sentinal = 7; + for (int i = 0; i < 2; ++i) { + EXPECT_EQ(3, y[i].rows()); + EXPECT_EQ(2, y[i].cols()); + for (int j = 0; j < y[i].size(); ++j) { + EXPECT_FLOAT_EQ(sentinal, y[i](j)); + ++sentinal; + } + } +} + +TEST(deserializer_stdvec_matrix, matrix_lb_constrain) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (int i = 0; i < 7; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + double lb = -1.5; + double lp = 0; + auto y = deserializer.read_lb, false>(lb, lp, 2, 3, 2); + EXPECT_EQ(2, y.size()); + double sentinal = 7; + for (int i = 0; i < 2; ++i) { + EXPECT_EQ(3, y[i].rows()); + EXPECT_EQ(2, y[i].cols()); + for (int j = 0; j < y[i].size(); ++j) { + EXPECT_FLOAT_EQ(stan::math::lb_constrain(sentinal, lb), y[i](j)); + ++sentinal; + } + } +} + +TEST(deserializer_stdvec_matrix, matrix_lb_constrain_lp) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (int i = 0; i < 7; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + double lb = -1.5; + double lp = -5.0; + auto y + = deserializer.read_lb, true>(lb, lp, 2, 3, 2); + EXPECT_EQ(2, y.size()); + double sentinal = 7; + for (int i = 0; i < 2; ++i) { + EXPECT_EQ(3, y[i].rows()); + EXPECT_EQ(2, y[i].cols()); + for (int j = 0; j < y[i].size(); ++j) { + EXPECT_FLOAT_EQ(stan::math::lb_constrain(sentinal, lb, lp), y[i](j)); + ++sentinal; + } + } +} + +TEST(deserializer_stdvec_matrix, matrix_ub) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (int i = 0; i < 7; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + double ub = 26.5; + auto y = deserializer.read_ub>(ub, 2, 3, 2); + EXPECT_EQ(2, y.size()); + double sentinal = 7; + for (int i = 0; i < 2; ++i) { + EXPECT_EQ(3, y[i].rows()); + EXPECT_EQ(2, y[i].cols()); + for (int j = 0; j < y[i].size(); ++j) { + EXPECT_FLOAT_EQ(sentinal, y[i](j)); + ++sentinal; + } + } +} + +TEST(deserializer_stdvec_matrix, matrix_ub_constrain) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (int i = 0; i < 7; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + double ub = 14.1; + double lp = 0; + auto y = deserializer.read_ub, false>(ub, lp, 2, 3, 2); + EXPECT_EQ(2, y.size()); + double sentinal = 7; + for (int i = 0; i < 2; ++i) { + EXPECT_EQ(3, y[i].rows()); + EXPECT_EQ(2, y[i].cols()); + for (int j = 0; j < y[i].size(); ++j) { + EXPECT_FLOAT_EQ(stan::math::ub_constrain(sentinal, ub), y[i](j)); + ++sentinal; + } + } +} + +TEST(deserializer_stdvec_matrix, matrix_ub_constrain_lp) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (int i = 0; i < 7; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + double ub = 12.1; + double lp = -5.0; + auto y = deserializer.read_ub, true>(ub, lp, 2, 3, 2); + EXPECT_EQ(2, y.size()); + double sentinal = 7; + for (int i = 0; i < 2; ++i) { + EXPECT_EQ(3, y[i].rows()); + EXPECT_EQ(2, y[i].cols()); + for (int j = 0; j < y[i].size(); ++j) { + EXPECT_FLOAT_EQ(stan::math::ub_constrain(sentinal, ub, lp), y[i](j)); + ++sentinal; + } + } +} + +TEST(deserializer_stdvec_matrix, matrix_lub) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (int i = 0; i < 7; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + double lb = 6.9; + double ub = 32.5; + auto y = deserializer.read_lub>(lb, ub, 2, 3, 2); + EXPECT_EQ(2, y.size()); + double sentinal = 7; + for (int i = 0; i < 2; ++i) { + EXPECT_EQ(3, y[i].rows()); + EXPECT_EQ(2, y[i].cols()); + for (int j = 0; j < y[i].size(); ++j) { + EXPECT_FLOAT_EQ(sentinal, y[i](j)); + ++sentinal; + } + } +} + +TEST(deserializer_stdvec_matrix, matrix_lub_constrain) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (int i = 0; i < 7; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + double lb = 3.5; + double ub = 14.1; + double lp = 0; + auto y = deserializer.read_lub, false>(lb, ub, lp, 2, 3, 2); + EXPECT_EQ(2, y.size()); + double sentinal = 7; + for (int i = 0; i < 2; ++i) { + EXPECT_EQ(3, y[i].rows()); + EXPECT_EQ(2, y[i].cols()); + for (int j = 0; j < y[i].size(); ++j) { + EXPECT_FLOAT_EQ(stan::math::lub_constrain(sentinal, lb, ub), y[i](j)); + ++sentinal; + } + } +} + +TEST(deserializer_stdvec_matrix, matrix_lub_constrain_lp) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (int i = 0; i < 7; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + double lb = 4.1; + double ub = 12.1; + double lp = -5.0; + auto y = deserializer.read_lub, true>(lb, ub, lp, 2,3, 2); + EXPECT_EQ(2, y.size()); + double sentinal = 7; + for (int i = 0; i < 2; ++i) { + EXPECT_EQ(3, y[i].rows()); + EXPECT_EQ(2, y[i].cols()); + for (int j = 0; j < y[i].size(); ++j) { + EXPECT_FLOAT_EQ(stan::math::lub_constrain(sentinal, lb, ub, lp), y[i](j)); + ++sentinal; + } + } +} + +TEST(deserializer_stdvec_matrix, corr_matrix) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + theta[0] = 1.0000000000000000; + theta[1] = 0.1817621852191252; + theta[2] = 0.8620926037637362; + theta[3] = 0.1817621852191252; + theta[4] = 1.0000000000000000; + theta[5] = 0.2248293054822660; + theta[6] = 0.8620926037637362; + theta[7] = 0.2248293054822660; + theta[8] = 1.0000000000000001; // allow some tolerance + theta[9] = 1.0000000000000000; + theta[10] = 0.1817621852191252; + theta[11] = 0.8620926037637362; + theta[12] = 0.1817621852191252; + theta[13] = 1.0000000000000000; + theta[14] = 0.2248293054822660; + theta[15] = 0.8620926037637362; + theta[16] = 0.2248293054822660; + theta[17] = 1.0000000000000001; // allow some tolerance + stan::io::deserializer deserializer(theta, theta_i); + auto S = deserializer.read_corr>(2, 3); + EXPECT_FLOAT_EQ(theta[0], S[0](0, 0)); +} + +TEST(deserializer_stdvec_matrix, corr_matrix_exception) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + theta[0] = 1.5; + theta[1] = 1.0; + theta[2] = 2.0; + theta[3] = 0.0; + theta[4] = 1.0; + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_THROW(deserializer.read_corr>(1, 1), std::domain_error); + EXPECT_THROW(deserializer.read_corr>(2, 3), std::domain_error); +} +TEST(deserializer_stdvec_matrix, corr_matrix_constrain) { + using Eigen::Dynamic; + using Eigen::Matrix; + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(-1.0); + theta.push_back(0.0); + theta.push_back(0.5); + theta.push_back(1.0); + theta.push_back(2.0); + theta.push_back(1.0); + theta.push_back(-2.0); + theta.push_back(-1.0); + theta.push_back(0.0); + theta.push_back(0.5); + theta.push_back(1.0); + theta.push_back(2.0); + theta.push_back(1.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0; + auto R(deserializer.read_corr, false>(lp, 2, 3U)); + EXPECT_EQ(2, R.size()); + for (int k = 0; k < 2; k++) { + EXPECT_EQ(3, R[k].rows()); + EXPECT_EQ(3, R[k].cols()); + for (size_t i = 0; i < 3U; ++i) { + EXPECT_FLOAT_EQ(1.0, R[k](i, i)); + for (size_t j = i + 1; j < 3U; ++j) + EXPECT_FLOAT_EQ(R[k](i, j), R[k](j, i)); + } + Eigen::SelfAdjointEigenSolver< + Eigen::Matrix> + solver(R[k], Eigen::EigenvaluesOnly); + assert(solver.eigenvalues()[0] > 1E-10); + } +} + +TEST(deserializer_stdvec_matrix, corr_matrix_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(-1.0); + theta.push_back(0.0); + theta.push_back(0.5); + theta.push_back(1.0); + theta.push_back(2.0); + theta.push_back(1.0); + theta.push_back(-2.0); + theta.push_back(-1.0); + theta.push_back(0.0); + theta.push_back(0.5); + theta.push_back(1.0); + theta.push_back(2.0); + theta.push_back(1.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = -9.2; + auto R(deserializer.read_corr, true>(lp, 2, 3U)); + EXPECT_EQ(2, R.size()); + for (int k = 0; k < 2; k++) { + EXPECT_EQ(3, R[k].rows()); + EXPECT_EQ(3, R[k].cols()); + for (size_t i = 0; i < 3U; ++i) { + EXPECT_FLOAT_EQ(1.0, R[k](i, i)); + for (size_t j = i + 1; j < 3U; ++j) + EXPECT_FLOAT_EQ(R[k](i, j), R[k](j, i)); + } + Eigen::SelfAdjointEigenSolver< + Eigen::Matrix> + solver(R[k], Eigen::EigenvaluesOnly); + assert(solver.eigenvalues()[0] > 1E-10); + } +} + +TEST(deserializer_stdvec_matrix, cov_matrix) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + theta[0] = 6.3295234356180128; + theta[1] = 0.6351775806192667; + theta[2] = 3.8081029582054304; + theta[3] = 0.6351775806192667; + theta[4] = 1.9293554162496527; + theta[5] = 0.5483126868366485; + theta[6] = 3.8081029582054304; + theta[7] = 0.5483126868366485; + theta[8] = 3.0827514661973088; + theta[9] = 6.3295234356180128; + theta[10] = 0.6351775806192667; + theta[11] = 3.8081029582054304; + theta[12] = 0.6351775806192667; + theta[13] = 1.9293554162496527; + theta[14] = 0.5483126868366485; + theta[15] = 3.8081029582054304; + theta[16] = 0.5483126868366485; + theta[17] = 3.0827514661973088; + stan::io::deserializer deserializer(theta, theta_i); + auto S = deserializer.read_cov_matrix>(2, 3); + EXPECT_FLOAT_EQ(theta[0], S[0](0, 0)); + EXPECT_FLOAT_EQ(theta[1], S[0](1, 0)); + EXPECT_FLOAT_EQ(theta[7], S[0](2, 1)); + EXPECT_FLOAT_EQ(theta[8], S[0](2, 2)); +} +TEST(deserializer_stdvec_matrix, cov_matrix_exception) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + theta[0] = 6.3; + theta[1] = 0.7; + theta[2] = 0.6; + theta[3] = 1.9; + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_THROW(deserializer.read_cov_matrix>(2, 2), std::domain_error); + EXPECT_THROW(deserializer.read_cov_matrix>(2, 0), std::invalid_argument); +} + +TEST(deserializer_stdvec_matrix, cov_matrix_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(-1.0); + theta.push_back(0.0); + theta.push_back(0.5); + theta.push_back(1.0); + theta.push_back(2.0); + theta.push_back(1.0); + theta.push_back(-2.0); + theta.push_back(-1.0); + theta.push_back(0.0); + theta.push_back(0.5); + theta.push_back(1.0); + theta.push_back(2.0); + theta.push_back(1.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0; + auto S(deserializer.read_cov_matrix, false>(lp, 2, 3U)); + EXPECT_EQ(2, S.size()); + for (int k = 0; k < 2; ++k) { + EXPECT_EQ(3, S[k].rows()); + EXPECT_EQ(3, S[k].cols()); + for (size_t i = 0; i < 3U; ++i) { + for (size_t j = i + 1; j < 3U; ++j) { + EXPECT_FLOAT_EQ(S[k](i, j), S[k](j, i)); + } + } + Eigen::SelfAdjointEigenSolver< + Eigen::Matrix> + solver(S[k], Eigen::EigenvaluesOnly); + assert(solver.eigenvalues()[0] + > 1E-10); // check positive definite with smallest eigenvalue > 0 + } +} + +TEST(deserializer_stdvec_matrix, cov_matrix_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(-1.0); + theta.push_back(0.0); + theta.push_back(0.5); + theta.push_back(1.0); + theta.push_back(2.0); + theta.push_back(1.0); + theta.push_back(-2.0); + theta.push_back(-1.0); + theta.push_back(0.0); + theta.push_back(0.5); + theta.push_back(1.0); + theta.push_back(2.0); + theta.push_back(1.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = -3.1; + + auto S(deserializer.read_cov_matrix, true>(lp, 2, 3U)); + + EXPECT_EQ(2, S.size()); + for (int k = 0; k < 2; ++k) { + EXPECT_EQ(3, S[k].rows()); + EXPECT_EQ(3, S[k].cols()); + for (size_t i = 0; i < 3U; ++i) { + for (size_t j = i + 1; j < 3U; ++j) { + EXPECT_FLOAT_EQ(S[k](i, j), S[k](j, i)); + } + } + Eigen::SelfAdjointEigenSolver< + Eigen::Matrix> + solver(S[k], Eigen::EigenvaluesOnly); + assert(solver.eigenvalues()[0] + > 1E-10); // check positive definite with smallest eigenvalue > 0 + } +} + +TEST(deserializer_stdvec_matrix, cholesky_factor_cov) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + // column major + theta[0] = 1; + theta[1] = 2; + theta[2] = 3; + + theta[3] = 0; + theta[4] = 4; + theta[5] = 5; + + theta[6] = 0; + theta[7] = 0; + theta[8] = 6; + + theta[9] = 1; + theta[10] = 2; + theta[11] = 3; + + theta[12] = 0; + theta[13] = 4; + theta[14] = 5; + + theta[15] = 0; + theta[16] = 0; + theta[17] = 6; + + stan::io::deserializer deserializer(theta, theta_i); + auto S = deserializer.read_cholesky_factor_cov>(2, 3, 3); + EXPECT_FLOAT_EQ(theta[0], S[0](0, 0)); + EXPECT_FLOAT_EQ(theta[1], S[0](1, 0)); + EXPECT_FLOAT_EQ(theta[7], S[0](1, 2)); + EXPECT_FLOAT_EQ(theta[8], S[0](2, 2)); +} +TEST(deserializer_stdvec_matrix, cholesky_factor_cov_asymmetric) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + // column major + theta[0] = 1; + theta[1] = 2; + theta[2] = 3; + + theta[3] = 0; + theta[4] = 4; + theta[5] = 5; + + theta[6] = 1; + theta[7] = 2; + theta[8] = 3; + + theta[9] = 0; + theta[10] = 4; + theta[11] = 5; + + stan::io::deserializer deserializer(theta, theta_i); + auto S = deserializer.read_cholesky_factor_cov>(2, 3, 2); + EXPECT_FLOAT_EQ(theta[0], S[0](0, 0)); + EXPECT_FLOAT_EQ(theta[1], S[0](1, 0)); + EXPECT_FLOAT_EQ(theta[2], S[0](2, 0)); + + EXPECT_FLOAT_EQ(theta[3], S[0](0, 1)); + EXPECT_FLOAT_EQ(theta[4], S[0](1, 1)); + EXPECT_FLOAT_EQ(theta[5], S[0](2, 1)); +} + +TEST(deserializer_stdvec_matrix, cholesky_factor_cov_exception) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + theta[0] = -6.3; + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_THROW(deserializer.read_cholesky_factor_cov>(2, 2, 2), std::domain_error); + EXPECT_THROW(deserializer.read_cholesky_factor_cov>(2, 0, 0), std::domain_error); + + theta[0] = 1; + EXPECT_THROW(deserializer.read_cholesky_factor_cov>(2, 2, 3), std::domain_error); +} +TEST(deserializer_stdvec_matrix, cholesky_factor_cov_constrain) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 16; ++i) + theta.push_back(-static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0; + auto L(deserializer.read_cholesky_factor_cov, false>(lp, 2U, 3U, 3U)); + EXPECT_NO_THROW(stan::math::check_cholesky_factor( + "test_cholesky_factor_constrain", "L", L[0])); + EXPECT_EQ(2, L.size()); + EXPECT_EQ(3, L[0].rows()); + EXPECT_EQ(3, L[0].cols()); + EXPECT_EQ(9, L[0].size()); +} + + +TEST(deserializer_stdvec_matrix, cholesky_factor_cov_constrain_asymmetric) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 16; ++i) + theta.push_back(-static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0; + auto L(deserializer.read_cholesky_factor_cov, false>(lp, 2U, 3U, 2U)); + EXPECT_NO_THROW(stan::math::check_cholesky_factor( + "test_cholesky_factor_constrain", "L", L[0])); + EXPECT_EQ(2, L.size()); + EXPECT_EQ(3, L[0].rows()); + EXPECT_EQ(2, L[0].cols()); + EXPECT_EQ(6, L[0].size()); +} +TEST(deserializer_stdvec_matrix, cholesky_factor_cov_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 16; ++i) + theta.push_back(-static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 1.9; + auto L(deserializer.read_cholesky_factor_cov, true>(lp, 2U, 3U, 3U)); + EXPECT_NO_THROW(stan::math::check_cholesky_factor( + "test_cholesky_factor_constrain", "L", L[0])); + EXPECT_EQ(2, L.size()); + EXPECT_EQ(3, L[0].rows()); + EXPECT_EQ(3, L[0].cols()); + EXPECT_EQ(9, L[0].size()); + EXPECT_EQ(1.9 + log(L[0](0, 0)) + log(L[0](1, 1)) + log(L[0](2, 2)) + + + log(L[1](0, 0)) + log(L[1](1, 1)) + log(L[1](2, 2)), lp); +} +TEST(deserializer_stdvec_matrix, cholesky_factor_cov_constrain_jacobian_asymmetric) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 24; ++i) + theta.push_back(-static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 1.9; + auto L(deserializer.read_cholesky_factor_cov, true>(lp, 2U, 4U, 3U)); + EXPECT_NO_THROW(stan::math::check_cholesky_factor( + "test_cholesky_factor_constrain", "L", L[0])); + EXPECT_EQ(2, L.size()); + EXPECT_EQ(4, L[0].rows()); + EXPECT_EQ(3, L[0].cols()); + EXPECT_EQ(12, L[0].size()); + EXPECT_EQ(1.9 + log(L[0](0, 0)) + log(L[0](1, 1)) + log(L[0](2, 2)) + + + log(L[1](0, 0)) + log(L[1](1, 1)) + log(L[1](2, 2)), lp); +} + +TEST(deserializer_stdvec_matrix, cholesky_factor_corr) { + std::vector theta_i; + std::vector theta(18); + // column major + theta[0] = 1; + theta[1] = 0; + theta[2] = 0; + + theta[3] = 0; + theta[4] = 1; + theta[5] = 0; + + theta[6] = 0; + theta[7] = 0; + theta[8] = 1; + theta[9] = 1; + theta[10] = 0; + theta[11] = 0; + + theta[12] = 0; + theta[13] = 1; + theta[14] = 0; + + theta[15] = 0; + theta[16] = 0; + theta[17] = 1; + + stan::io::deserializer deserializer(theta, theta_i); + auto S = deserializer.read_cholesky_factor_corr>(2, 3); + EXPECT_FLOAT_EQ(theta[0], S[0](0, 0)); + EXPECT_FLOAT_EQ(theta[1], S[0](1, 0)); + EXPECT_FLOAT_EQ(theta[4], S[0](1, 1)); + EXPECT_FLOAT_EQ(theta[7], S[0](1, 2)); + EXPECT_FLOAT_EQ(theta[8], S[0](2, 2)); +} + +TEST(deserializer_stdvec_matrix, cholesky_factor_corr_exception) { + std::vector theta_i; + std::vector theta(18); + Eigen::Matrix S; + + // non lower-triangular matrix (column major) + // the rest of these tests are with check_cholesky_factor_corr + theta[0] = 1; + theta[1] = 0; + theta[2] = 0; + + theta[3] = 0.5; + theta[4] = 1; + theta[5] = 0; + + theta[6] = 0; + theta[7] = 0; + theta[8] = 1; + theta[9] = 1; + theta[10] = 0; + theta[11] = 0; + + theta[12] = 0.5; + theta[13] = 1; + theta[14] = 0; + + theta[15] = 0; + theta[16] = 0; + theta[17] = 1; + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_THROW(deserializer.read_cholesky_factor_corr>(2, 3), std::domain_error); +} +TEST(deserializer_stdvec_matrix, cholesky_factor_corr_constrain) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 16; ++i) + theta.push_back(-static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0; + auto L(deserializer.read_cholesky_factor_corr, false>(lp, 2U, 3U)); + EXPECT_NO_THROW(stan::math::check_cholesky_factor_corr( + "test_cholesky_factor_corr_constrain", "L", L[0])); + EXPECT_EQ(3, L[0].rows()); + EXPECT_EQ(3, L[0].cols()); + EXPECT_EQ(9, L[0].size()); +} +/* +// var matrix + + +TEST(deserializer_varmat, var_vector) { + using stan::math::var; + using stan::math::var_value; + using var_vec = var_value; + std::vector theta{0, 1, 2, 3, 4}; + std::vector theta_i; + stan::io::deserializer deserializer(theta, theta_i); + auto vec_x = deserializer.read(5); + EXPECT_TRUE((stan::is_var_vector::value)); + for (int i = 0; i < 5; ++i) { + EXPECT_EQ(vec_x.val()(i), i); + } + auto vec_x_empty = deserializer.read(0); + stan::math::recover_memory(); +} + +TEST(deserializer_varmat, var_vector_double) { + using stan::math::var; + using stan::math::var_value; + using var_vec = var_value; + std::vector theta{0, 1, 2, 3, 4}; + std::vector theta_i; + stan::io::deserializer deserializer(theta, theta_i); + auto vec_x = deserializer.read(5); + EXPECT_TRUE( + (stan::is_eigen_vector::value + && std::is_arithmetic>::value)); + for (int i = 0; i < 5; ++i) { + EXPECT_EQ(vec_x.val()(i), i); + } +} + +TEST(deserializer_varmat, var_row_vector) { + using stan::math::var; + using stan::math::var_value; + using var_row_vec = var_value; + std::vector theta{0, 1, 2, 3, 4}; + std::vector theta_i; + stan::io::deserializer deserializer(theta, theta_i); + auto vec_x = deserializer.read(5); + EXPECT_TRUE((stan::is_var_row_vector::value)); + for (int i = 0; i < 5; ++i) { + EXPECT_EQ(vec_x.val()(i), i); + } + auto vec_x_empty = deserializer.read(0); +} + +TEST(deserializer_varmat, var_row_vector_double) { + using stan::math::var; + using stan::math::var_value; + using var_row_vec = var_value; + std::vector theta{0, 1, 2, 3, 4}; + std::vector theta_i; + stan::io::deserializer deserializer(theta, theta_i); + auto vec_x = deserializer.read(5); + EXPECT_TRUE( + (stan::is_eigen_row_vector::value + && std::is_arithmetic>::value)); + for (int i = 0; i < 5; ++i) { + EXPECT_EQ(vec_x.val()(i), i); + } + auto vec_x_empty = deserializer.read(0); +} + +TEST(deserializer_varmat, var_matrix) { + using stan::math::var; + using stan::math::var_value; + using var_matrix = var_value; + std::vector theta{0, 1, 2, 3, 4, 5, 6, 7, 8}; + std::vector theta_i; + stan::io::deserializer deserializer(theta, theta_i); + auto mat_x = deserializer.read(3, 3); + EXPECT_TRUE((stan::is_var_matrix::value)); + for (int i = 0; i < 9; ++i) { + EXPECT_EQ(mat_x.val()(i), i); + } + auto mat_x_empty = deserializer.read(0, 0); +} + +TEST(deserializer_varmat, var_matrix_double) { + using stan::math::var; + using stan::math::var_value; + using var_matrix = var_value; + std::vector theta{0, 1, 2, 3, 4, 5, 6, 7, 8}; + std::vector theta_i; + stan::io::deserializer deserializer(theta, theta_i); + auto mat_x = deserializer.read(3, 3); + EXPECT_TRUE( + (stan::is_eigen_dense_dynamic::value + && std::is_arithmetic>::value)); + for (int i = 0; i < 9; ++i) { + EXPECT_EQ(mat_x.val()(i), i); + } + auto mat_x_empty = deserializer.read(0, 0); +} +*/ diff --git a/src/test/unit/io/deserializer_test.cpp b/src/test/unit/io/deserializer_test.cpp index 0cfaf975638..3cea7ebcab5 100644 --- a/src/test/unit/io/deserializer_test.cpp +++ b/src/test/unit/io/deserializer_test.cpp @@ -81,49 +81,7 @@ TEST(deserializer_rowvector, read) { EXPECT_FLOAT_EQ(11.0, z); } -TEST(deserializer_stdvec, std_vector_vector) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100U; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - auto y = deserializer.read>(5, 4); - EXPECT_EQ(5, y.size()); - int sentinal = 0; - for (int i = 0; i < y.size(); ++i) { - EXPECT_EQ(4, y[i].rows()); - EXPECT_EQ(1, y[i].cols()); - for (int j = 0; j < 4; ++j) { - EXPECT_FLOAT_EQ(sentinal, y[i].coeff(j)); - sentinal++; - } - } -} - -TEST(deserializer_stdvec, std_vector_std_vector_matrix) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 120U; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - auto y = deserializer.read>>(5, 4, 3, 2); - EXPECT_EQ(5, y.size()); - int sentinal = 0; - for (int i = 0; i < y.size(); ++i) { - EXPECT_EQ(4, y[i].size()); - for (int j = 0; j < 4; ++j) { - EXPECT_EQ(3, y[i][j].rows()); - EXPECT_EQ(2, y[i][j].cols()); - for (int k = 0; k < 6; ++k) { - EXPECT_FLOAT_EQ(sentinal, y[i][j].coeff(k)); - sentinal++; - } - } - } -} - // scalar bounds - TEST(deserializer_scalar, read) { std::vector theta_i; std::vector theta; @@ -495,868 +453,6 @@ TEST(deserializer_scalar, corr_constrain_jacobian) { EXPECT_FLOAT_EQ(expected_lp, lp); } -// vectors - -TEST(deserializer_vector, read) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100U; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - for (size_t i = 0; i < 7U; ++i) { - double x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - Eigen::Matrix y = deserializer.read(4); - EXPECT_EQ(4, y.rows()); - EXPECT_EQ(1, y.cols()); - EXPECT_EQ(4, y.size()); - EXPECT_FLOAT_EQ(7.0, y[0]); - EXPECT_FLOAT_EQ(8.0, y[1]); - EXPECT_FLOAT_EQ(9.0, y[2]); - EXPECT_FLOAT_EQ(10.0, y[3]); - - double z = deserializer.read(); - EXPECT_FLOAT_EQ(11.0, z); -} - -TEST(deserializer_vector, unit_vector) { - std::vector theta_i(0); - std::vector theta(4, sqrt(0.25)); - stan::io::deserializer deserializer(theta, theta_i); - Eigen::VectorXd y = deserializer.read_unit_vector(4); - EXPECT_EQ(4, y.size()); - EXPECT_FLOAT_EQ(sqrt(0.25), y[0]); - EXPECT_FLOAT_EQ(sqrt(0.25), y[1]); - EXPECT_FLOAT_EQ(sqrt(0.25), y[2]); - EXPECT_FLOAT_EQ(sqrt(0.25), y[3]); -} - -TEST(deserializer_vector, unit_vector_exception) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - theta[0] = 0.00; - theta[1] = -sqrt(0.29); - theta[2] = sqrt(0.70); - theta[3] = -sqrt(0.01); - theta[4] = sqrt(1.0); - theta[5] = sqrt(1.0); - EXPECT_NO_THROW(deserializer.read_unit_vector(4)); - EXPECT_THROW(deserializer.read_unit_vector(2), std::domain_error); - EXPECT_THROW(deserializer.read_unit_vector(0), std::invalid_argument); -} - -TEST(deserializer_vector, simplex) { - std::vector theta_i(0); - std::vector theta(4, 0.25); - stan::io::deserializer deserializer(theta, theta_i); - Eigen::Matrix y = deserializer.read_simplex(4); - EXPECT_EQ(4, y.size()); - EXPECT_FLOAT_EQ(0.25, y[0]); - EXPECT_FLOAT_EQ(0.25, y[1]); - EXPECT_FLOAT_EQ(0.25, y[2]); - EXPECT_FLOAT_EQ(0.25, y[3]); -} -TEST(deserializer_vector, simplex_exception) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - theta[0] = 0.00; - theta[1] = 0.29; - theta[2] = 0.70; - theta[3] = 0.01; - theta[4] = 1.0; - theta[5] = 1.0; - EXPECT_NO_THROW(deserializer.read_simplex(4)); - EXPECT_THROW(deserializer.read_simplex(2), std::domain_error); - EXPECT_THROW(deserializer.read_simplex(0), std::invalid_argument); -} - -TEST(deserializer_vector, ordered) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - EXPECT_FLOAT_EQ(0.0, deserializer.read()); // throw away theta[0] - Eigen::Matrix y = deserializer.read_ordered(5); - EXPECT_EQ(5, y.size()); - EXPECT_FLOAT_EQ(1.0, y[0]); - EXPECT_FLOAT_EQ(2.0, y[1]); - EXPECT_FLOAT_EQ(5.0, y[4]); - EXPECT_FLOAT_EQ(6.0, deserializer.read()); -} -TEST(deserializer_vector, ordered_exception) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - EXPECT_FLOAT_EQ(0.0, deserializer.read()); // throw away theta[0] - Eigen::Matrix y = deserializer.read_ordered(5); - EXPECT_EQ(5, y.size()); - EXPECT_FLOAT_EQ(1.0, y[0]); - EXPECT_FLOAT_EQ(2.0, y[1]); - EXPECT_FLOAT_EQ(5.0, y[4]); - EXPECT_FLOAT_EQ(6.0, deserializer.read()); -} -TEST(deserializer_vector, ordered_constrain) { - std::vector theta_i; - std::vector theta; - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); - double v0 = 3.0; - double v1 = v0 + exp(-1.0); - double v2 = v1 + exp(-2.0); - double v3 = v2 + exp(0.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = 0; - Eigen::Matrix phi(deserializer.read_ordered(lp, 4)); - EXPECT_FLOAT_EQ(v0, phi[0]); - EXPECT_FLOAT_EQ(v1, phi[1]); - EXPECT_FLOAT_EQ(v2, phi[2]); - EXPECT_FLOAT_EQ(v3, phi[3]); -} -TEST(deserializer_vector, ordered_constrain_jacobian) { - std::vector theta_i; - std::vector theta; - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); - double v0 = 3.0; - double v1 = v0 + exp(-1.0); - double v2 = v1 + exp(-2.0); - double v3 = v2 + exp(0.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = -101.1; - double expected_lp = lp - 1.0 - 2.0 + 0.0; - Eigen::Matrix phi(deserializer.read_ordered(lp, 4)); - EXPECT_FLOAT_EQ(v0, phi[0]); - EXPECT_FLOAT_EQ(v1, phi[1]); - EXPECT_FLOAT_EQ(v2, phi[2]); - EXPECT_FLOAT_EQ(v3, phi[3]); - EXPECT_FLOAT_EQ(expected_lp, lp); -} - -TEST(deserializer_vector, positive_ordered) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - EXPECT_FLOAT_EQ(0.0, deserializer.read()); // throw away theta[0] - Eigen::Matrix y = deserializer.read_positive_ordered(5); - EXPECT_EQ(5, y.size()); - EXPECT_FLOAT_EQ(1.0, y[0]); - EXPECT_FLOAT_EQ(2.0, y[1]); - EXPECT_FLOAT_EQ(5.0, y[4]); - EXPECT_FLOAT_EQ(6.0, deserializer.read()); -} - -TEST(deserializer_vector, positive_ordered_constrain) { - std::vector theta_i; - std::vector theta; - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); - double v0 = exp(3.0); - double v1 = v0 + exp(-1.0); - double v2 = v1 + exp(-2.0); - double v3 = v2 + exp(0.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = 0; - Eigen::Matrix phi( - deserializer.read_positive_ordered(lp, 4)); - EXPECT_FLOAT_EQ(v0, phi[0]); - EXPECT_FLOAT_EQ(v1, phi[1]); - EXPECT_FLOAT_EQ(v2, phi[2]); - EXPECT_FLOAT_EQ(v3, phi[3]); -} - -TEST(deserializer_vector, positive_ordered_constrain_jacobian) { - std::vector theta_i; - std::vector theta; - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); - double v0 = exp(3.0); - double v1 = v0 + exp(-1.0); - double v2 = v1 + exp(-2.0); - double v3 = v2 + exp(0.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = -101.1; - double expected_lp = lp + 3.0 - 1.0 - 2.0 + 0.0; - Eigen::Matrix phi( - deserializer.read_positive_ordered(lp, 4)); - EXPECT_FLOAT_EQ(v0, phi[0]); - EXPECT_FLOAT_EQ(v1, phi[1]); - EXPECT_FLOAT_EQ(v2, phi[2]); - EXPECT_FLOAT_EQ(v3, phi[3]); - EXPECT_FLOAT_EQ(expected_lp, lp); -} - -// matrix - -TEST(deserializer_matrix, read) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - for (int i = 0; i < 7; ++i) { - double x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - using eig_mat = Eigen::Matrix; - eig_mat y = deserializer.read(3, 2); - EXPECT_EQ(3, y.rows()); - EXPECT_EQ(2, y.cols()); - EXPECT_FLOAT_EQ(7.0, y(0, 0)); - EXPECT_FLOAT_EQ(8.0, y(1, 0)); - EXPECT_FLOAT_EQ(9.0, y(2, 0)); - EXPECT_FLOAT_EQ(10.0, y(0, 1)); - EXPECT_FLOAT_EQ(11.0, y(1, 1)); - EXPECT_FLOAT_EQ(12.0, y(2, 1)); - - double a = deserializer.read(); - EXPECT_FLOAT_EQ(13.0, a); -} - - -TEST(deserializer_matrix, matrix_lb) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - for (int i = 0; i < 7; ++i) { - double x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - double lb = -1.5; - Eigen::Matrix y - = deserializer.read_lb(lb, 3, 2); - EXPECT_EQ(3, y.rows()); - EXPECT_EQ(2, y.cols()); - EXPECT_FLOAT_EQ(7.0, y(0, 0)); - EXPECT_FLOAT_EQ(8.0, y(1, 0)); - EXPECT_FLOAT_EQ(9.0, y(2, 0)); - EXPECT_FLOAT_EQ(10.0, y(0, 1)); - EXPECT_FLOAT_EQ(11.0, y(1, 1)); - EXPECT_FLOAT_EQ(12.0, y(2, 1)); - - double a = deserializer.read(); - EXPECT_FLOAT_EQ(13.0, a); -} - -TEST(deserializer_matrix, matrix_lb_constrain) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - for (int i = 0; i < 7; ++i) { - double x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - double lb = -1.5; - double lp = 0; - Eigen::Matrix y - = deserializer.read_lb(lb, lp, 3, 2); - EXPECT_EQ(3, y.rows()); - EXPECT_EQ(2, y.cols()); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(7.0, lb), y(0, 0)); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(8.0, lb), y(1, 0)); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(9.0, lb), y(2, 0)); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(10.0, lb), y(0, 1)); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(11.0, lb), y(1, 1)); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(12.0, lb), y(2, 1)); - - double a = deserializer.read(); - EXPECT_FLOAT_EQ(13.0, a); -} - -TEST(deserializer_matrix, matrix_lb_constrain_lp) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - for (int i = 0; i < 7; ++i) { - double x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - double lb = -1.5; - double lp = -5.0; - Eigen::Matrix y - = deserializer.read_lb(lb, lp, 3, 2); - EXPECT_EQ(3, y.rows()); - EXPECT_EQ(2, y.cols()); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(7.0, lb, lp), y(0, 0)); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(8.0, lb, lp), y(1, 0)); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(9.0, lb, lp), y(2, 0)); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(10.0, lb, lp), y(0, 1)); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(11.0, lb, lp), y(1, 1)); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(12.0, lb, lp), y(2, 1)); - - double a = deserializer.read(); - EXPECT_FLOAT_EQ(13.0, a); -} - -TEST(deserializer_matrix, matrix_ub) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - for (int i = 0; i < 7; ++i) { - double x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - double ub = 12.5; - Eigen::Matrix y - = deserializer.read_ub(ub, 3, 2); - EXPECT_EQ(3, y.rows()); - EXPECT_EQ(2, y.cols()); - EXPECT_FLOAT_EQ(7.0, y(0, 0)); - EXPECT_FLOAT_EQ(8.0, y(1, 0)); - EXPECT_FLOAT_EQ(9.0, y(2, 0)); - EXPECT_FLOAT_EQ(10.0, y(0, 1)); - EXPECT_FLOAT_EQ(11.0, y(1, 1)); - EXPECT_FLOAT_EQ(12.0, y(2, 1)); - - double a = deserializer.read(); - EXPECT_FLOAT_EQ(13.0, a); -} - -TEST(deserializer_matrix, matrix_ub_constrain) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - for (int i = 0; i < 7; ++i) { - double x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - double ub = 14.1; - double lp = 0; - Eigen::Matrix y - = deserializer.read_ub(ub, lp, 3, 2); - EXPECT_EQ(3, y.rows()); - EXPECT_EQ(2, y.cols()); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(7.0, ub), y(0, 0)); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(8.0, ub), y(1, 0)); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(9.0, ub), y(2, 0)); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(10.0, ub), y(0, 1)); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(11.0, ub), y(1, 1)); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(12.0, ub), y(2, 1)); - - double a = deserializer.read(); - EXPECT_FLOAT_EQ(13.0, a); -} - -TEST(deserializer_matrix, matrix_ub_constrain_lp) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - for (int i = 0; i < 7; ++i) { - double x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - double ub = 12.1; - double lp = -5.0; - Eigen::Matrix y - = deserializer.read_ub(ub, lp, 3, 2); - EXPECT_EQ(3, y.rows()); - EXPECT_EQ(2, y.cols()); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(7.0, ub, lp), y(0, 0)); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(8.0, ub, lp), y(1, 0)); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(9.0, ub, lp), y(2, 0)); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(10.0, ub, lp), y(0, 1)); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(11.0, ub, lp), y(1, 1)); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(12.0, ub, lp), y(2, 1)); - - double a = deserializer.read(); - EXPECT_FLOAT_EQ(13.0, a); -} - -TEST(deserializer_matrix, matrix_lub) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - for (int i = 0; i < 7; ++i) { - double x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - double lb = 6.9; - double ub = 12.5; - Eigen::Matrix y - = deserializer.read_lub(lb, ub, 3, 2); - EXPECT_EQ(3, y.rows()); - EXPECT_EQ(2, y.cols()); - EXPECT_FLOAT_EQ(7.0, y(0, 0)); - EXPECT_FLOAT_EQ(8.0, y(1, 0)); - EXPECT_FLOAT_EQ(9.0, y(2, 0)); - EXPECT_FLOAT_EQ(10.0, y(0, 1)); - EXPECT_FLOAT_EQ(11.0, y(1, 1)); - EXPECT_FLOAT_EQ(12.0, y(2, 1)); - - double a = deserializer.read(); - EXPECT_FLOAT_EQ(13.0, a); -} - -TEST(deserializer_matrix, matrix_lub_constrain) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - for (int i = 0; i < 7; ++i) { - double x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - double lb = 3.5; - double ub = 14.1; - double lp = 0; - Eigen::Matrix y - = deserializer.read_lub(lb, ub, lp, 3, 2); - EXPECT_EQ(3, y.rows()); - EXPECT_EQ(2, y.cols()); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(7.0, lb, ub), y(0, 0)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(8.0, lb, ub), y(1, 0)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(9.0, lb, ub), y(2, 0)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(10.0, lb, ub), y(0, 1)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(11.0, lb, ub), y(1, 1)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(12.0, lb, ub), y(2, 1)); - - double a = deserializer.read(); - EXPECT_FLOAT_EQ(13.0, a); -} - -TEST(deserializer_matrix, matrix_lub_constrain_lp) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - for (int i = 0; i < 7; ++i) { - double x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - double lb = 4.1; - double ub = 12.1; - double lp = -5.0; - Eigen::Matrix y - = deserializer.read_lub(lb, ub, lp, 3, 2); - EXPECT_EQ(3, y.rows()); - EXPECT_EQ(2, y.cols()); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(7.0, lb, ub, lp), y(0, 0)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(8.0, lb, ub, lp), y(1, 0)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(9.0, lb, ub, lp), y(2, 0)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(10.0, lb, ub, lp), y(0, 1)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(11.0, lb, ub, lp), y(1, 1)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(12.0, lb, ub, lp), y(2, 1)); - - double a = deserializer.read(); - EXPECT_FLOAT_EQ(13.0, a); -} - -TEST(deserializer_matrix, corr_matrix) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - theta[0] = 1.0000000000000000; - theta[1] = 0.1817621852191252; - theta[2] = 0.8620926037637362; - theta[3] = 0.1817621852191252; - theta[4] = 1.0000000000000000; - theta[5] = 0.2248293054822660; - theta[6] = 0.8620926037637362; - theta[7] = 0.2248293054822660; - theta[8] = 1.0000000000000001; // allow some tolerance - stan::io::deserializer deserializer(theta, theta_i); - Eigen::Matrix S - = deserializer.read_corr(3); - EXPECT_FLOAT_EQ(theta[0], S(0, 0)); -} -TEST(deserializer_matrix, corr_matrix_exception) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - theta[0] = 1.5; - theta[1] = 1.0; - theta[2] = 2.0; - theta[3] = 0.0; - theta[4] = 1.0; - stan::io::deserializer deserializer(theta, theta_i); - EXPECT_THROW(deserializer.read_corr(1), std::domain_error); - EXPECT_THROW(deserializer.read_corr(2), std::domain_error); -} -TEST(deserializer_matrix, corr_matrix_constrain) { - using Eigen::Dynamic; - using Eigen::Matrix; - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(-1.0); - theta.push_back(0.0); - theta.push_back(0.5); - theta.push_back(1.0); - theta.push_back(2.0); - theta.push_back(1.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = 0; - Matrix R(deserializer.read_corr(lp, 3U)); - EXPECT_EQ(3, R.rows()); - EXPECT_EQ(3, R.cols()); - EXPECT_EQ(9, R.size()); - EXPECT_EQ(4U, deserializer.available()); - for (size_t i = 0; i < 3U; ++i) { - EXPECT_FLOAT_EQ(1.0, R(i, i)); - for (size_t j = i + 1; j < 3U; ++j) - EXPECT_FLOAT_EQ(R(i, j), R(j, i)); - } - Eigen::SelfAdjointEigenSolver< - Eigen::Matrix> - solver(R, Eigen::EigenvaluesOnly); - assert(solver.eigenvalues()[0] > 1E-10); -} -TEST(deserializer_matrix, corr_matrix_constrain_jacobian) { - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(-1.0); - theta.push_back(0.0); - theta.push_back(0.5); - theta.push_back(1.0); - theta.push_back(2.0); - theta.push_back(1.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = -9.2; - Eigen::Matrix R( - deserializer.read_corr(lp, 3U)); - EXPECT_EQ(3, R.rows()); - EXPECT_EQ(3, R.cols()); - EXPECT_EQ(9, R.size()); - EXPECT_EQ(4U, deserializer.available()); - for (size_t i = 0; i < 3U; ++i) { - EXPECT_FLOAT_EQ(1.0, R(i, i)); - for (size_t j = i + 1; j < 3U; ++j) - EXPECT_FLOAT_EQ(R(i, j), R(j, i)); - } - Eigen::SelfAdjointEigenSolver< - Eigen::Matrix> - solver(R, Eigen::EigenvaluesOnly); - assert(solver.eigenvalues()[0] > 1E-10); - // FIXME: test jacobian -} - -TEST(deserializer_matrix, cov_matrix) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - theta[0] = 6.3295234356180128; - theta[1] = 0.6351775806192667; - theta[2] = 3.8081029582054304; - theta[3] = 0.6351775806192667; - theta[4] = 1.9293554162496527; - theta[5] = 0.5483126868366485; - theta[6] = 3.8081029582054304; - theta[7] = 0.5483126868366485; - theta[8] = 3.0827514661973088; - stan::io::deserializer deserializer(theta, theta_i); - Eigen::Matrix S - = deserializer.read_cov_matrix(3); - EXPECT_FLOAT_EQ(theta[0], S(0, 0)); - EXPECT_FLOAT_EQ(theta[1], S(1, 0)); - EXPECT_FLOAT_EQ(theta[7], S(2, 1)); - EXPECT_FLOAT_EQ(theta[8], S(2, 2)); -} -TEST(deserializer_matrix, cov_matrix_exception) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - theta[0] = 6.3; - theta[1] = 0.7; - theta[2] = 0.6; - theta[3] = 1.9; - stan::io::deserializer deserializer(theta, theta_i); - EXPECT_THROW(deserializer.read_cov_matrix(2), std::domain_error); - EXPECT_THROW(deserializer.read_cov_matrix(0), std::invalid_argument); -} -TEST(deserializer_matrix, cov_matrix_constrain) { - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(-1.0); - theta.push_back(0.0); - theta.push_back(0.5); - theta.push_back(1.0); - theta.push_back(2.0); - theta.push_back(1.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = 0; - Eigen::Matrix S( - deserializer.read_cov_matrix(lp, 3U)); - EXPECT_EQ(3, S.rows()); - EXPECT_EQ(3, S.cols()); - EXPECT_EQ(9, S.size()); - EXPECT_EQ(1U, deserializer.available()); - for (size_t i = 0; i < 3U; ++i) - for (size_t j = i + 1; j < 3U; ++j) - EXPECT_FLOAT_EQ(S(i, j), S(j, i)); - Eigen::SelfAdjointEigenSolver< - Eigen::Matrix> - solver(S, Eigen::EigenvaluesOnly); - assert(solver.eigenvalues()[0] - > 1E-10); // check positive definite with smallest eigenvalue > 0 -} -TEST(deserializer_matrix, cov_matrix_constrain_jacobian) { - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(-1.0); - theta.push_back(0.0); - theta.push_back(0.5); - theta.push_back(1.0); - theta.push_back(2.0); - theta.push_back(1.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = -3.1; - - Eigen::Matrix S( - deserializer.read_cov_matrix(lp, 3U)); - - EXPECT_EQ(3, S.rows()); - EXPECT_EQ(3, S.cols()); - EXPECT_EQ(9, S.size()); - EXPECT_EQ(1U, deserializer.available()); - for (size_t i = 0; i < 3U; ++i) - for (size_t j = i + 1; j < 3U; ++j) - EXPECT_FLOAT_EQ(S(i, j), S(j, i)); - Eigen::SelfAdjointEigenSolver< - Eigen::Matrix> - solver(S, Eigen::EigenvaluesOnly); - assert(solver.eigenvalues()[0] - > 1E-10); // check positive definite with smallest eigenvalue > 0 - // FIXME: test Jacobian -} - -TEST(deserializer_matrix, cholesky_factor_cov) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - // column major - theta[0] = 1; - theta[1] = 2; - theta[2] = 3; - - theta[3] = 0; - theta[4] = 4; - theta[5] = 5; - - theta[6] = 0; - theta[7] = 0; - theta[8] = 6; - stan::io::deserializer deserializer(theta, theta_i); - Eigen::Matrix S - = deserializer.read_cholesky_factor_cov(3, 3); - EXPECT_FLOAT_EQ(theta[0], S(0, 0)); - EXPECT_FLOAT_EQ(theta[1], S(1, 0)); - EXPECT_FLOAT_EQ(theta[7], S(1, 2)); - EXPECT_FLOAT_EQ(theta[8], S(2, 2)); -} -TEST(deserializer_matrix, cholesky_factor_cov_asymmetric) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - // column major - theta[0] = 1; - theta[1] = 2; - theta[2] = 3; - - theta[3] = 0; - theta[4] = 4; - theta[5] = 5; - - stan::io::deserializer deserializer(theta, theta_i); - Eigen::Matrix S - = deserializer.read_cholesky_factor_cov(3, 2); - EXPECT_FLOAT_EQ(theta[0], S(0, 0)); - EXPECT_FLOAT_EQ(theta[1], S(1, 0)); - EXPECT_FLOAT_EQ(theta[2], S(2, 0)); - - EXPECT_FLOAT_EQ(theta[3], S(0, 1)); - EXPECT_FLOAT_EQ(theta[4], S(1, 1)); - EXPECT_FLOAT_EQ(theta[5], S(2, 1)); -} - -TEST(deserializer_matrix, cholesky_factor_cov_exception) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - theta[0] = -6.3; - stan::io::deserializer deserializer(theta, theta_i); - EXPECT_THROW(deserializer.read_cholesky_factor_cov(2, 2), std::domain_error); - EXPECT_THROW(deserializer.read_cholesky_factor_cov(0, 0), std::domain_error); - - theta[0] = 1; - EXPECT_THROW(deserializer.read_cholesky_factor_cov(2, 3), std::domain_error); -} -TEST(deserializer_matrix, cholesky_factor_cov_constrain) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 8; ++i) - theta.push_back(-static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - double lp = 0; - Eigen::Matrix L( - deserializer.read_cholesky_factor_cov(lp, 3U, 3U)); - EXPECT_NO_THROW(stan::math::check_cholesky_factor( - "test_cholesky_factor_constrain", "L", L)); - EXPECT_EQ(3, L.rows()); - EXPECT_EQ(3, L.cols()); - EXPECT_EQ(9, L.size()); - EXPECT_EQ(2U, deserializer.available()); -} - - -TEST(deserializer_matrix, cholesky_factor_cov_constrain_asymmetric) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 8; ++i) - theta.push_back(-static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - double lp = 0; - Eigen::Matrix L( - deserializer.read_cholesky_factor_cov(lp, 3U, 2U)); - EXPECT_NO_THROW(stan::math::check_cholesky_factor( - "test_cholesky_factor_constrain", "L", L)); - EXPECT_EQ(3, L.rows()); - EXPECT_EQ(2, L.cols()); - EXPECT_EQ(6, L.size()); - EXPECT_EQ(3U, deserializer.available()); -} -TEST(deserializer_matrix, cholesky_factor_cov_constrain_jacobian) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 8; ++i) - theta.push_back(-static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - double lp = 1.9; - Eigen::Matrix L( - deserializer.read_cholesky_factor_cov(lp, 3U, 3U)); - EXPECT_NO_THROW(stan::math::check_cholesky_factor( - "test_cholesky_factor_constrain", "L", L)); - EXPECT_EQ(3, L.rows()); - EXPECT_EQ(3, L.cols()); - EXPECT_EQ(9, L.size()); - EXPECT_EQ(2U, deserializer.available()); - EXPECT_EQ(1.9 + log(L(0, 0)) + log(L(1, 1)) + log(L(2, 2)), lp); -} -TEST(deserializer_matrix, cholesky_factor_cov_constrain_jacobian_asymmetric) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 12; ++i) - theta.push_back(-static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - double lp = 1.9; - Eigen::Matrix L( - deserializer.read_cholesky_factor_cov(lp, 4U, 3U)); - EXPECT_NO_THROW(stan::math::check_cholesky_factor( - "test_cholesky_factor_constrain", "L", L)); - EXPECT_EQ(4, L.rows()); - EXPECT_EQ(3, L.cols()); - EXPECT_EQ(12, L.size()); - EXPECT_EQ(3U, deserializer.available()); - EXPECT_EQ(1.9 + log(L(0, 0)) + log(L(1, 1)) + log(L(2, 2)), lp); -} - -TEST(deserializer_matrix, cholesky_factor_corr) { - std::vector theta_i; - std::vector theta(9); - // column major - theta[0] = 1; - theta[1] = 0; - theta[2] = 0; - - theta[3] = 0; - theta[4] = 1; - theta[5] = 0; - - theta[6] = 0; - theta[7] = 0; - theta[8] = 1; - stan::io::deserializer deserializer(theta, theta_i); - Eigen::Matrix S - = deserializer.read_cholesky_factor_corr(3); - EXPECT_FLOAT_EQ(theta[0], S(0, 0)); - EXPECT_FLOAT_EQ(theta[1], S(1, 0)); - EXPECT_FLOAT_EQ(theta[4], S(1, 1)); - EXPECT_FLOAT_EQ(theta[7], S(1, 2)); - EXPECT_FLOAT_EQ(theta[8], S(2, 2)); -} - -TEST(deserializer_matrix, cholesky_factor_corr_exception) { - std::vector theta_i; - std::vector theta(9); - Eigen::Matrix S; - - // non lower-triangular matrix (column major) - // the rest of these tests are with check_cholesky_factor_corr - theta[0] = 1; - theta[1] = 0; - theta[2] = 0; - - theta[3] = 0.5; - theta[4] = 1; - theta[5] = 0; - - theta[6] = 0; - theta[7] = 0; - theta[8] = 1; - stan::io::deserializer deserializer(theta, theta_i); - EXPECT_THROW(deserializer.read_cholesky_factor_corr(3), std::domain_error); -} -TEST(deserializer_matrix, cholesky_factor_corr_constrain) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 8; ++i) - theta.push_back(-static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - double lp = 0; - Eigen::Matrix L( - deserializer.read_cholesky_factor_corr(lp, 3U)); - EXPECT_NO_THROW(stan::math::check_cholesky_factor_corr( - "test_cholesky_factor_corr_constrain", "L", L)); - EXPECT_EQ(3, L.rows()); - EXPECT_EQ(3, L.cols()); - EXPECT_EQ(9, L.size()); - EXPECT_EQ(5U, deserializer.available()); -} - // var matrix diff --git a/src/test/unit/io/deserializer_varmat_test.cpp b/src/test/unit/io/deserializer_varmat_test.cpp new file mode 100644 index 00000000000..71798118491 --- /dev/null +++ b/src/test/unit/io/deserializer_varmat_test.cpp @@ -0,0 +1,862 @@ +#include +#include + +using var_matrix_t = stan::math::var_value; +using var_vector_t = stan::math::var_value; + +// vectors +TEST(deserializer_var_vector, read) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100U; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (size_t i = 0; i < 7U; ++i) { + stan::math::var x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x.val()); + } + var_vector_t y = deserializer.read(4); + EXPECT_EQ(4, y.rows()); + EXPECT_EQ(1, y.cols()); + EXPECT_EQ(4, y.size()); + EXPECT_FLOAT_EQ(7.0, y.val()[0]); + EXPECT_FLOAT_EQ(8.0, y.val()[1]); + EXPECT_FLOAT_EQ(9.0, y.val()[2]); + EXPECT_FLOAT_EQ(10.0, y.val()[3]); + + stan::math::var z = deserializer.read(); + EXPECT_FLOAT_EQ(11.0, z.val()); +} + +TEST(deserializer_var_vector, unit_vector) { + std::vector theta_i(0); + std::vector theta(4, sqrt(0.25)); + stan::io::deserializer deserializer(theta, theta_i); + var_vector_t y = deserializer.read_unit_vector(4); + EXPECT_EQ(4, y.size()); + EXPECT_FLOAT_EQ(sqrt(0.25), y.val()[0]); + EXPECT_FLOAT_EQ(sqrt(0.25), y.val()[1]); + EXPECT_FLOAT_EQ(sqrt(0.25), y.val()[2]); + EXPECT_FLOAT_EQ(sqrt(0.25), y.val()[3]); +} + +TEST(deserializer_var_vector, unit_vector_exception) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + theta[0] = 0.00; + theta[1] = -sqrt(0.29); + theta[2] = sqrt(0.70); + theta[3] = -sqrt(0.01); + theta[4] = sqrt(1.0); + theta[5] = sqrt(1.0); + EXPECT_NO_THROW(deserializer.read_unit_vector(4)); + EXPECT_THROW(deserializer.read_unit_vector(2), std::domain_error); + EXPECT_THROW(deserializer.read_unit_vector(0), std::invalid_argument); +} + +TEST(deserializer_var_vector, simplex) { + std::vector theta_i(0); + std::vector theta(4, 0.25); + stan::io::deserializer deserializer(theta, theta_i); + var_vector_t y = deserializer.read_simplex(4); + EXPECT_EQ(4, y.size()); + EXPECT_FLOAT_EQ(0.25, y.val()[0]); + EXPECT_FLOAT_EQ(0.25, y.val()[1]); + EXPECT_FLOAT_EQ(0.25, y.val()[2]); + EXPECT_FLOAT_EQ(0.25, y.val()[3]); +} +TEST(deserializer_var_vector, simplex_exception) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + theta[0] = 0.00; + theta[1] = 0.29; + theta[2] = 0.70; + theta[3] = 0.01; + theta[4] = 1.0; + theta[5] = 1.0; + EXPECT_NO_THROW(deserializer.read_simplex(4)); + EXPECT_THROW(deserializer.read_simplex(2), std::domain_error); + EXPECT_THROW(deserializer.read_simplex(0), std::invalid_argument); +} + +TEST(deserializer_var_vector, ordered) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_FLOAT_EQ(0.0, deserializer.read().val()); // throw away theta[0] + var_vector_t y = deserializer.read_ordered(5); + EXPECT_EQ(5, y.size()); + EXPECT_FLOAT_EQ(1.0, y.val()[0]); + EXPECT_FLOAT_EQ(2.0, y.val()[1]); + EXPECT_FLOAT_EQ(5.0, y.val()[4]); + EXPECT_FLOAT_EQ(6.0, deserializer.read().val()); +} +TEST(deserializer_var_vector, ordered_exception) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_FLOAT_EQ(0.0, deserializer.read().val()); // throw away theta[0] + var_vector_t y = deserializer.read_ordered(5); + EXPECT_EQ(5, y.size()); + EXPECT_FLOAT_EQ(1.0, y.val()[0]); + EXPECT_FLOAT_EQ(2.0, y.val()[1]); + EXPECT_FLOAT_EQ(5.0, y.val()[4]); + EXPECT_FLOAT_EQ(6.0, deserializer.read().val()); +} +TEST(deserializer_var_vector, ordered_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + double v0 = 3.0; + double v1 = v0 + exp(-1.0); + double v2 = v1 + exp(-2.0); + double v3 = v2 + exp(0.0); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp = 0; + var_vector_t phi(deserializer.read_ordered(lp, 4)); + EXPECT_FLOAT_EQ(v0, phi.val()[0]); + EXPECT_FLOAT_EQ(v1, phi.val()[1]); + EXPECT_FLOAT_EQ(v2, phi.val()[2]); + EXPECT_FLOAT_EQ(v3, phi.val()[3]); +} +TEST(deserializer_var_vector, ordered_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + double v0 = 3.0; + double v1 = v0 + exp(-1.0); + double v2 = v1 + exp(-2.0); + double v3 = v2 + exp(0.0); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp = -101.1; + double expected_lp = lp.val() - 1.0 - 2.0 + 0.0; + var_vector_t phi(deserializer.read_ordered(lp, 4)); + EXPECT_FLOAT_EQ(v0, phi.val()[0]); + EXPECT_FLOAT_EQ(v1, phi.val()[1]); + EXPECT_FLOAT_EQ(v2, phi.val()[2]); + EXPECT_FLOAT_EQ(v3, phi.val()[3]); + EXPECT_FLOAT_EQ(expected_lp, lp.val()); +} + +TEST(deserializer_var_vector, positive_ordered) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_FLOAT_EQ(0.0, deserializer.read().val()); // throw away theta[0] + var_vector_t y = deserializer.read_positive_ordered(5); + EXPECT_EQ(5, y.size()); + EXPECT_FLOAT_EQ(1.0, y.val()[0]); + EXPECT_FLOAT_EQ(2.0, y.val()[1]); + EXPECT_FLOAT_EQ(5.0, y.val()[4]); + EXPECT_FLOAT_EQ(6.0, deserializer.read().val()); +} + +TEST(deserializer_var_vector, positive_ordered_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + double v0 = exp(3.0); + double v1 = v0 + exp(-1.0); + double v2 = v1 + exp(-2.0); + double v3 = v2 + exp(0.0); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp = 0; + var_vector_t phi( + deserializer.read_positive_ordered(lp, 4)); + EXPECT_FLOAT_EQ(v0, phi.val()[0]); + EXPECT_FLOAT_EQ(v1, phi.val()[1]); + EXPECT_FLOAT_EQ(v2, phi.val()[2]); + EXPECT_FLOAT_EQ(v3, phi.val()[3]); +} + +TEST(deserializer_var_vector, positive_ordered_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + double v0 = exp(3.0); + double v1 = v0 + exp(-1.0); + double v2 = v1 + exp(-2.0); + double v3 = v2 + exp(0.0); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp = -101.1; + double expected_lp = lp.val() + 3.0 - 1.0 - 2.0 + 0.0; + var_vector_t phi( + deserializer.read_positive_ordered(lp, 4)); + EXPECT_FLOAT_EQ(v0, phi.val()[0]); + EXPECT_FLOAT_EQ(v1, phi.val()[1]); + EXPECT_FLOAT_EQ(v2, phi.val()[2]); + EXPECT_FLOAT_EQ(v3, phi.val()[3]); + EXPECT_FLOAT_EQ(expected_lp, lp.val()); +} + +// matrix + +TEST(deserializer_var_matrix, read) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (int i = 0; i < 7; ++i) { + stan::math::var x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x.val()); + } + var_matrix_t y = deserializer.read(3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(7.0, y.val()(0, 0)); + EXPECT_FLOAT_EQ(8.0, y.val()(1, 0)); + EXPECT_FLOAT_EQ(9.0, y.val()(2, 0)); + EXPECT_FLOAT_EQ(10.0, y.val()(0, 1)); + EXPECT_FLOAT_EQ(11.0, y.val()(1, 1)); + EXPECT_FLOAT_EQ(12.0, y.val()(2, 1)); + + stan::math::var a = deserializer.read(); + EXPECT_FLOAT_EQ(13.0, a.val()); +} + + +TEST(deserializer_var_matrix, matrix_lb) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (int i = 0; i < 7; ++i) { + stan::math::var x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x.val()); + } + stan::math::var lb = -1.5; + var_matrix_t y = deserializer.read_lb(lb, 3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(7.0, y.val()(0, 0)); + EXPECT_FLOAT_EQ(8.0, y.val()(1, 0)); + EXPECT_FLOAT_EQ(9.0, y.val()(2, 0)); + EXPECT_FLOAT_EQ(10.0, y.val()(0, 1)); + EXPECT_FLOAT_EQ(11.0, y.val()(1, 1)); + EXPECT_FLOAT_EQ(12.0, y.val()(2, 1)); + + stan::math::var a = deserializer.read(); + EXPECT_FLOAT_EQ(13.0, a.val()); +} + +TEST(deserializer_var_matrix, matrix_lb_constrain) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (int i = 0; i < 7; ++i) { + stan::math::var x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x.val()); + } + stan::math::var lb = -1.5; + stan::math::var lp = 0; + var_matrix_t y + = deserializer.read_lb(lb, lp, 3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(7.0, lb).val(), y.val()(0, 0)); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(8.0, lb).val(), y.val()(1, 0)); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(9.0, lb).val(), y.val()(2, 0)); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(10.0, lb).val(), y.val()(0, 1)); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(11.0, lb).val(), y.val()(1, 1)); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(12.0, lb).val(), y.val()(2, 1)); + + stan::math::var a = deserializer.read(); + EXPECT_FLOAT_EQ(13.0, a.val()); +} + +TEST(deserializer_var_matrix, matrix_lb_constrain_lp) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (int i = 0; i < 7; ++i) { + stan::math::var x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x.val()); + } + stan::math::var lb = -1.5; + stan::math::var lp = -5.0; + var_matrix_t y + = deserializer.read_lb(lb, lp, 3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(7.0, lb, lp).val(), y.val()(0, 0)); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(8.0, lb, lp).val(), y.val()(1, 0)); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(9.0, lb, lp).val(), y.val()(2, 0)); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(10.0, lb, lp).val(), y.val()(0, 1)); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(11.0, lb, lp).val(), y.val()(1, 1)); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(12.0, lb, lp).val(), y.val()(2, 1)); + + stan::math::var a = deserializer.read(); + EXPECT_FLOAT_EQ(13.0, a.val()); +} + +TEST(deserializer_var_matrix, matrix_ub) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (int i = 0; i < 7; ++i) { + stan::math::var x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x.val()); + } + stan::math::var ub = 12.5; + var_matrix_t y + = deserializer.read_ub(ub, 3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(7.0, y.val()(0, 0)); + EXPECT_FLOAT_EQ(8.0, y.val()(1, 0)); + EXPECT_FLOAT_EQ(9.0, y.val()(2, 0)); + EXPECT_FLOAT_EQ(10.0, y.val()(0, 1)); + EXPECT_FLOAT_EQ(11.0, y.val()(1, 1)); + EXPECT_FLOAT_EQ(12.0, y.val()(2, 1)); + + stan::math::var a = deserializer.read(); + EXPECT_FLOAT_EQ(13.0, a.val()); +} + +TEST(deserializer_var_matrix, matrix_ub_constrain) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (int i = 0; i < 7; ++i) { + stan::math::var x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x.val()); + } + stan::math::var ub = 14.1; + stan::math::var lp = 0; + var_matrix_t y + = deserializer.read_ub(ub, lp, 3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(7.0, ub).val(), y.val()(0, 0)); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(8.0, ub).val(), y.val()(1, 0)); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(9.0, ub).val(), y.val()(2, 0)); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(10.0, ub).val(), y.val()(0, 1)); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(11.0, ub).val(), y.val()(1, 1)); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(12.0, ub).val(), y.val()(2, 1)); + + stan::math::var a = deserializer.read(); + EXPECT_FLOAT_EQ(13.0, a.val()); +} + +TEST(deserializer_var_matrix, matrix_ub_constrain_lp) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (int i = 0; i < 7; ++i) { + stan::math::var x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x.val()); + } + stan::math::var ub = 12.1; + stan::math::var lp = -5.0; + var_matrix_t y + = deserializer.read_ub(ub, lp, 3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(7.0, ub, lp).val(), y.val()(0, 0)); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(8.0, ub, lp).val(), y.val()(1, 0)); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(9.0, ub, lp).val(), y.val()(2, 0)); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(10.0, ub, lp).val(), y.val()(0, 1)); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(11.0, ub, lp).val(), y.val()(1, 1)); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(12.0, ub, lp).val(), y.val()(2, 1)); + + stan::math::var a = deserializer.read(); + EXPECT_FLOAT_EQ(13.0, a.val()); +} + +TEST(deserializer_var_matrix, matrix_lub) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (int i = 0; i < 7; ++i) { + stan::math::var x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x.val()); + } + stan::math::var lb = 6.9; + stan::math::var ub = 12.5; + var_matrix_t y = deserializer.read_lub(lb, ub, 3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(7.0, y.val()(0, 0)); + EXPECT_FLOAT_EQ(8.0, y.val()(1, 0)); + EXPECT_FLOAT_EQ(9.0, y.val()(2, 0)); + EXPECT_FLOAT_EQ(10.0, y.val()(0, 1)); + EXPECT_FLOAT_EQ(11.0, y.val()(1, 1)); + EXPECT_FLOAT_EQ(12.0, y.val()(2, 1)); + + stan::math::var a = deserializer.read(); + EXPECT_FLOAT_EQ(13.0, a.val()); +} + +TEST(deserializer_var_matrix, matrix_lub_constrain) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (int i = 0; i < 7; ++i) { + stan::math::var x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x.val()); + } + stan::math::var lb = 3.5; + stan::math::var ub = 14.1; + stan::math::var lp = 0; + var_matrix_t y + = deserializer.read_lub(lb, ub, lp, 3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(7.0, lb, ub).val(), y.val()(0, 0)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(8.0, lb, ub).val(), y.val()(1, 0)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(9.0, lb, ub).val(), y.val()(2, 0)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(10.0, lb, ub).val(), y.val()(0, 1)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(11.0, lb, ub).val(), y.val()(1, 1)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(12.0, lb, ub).val(), y.val()(2, 1)); + + stan::math::var a = deserializer.read(); + EXPECT_FLOAT_EQ(13.0, a.val()); +} + +TEST(deserializer_var_matrix, matrix_lub_constrain_lp) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (int i = 0; i < 7; ++i) { + stan::math::var x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x.val()); + } + stan::math::var lb = 4.1; + stan::math::var ub = 12.1; + stan::math::var lp = -5.0; + var_matrix_t y + = deserializer.read_lub(lb, ub, lp, 3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(7.0, lb, ub, lp).val(), y.val()(0, 0)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(8.0, lb, ub, lp).val(), y.val()(1, 0)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(9.0, lb, ub, lp).val(), y.val()(2, 0)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(10.0, lb, ub, lp).val(), y.val()(0, 1)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(11.0, lb, ub, lp).val(), y.val()(1, 1)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(12.0, lb, ub, lp).val(), y.val()(2, 1)); + + stan::math::var a = deserializer.read(); + EXPECT_FLOAT_EQ(13.0, a.val()); +} + +TEST(deserializer_var_matrix, corr_matrix) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + theta[0] = 1.0000000000000000; + theta[1] = 0.1817621852191252; + theta[2] = 0.8620926037637362; + theta[3] = 0.1817621852191252; + theta[4] = 1.0000000000000000; + theta[5] = 0.2248293054822660; + theta[6] = 0.8620926037637362; + theta[7] = 0.2248293054822660; + theta[8] = 1.0000000000000001; // allow some tolerance + stan::io::deserializer deserializer(theta, theta_i); + var_matrix_t S = deserializer.read_corr(3); + EXPECT_FLOAT_EQ(theta[0].val(), S.val()(0, 0)); +} +TEST(deserializer_var_matrix, corr_matrix_exception) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + theta[0] = 1.5; + theta[1] = 1.0; + theta[2] = 2.0; + theta[3] = 0.0; + theta[4] = 1.0; + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_THROW(deserializer.read_corr(1), std::domain_error); + EXPECT_THROW(deserializer.read_corr(2), std::domain_error); +} + +TEST(deserializer_var_matrix, corr_matrix_constrain) { + using Eigen::Dynamic; + using Eigen::Matrix; + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(-1.0); + theta.push_back(0.0); + theta.push_back(0.5); + theta.push_back(1.0); + theta.push_back(2.0); + theta.push_back(1.0); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp = 0; + var_matrix_t R(deserializer.read_corr(lp, 3U)); + EXPECT_EQ(3, R.rows()); + EXPECT_EQ(3, R.cols()); + EXPECT_EQ(9, R.size()); + EXPECT_EQ(4U, deserializer.available()); + for (size_t i = 0; i < 3U; ++i) { + EXPECT_FLOAT_EQ(1.0, R.val()(i, i)); + for (size_t j = i + 1; j < 3U; ++j) + EXPECT_FLOAT_EQ(R.val()(i, j), R.val()(j, i)); + } + Eigen::SelfAdjointEigenSolver< + Eigen::Matrix> + solver(R.val(), Eigen::EigenvaluesOnly); + assert(solver.eigenvalues()[0] > 1E-10); +} +TEST(deserializer_var_matrix, corr_matrix_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(-1.0); + theta.push_back(0.0); + theta.push_back(0.5); + theta.push_back(1.0); + theta.push_back(2.0); + theta.push_back(1.0); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp = -9.2; + var_matrix_t R(deserializer.read_corr(lp, 3U)); + EXPECT_EQ(3, R.rows()); + EXPECT_EQ(3, R.cols()); + EXPECT_EQ(9, R.size()); + EXPECT_EQ(4U, deserializer.available()); + for (size_t i = 0; i < 3U; ++i) { + EXPECT_FLOAT_EQ(1.0, R.val()(i, i)); + for (size_t j = i + 1; j < 3U; ++j) + EXPECT_FLOAT_EQ(R.val()(i, j), R.val()(j, i)); + } + Eigen::SelfAdjointEigenSolver< + Eigen::Matrix> + solver(R.val(), Eigen::EigenvaluesOnly); + assert(solver.eigenvalues()[0] > 1E-10); + // FIXME: test jacobian +} + +TEST(deserializer_var_matrix, cov_matrix) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + theta[0] = 6.3295234356180128; + theta[1] = 0.6351775806192667; + theta[2] = 3.8081029582054304; + theta[3] = 0.6351775806192667; + theta[4] = 1.9293554162496527; + theta[5] = 0.5483126868366485; + theta[6] = 3.8081029582054304; + theta[7] = 0.5483126868366485; + theta[8] = 3.0827514661973088; + stan::io::deserializer deserializer(theta, theta_i); + var_matrix_t S = deserializer.read_cov_matrix(3); + EXPECT_FLOAT_EQ(theta[0].val(), S.val()(0, 0)); + EXPECT_FLOAT_EQ(theta[1].val(), S.val()(1, 0)); + EXPECT_FLOAT_EQ(theta[7].val(), S.val()(2, 1)); + EXPECT_FLOAT_EQ(theta[8].val(), S.val()(2, 2)); +} +TEST(deserializer_var_matrix, cov_matrix_exception) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + theta[0] = 6.3; + theta[1] = 0.7; + theta[2] = 0.6; + theta[3] = 1.9; + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_THROW(deserializer.read_cov_matrix(2), std::domain_error); + EXPECT_THROW(deserializer.read_cov_matrix(0), std::invalid_argument); +} +TEST(deserializer_var_matrix, cov_matrix_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(-1.0); + theta.push_back(0.0); + theta.push_back(0.5); + theta.push_back(1.0); + theta.push_back(2.0); + theta.push_back(1.0); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp = 0; + var_matrix_t S( + deserializer.read_cov_matrix(lp, 3U)); + EXPECT_EQ(3, S.rows()); + EXPECT_EQ(3, S.cols()); + EXPECT_EQ(9, S.size()); + EXPECT_EQ(1U, deserializer.available()); + for (size_t i = 0; i < 3U; ++i) { + for (size_t j = i + 1; j < 3U; ++j) { + EXPECT_FLOAT_EQ(S.val()(i, j), S.val()(j, i)); + } + } + using eig_m = Eigen::Matrix; + Eigen::SelfAdjointEigenSolver solver(S.val(), Eigen::EigenvaluesOnly); + assert(solver.eigenvalues()[0] + > 1E-10); // check positive definite with smallest eigenvalue > 0 +} +TEST(deserializer_var_matrix, cov_matrix_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(-1.0); + theta.push_back(0.0); + theta.push_back(0.5); + theta.push_back(1.0); + theta.push_back(2.0); + theta.push_back(1.0); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp = -3.1; + + var_matrix_t S(deserializer.read_cov_matrix(lp, 3U)); + + EXPECT_EQ(3, S.rows()); + EXPECT_EQ(3, S.cols()); + EXPECT_EQ(9, S.size()); + EXPECT_EQ(1U, deserializer.available()); + for (size_t i = 0; i < 3U; ++i) { + for (size_t j = i + 1; j < 3U; ++j) { + EXPECT_FLOAT_EQ(S.val()(i, j), S.val()(j, i)); + } + } + using eig_m = Eigen::Matrix; + Eigen::SelfAdjointEigenSolver solver(S.val(), Eigen::EigenvaluesOnly); + assert(solver.eigenvalues()[0] + > 1E-10); // check positive definite with smallest eigenvalue > 0 + // FIXME: test Jacobian +} + +TEST(deserializer_var_matrix, cholesky_factor_cov) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + // column major + theta[0] = 1; + theta[1] = 2; + theta[2] = 3; + + theta[3] = 0; + theta[4] = 4; + theta[5] = 5; + + theta[6] = 0; + theta[7] = 0; + theta[8] = 6; + stan::io::deserializer deserializer(theta, theta_i); + var_matrix_t S + = deserializer.read_cholesky_factor_cov(3, 3); + EXPECT_FLOAT_EQ(theta[0].val(), S.val()(0, 0)); + EXPECT_FLOAT_EQ(theta[1].val(), S.val()(1, 0)); + EXPECT_FLOAT_EQ(theta[7].val(), S.val()(1, 2)); + EXPECT_FLOAT_EQ(theta[8].val(), S.val()(2, 2)); +} +TEST(deserializer_var_matrix, cholesky_factor_cov_asymmetric) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + // column major + theta[0] = 1; + theta[1] = 2; + theta[2] = 3; + + theta[3] = 0; + theta[4] = 4; + theta[5] = 5; + + stan::io::deserializer deserializer(theta, theta_i); + var_matrix_t S + = deserializer.read_cholesky_factor_cov(3, 2); + EXPECT_FLOAT_EQ(theta[0].val(), S.val()(0, 0)); + EXPECT_FLOAT_EQ(theta[1].val(), S.val()(1, 0)); + EXPECT_FLOAT_EQ(theta[2].val(), S.val()(2, 0)); + + EXPECT_FLOAT_EQ(theta[3].val(), S.val()(0, 1)); + EXPECT_FLOAT_EQ(theta[4].val(), S.val()(1, 1)); + EXPECT_FLOAT_EQ(theta[5].val(), S.val()(2, 1)); +} + +TEST(deserializer_var_matrix, cholesky_factor_cov_exception) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + theta[0] = -6.3; + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_THROW(deserializer.read_cholesky_factor_cov(2, 2), std::domain_error); + EXPECT_THROW(deserializer.read_cholesky_factor_cov(0, 0), std::domain_error); + + theta[0] = 1; + EXPECT_THROW(deserializer.read_cholesky_factor_cov(2, 3), std::domain_error); +} +TEST(deserializer_var_matrix, cholesky_factor_cov_constrain) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 8; ++i) + theta.push_back(-static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp = 0; + var_matrix_t L( + deserializer.read_cholesky_factor_cov(lp, 3U, 3U)); + EXPECT_NO_THROW(stan::math::check_cholesky_factor( + "test_cholesky_factor_constrain", "L", L.val())); + EXPECT_EQ(3, L.rows()); + EXPECT_EQ(3, L.cols()); + EXPECT_EQ(9, L.size()); + EXPECT_EQ(2U, deserializer.available()); +} + + +TEST(deserializer_var_matrix, cholesky_factor_cov_constrain_asymmetric) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 8; ++i) + theta.push_back(-static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp = 0; + var_matrix_t L( + deserializer.read_cholesky_factor_cov(lp, 3U, 2U)); + EXPECT_NO_THROW(stan::math::check_cholesky_factor( + "test_cholesky_factor_constrain", "L", L.val())); + EXPECT_EQ(3, L.rows()); + EXPECT_EQ(2, L.cols()); + EXPECT_EQ(6, L.size()); + EXPECT_EQ(3U, deserializer.available()); +} +TEST(deserializer_var_matrix, cholesky_factor_cov_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 8; ++i) + theta.push_back(-static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp = 1.9; + var_matrix_t L( + deserializer.read_cholesky_factor_cov(lp, 3U, 3U)); + EXPECT_NO_THROW(stan::math::check_cholesky_factor( + "test_cholesky_factor_constrain", "L", L.val())); + EXPECT_EQ(3, L.rows()); + EXPECT_EQ(3, L.cols()); + EXPECT_EQ(9, L.size()); + EXPECT_EQ(2U, deserializer.available()); + EXPECT_EQ(1.9 + log(L.val()(0, 0)) + log(L.val()(1, 1)) + log(L.val()(2, 2)), lp.val()); +} +TEST(deserializer_var_matrix, cholesky_factor_cov_constrain_jacobian_asymmetric) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 12; ++i) + theta.push_back(-static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp = 1.9; + var_matrix_t L( + deserializer.read_cholesky_factor_cov(lp, 4U, 3U)); + EXPECT_NO_THROW(stan::math::check_cholesky_factor( + "test_cholesky_factor_constrain", "L", L.val())); + EXPECT_EQ(4, L.rows()); + EXPECT_EQ(3, L.cols()); + EXPECT_EQ(12, L.size()); + EXPECT_EQ(3U, deserializer.available()); + EXPECT_EQ(1.9 + log(L.val()(0, 0)) + log(L.val()(1, 1)) + log(L.val()(2, 2)), lp.val()); +} + +TEST(deserializer_var_matrix, cholesky_factor_corr) { + std::vector theta_i; + std::vector theta(9); + // column major + theta[0] = 1; + theta[1] = 0; + theta[2] = 0; + + theta[3] = 0; + theta[4] = 1; + theta[5] = 0; + + theta[6] = 0; + theta[7] = 0; + theta[8] = 1; + stan::io::deserializer deserializer(theta, theta_i); + var_matrix_t S + = deserializer.read_cholesky_factor_corr(3); + EXPECT_FLOAT_EQ(theta[0].val(), S.val()(0, 0)); + EXPECT_FLOAT_EQ(theta[1].val(), S.val()(1, 0)); + EXPECT_FLOAT_EQ(theta[4].val(), S.val()(1, 1)); + EXPECT_FLOAT_EQ(theta[7].val(), S.val()(1, 2)); + EXPECT_FLOAT_EQ(theta[8].val(), S.val()(2, 2)); +} + +TEST(deserializer_var_matrix, cholesky_factor_corr_exception) { + std::vector theta_i; + std::vector theta(9); + var_matrix_t S; + + // non lower-triangular matrix (column major) + // the rest of these tests are with check_cholesky_factor_corr + theta[0] = 1; + theta[1] = 0; + theta[2] = 0; + + theta[3] = 0.5; + theta[4] = 1; + theta[5] = 0; + + theta[6] = 0; + theta[7] = 0; + theta[8] = 1; + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_THROW(deserializer.read_cholesky_factor_corr(3), std::domain_error); +} +TEST(deserializer_var_matrix, cholesky_factor_corr_constrain) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 8; ++i) + theta.push_back(-static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp = 0; + var_matrix_t L( + deserializer.read_cholesky_factor_corr(lp, 3U)); + EXPECT_NO_THROW(stan::math::check_cholesky_factor_corr( + "test_cholesky_factor_corr_constrain", "L", L.val())); + EXPECT_EQ(3, L.rows()); + EXPECT_EQ(3, L.cols()); + EXPECT_EQ(9, L.size()); + EXPECT_EQ(5U, deserializer.available()); +} From 6c6aa3f44b61447d4163b8670faf7e918d93612c Mon Sep 17 00:00:00 2001 From: Stan Jenkins Date: Fri, 26 Feb 2021 15:16:37 +0000 Subject: [PATCH 09/29] [Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.04.1 (tags/RELEASE_600/final) --- .../unit/io/deserializer_stdvector_test.cpp | 203 ++++++++++++------ src/test/unit/io/deserializer_test.cpp | 101 +++++---- src/test/unit/io/deserializer_varmat_test.cpp | 98 +++++---- 3 files changed, 250 insertions(+), 152 deletions(-) diff --git a/src/test/unit/io/deserializer_stdvector_test.cpp b/src/test/unit/io/deserializer_stdvector_test.cpp index 784c9320f1b..c30dcd7572a 100644 --- a/src/test/unit/io/deserializer_stdvector_test.cpp +++ b/src/test/unit/io/deserializer_stdvector_test.cpp @@ -1,7 +1,6 @@ #include #include - TEST(deserializer_rowvector, read) { std::vector theta_i; std::vector theta; @@ -12,7 +11,8 @@ TEST(deserializer_rowvector, read) { double x = deserializer.read(); EXPECT_FLOAT_EQ(static_cast(i), x); } - Eigen::Matrix y = deserializer.read(4); + Eigen::Matrix y + = deserializer.read(4); EXPECT_EQ(4, y.cols()); EXPECT_EQ(1, y.rows()); EXPECT_EQ(4, y.size()); @@ -50,7 +50,8 @@ TEST(deserializer_stdvec, std_vector_std_vector_matrix) { for (size_t i = 0; i < 120U; ++i) theta.push_back(static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); - auto y = deserializer.read>>(5, 4, 3, 2); + auto y = deserializer.read>>(5, 4, 3, + 2); EXPECT_EQ(5, y.size()); int sentinal = 0; for (int i = 0; i < y.size(); ++i) { @@ -85,7 +86,8 @@ TEST(deserializer_stdvec_scalar, read_lb) { theta.push_back(-1.0); theta.push_back(2.0); stan::io::deserializer deserializer(theta, theta_i); - auto x = deserializer.read_lb>(std::vector{-2.0, 1.0}, 2); + auto x = deserializer.read_lb>( + std::vector{-2.0, 1.0}, 2); EXPECT_FLOAT_EQ(-1.0, x[0]); EXPECT_FLOAT_EQ(2.0, x[1]); EXPECT_EQ(0U, deserializer.available()); @@ -97,7 +99,8 @@ TEST(deserializer_stdvec_scalar, read_lb_exception) { theta.push_back(2.0); stan::io::deserializer deserializer(theta, theta_i); EXPECT_NO_THROW(deserializer.read_lb>(-1.0, 2)); - EXPECT_THROW(deserializer.read_lb>(3.0, 2), std::runtime_error); + EXPECT_THROW(deserializer.read_lb>(3.0, 2), + std::runtime_error); } TEST(deserializer_stdvec_scalar, read_lb_constrain) { std::vector theta_i; @@ -108,7 +111,8 @@ TEST(deserializer_stdvec_scalar, read_lb_constrain) { theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); double lp = 0.0; - auto ret = deserializer.read_lb, false>(std::vector{1.0, 5, -2, 15}, lp, 4); + auto ret = deserializer.read_lb, false>( + std::vector{1.0, 5, -2, 15}, lp, 4); EXPECT_FLOAT_EQ(1.0 + exp(-2.0), ret[0]); EXPECT_FLOAT_EQ(5.0 + exp(3.0), ret[1]); EXPECT_FLOAT_EQ(-2.0 + exp(-1.0), ret[2]); @@ -123,7 +127,8 @@ TEST(deserializer_stdvec_scalar, read_lb_constrain_jacobian) { theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); double lp = -1.5; - auto ret = deserializer.read_lb, true>(std::vector{1.0, 5.0, -2.0, 15.0}, lp, 4); + auto ret = deserializer.read_lb, true>( + std::vector{1.0, 5.0, -2.0, 15.0}, lp, 4); EXPECT_FLOAT_EQ(1.0 + exp(-2.0), ret[0]); EXPECT_FLOAT_EQ(5.0 + exp(3.0), ret[1]); EXPECT_FLOAT_EQ(-2.0 + exp(-1.0), ret[2]); @@ -151,7 +156,8 @@ TEST(deserializer_stdvec_scalar, read_ub_exception) { theta.push_back(2.0); stan::io::deserializer deserializer(theta, theta_i); EXPECT_NO_THROW(deserializer.read_ub>(3.0, 2)); - EXPECT_THROW(deserializer.read_ub>(1.0, 2), std::runtime_error); + EXPECT_THROW(deserializer.read_ub>(1.0, 2), + std::runtime_error); } TEST(deserializer_stdvec_scalar, read_ub_constrain) { std::vector theta_i; @@ -162,7 +168,8 @@ TEST(deserializer_stdvec_scalar, read_ub_constrain) { theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); double lp = 0; - auto ret = deserializer.read_ub, false>(std::vector{1.0, 5.0, -2, 15}, lp, 4); + auto ret = deserializer.read_ub, false>( + std::vector{1.0, 5.0, -2, 15}, lp, 4); EXPECT_FLOAT_EQ(1.0 - exp(-2.0), ret[0]); EXPECT_FLOAT_EQ(5.0 - exp(3.0), ret[1]); EXPECT_FLOAT_EQ(-2.0 - exp(-1.0), ret[2]); @@ -177,7 +184,8 @@ TEST(deserializer_stdvec_scalar, read_ub_constrain_jacobian) { theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); double lp = -12.9; - auto ret = deserializer.read_ub, false>(std::vector{1.0, 5.0, -2, 15}, lp, 4); + auto ret = deserializer.read_ub, false>( + std::vector{1.0, 5.0, -2, 15}, lp, 4); EXPECT_FLOAT_EQ(1.0 - exp(-2.0), ret[0]); EXPECT_FLOAT_EQ(5.0 - exp(3.0), ret[1]); EXPECT_FLOAT_EQ(-2.0 - exp(-1.0), ret[2]); @@ -187,7 +195,6 @@ TEST(deserializer_stdvec_scalar, read_ub_constrain_jacobian) { // lub - TEST(deserializer_stdvec_scalar, read_lub) { std::vector theta_i; std::vector theta; @@ -207,7 +214,8 @@ TEST(deserializer_stdvec_scalar, read_lub_exception) { theta.push_back(2.0); stan::io::deserializer deserializer(theta, theta_i); EXPECT_NO_THROW(deserializer.read_lub>(-2.0, 2.0, 2)); - EXPECT_THROW(deserializer.read_lub>(-1.0, 1.0, 2), std::runtime_error); + EXPECT_THROW(deserializer.read_lub>(-1.0, 1.0, 2), + std::runtime_error); } const double inv_logit_m2 = 0.1192029; // stan::math::inv_logit(-2.0) const double inv_logit_m1 = 0.2689414; // stan::math::inv_logit(-1.0) @@ -225,7 +233,7 @@ TEST(deserializer_stdvec_scalar, read_lub_constrain) { double lp = 0; std::vector lb{0.0, 3.0, -3.0, -15.0}; std::vector ub{1.0, 5.0, 2.0, 15.0}; - auto ret = deserializer.read_lub, false>(lb, ub, lp, 4); + auto ret = deserializer.read_lub, false>(lb, ub, lp, 4); EXPECT_FLOAT_EQ(inv_logit_m2, ret[0]); EXPECT_FLOAT_EQ(3.0 + 2.0 * inv_logit_3, ret[1]); EXPECT_FLOAT_EQ(-3.0 + 5.0 * inv_logit_m1, ret[2]); @@ -263,7 +271,8 @@ TEST(deserializer_stdvec_scalar, read_offset_multiplier) { theta.push_back(-1.0); theta.push_back(2.0); stan::io::deserializer deserializer(theta, theta_i); - auto x = deserializer.read_offset_multiplier>(-3.0, 3.0, 2); + auto x + = deserializer.read_offset_multiplier>(-3.0, 3.0, 2); EXPECT_FLOAT_EQ(-1.0, x[0]); EXPECT_FLOAT_EQ(2.0, x[1]); @@ -276,8 +285,10 @@ TEST(deserializer_stdvec_scalar, offset_multiplier_exception) { theta.push_back(2.0); stan::io::deserializer deserializer(theta, theta_i); double lp = 0; - EXPECT_NO_THROW(deserializer.read_offset_multiplier>(-2.0, -2.0, 2)); - EXPECT_THROW((deserializer.read_offset_multiplier, false>(-2.0, -2.0, lp, 2)), + EXPECT_NO_THROW( + deserializer.read_offset_multiplier>(-2.0, -2.0, 2)); + EXPECT_THROW((deserializer.read_offset_multiplier, false>( + -2.0, -2.0, lp, 2)), std::runtime_error); } @@ -292,7 +303,8 @@ TEST(deserializer_stdvec_scalar, offset_multiplier_constrain) { double lp = 0; std::vector offset{0, 3, -3, -15}; std::vector mult{1.0, 5.0, 2.0, 15}; - auto ret = deserializer.read_offset_multiplier, false>(offset, mult, lp, 4); + auto ret = deserializer.read_offset_multiplier, false>( + offset, mult, lp, 4); EXPECT_FLOAT_EQ(-2.0, ret[0]); EXPECT_FLOAT_EQ(3.0 + 5.0 * 3.0, ret[1]); EXPECT_FLOAT_EQ(-3.0 + 2.0 * -1.0, ret[2]); @@ -309,7 +321,8 @@ TEST(deserializer_stdvec_scalar, offset_multiplier_constrain_jacobian) { double lp = -7.2; std::vector offset{0, 3, -3, -15}; std::vector mult{1.0, 5.0, 2.0, 15}; - auto ret = deserializer.read_offset_multiplier, true>(offset, mult, lp, 4); + auto ret = deserializer.read_offset_multiplier, true>( + offset, mult, lp, 4); EXPECT_FLOAT_EQ(-2.0, ret[0]); EXPECT_FLOAT_EQ(3.0 + 5.0 * 3.0, ret[1]); EXPECT_FLOAT_EQ(-3.0 + 2.0 * -1.0, ret[2]); @@ -343,7 +356,7 @@ TEST(deserializer_stdvec_scalar, prob_constrain) { theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); double lp = 0; - auto ret = deserializer.read_prob, false>(lp, 4); + auto ret = deserializer.read_prob, false>(lp, 4); EXPECT_FLOAT_EQ(inv_logit_m2, ret[0]); EXPECT_FLOAT_EQ(inv_logit_3, ret[1]); EXPECT_FLOAT_EQ(inv_logit_m1, ret[2]); @@ -359,7 +372,7 @@ TEST(deserializer_stdvec_scalar, prob_constrain_jacobian) { theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); double lp = -0.88; - auto ret = deserializer.read_prob, true>(lp, 4); + auto ret = deserializer.read_prob, true>(lp, 4); EXPECT_FLOAT_EQ(inv_logit_m2, ret[0]); EXPECT_FLOAT_EQ(inv_logit_3, ret[1]); EXPECT_FLOAT_EQ(inv_logit_m1, ret[2]); @@ -395,7 +408,8 @@ TEST(deserializer_stdvec_scalar, corr_exception) { stan::io::deserializer deserializer(theta, theta_i); double lp = 0; EXPECT_NO_THROW((deserializer.read_corr, false>(lp, 3))); - EXPECT_THROW(deserializer.read_corr>(3), std::runtime_error); + EXPECT_THROW(deserializer.read_corr>(3), + std::runtime_error); } TEST(deserializer_stdvec_scalar, corr_constrain) { std::vector theta_i; @@ -406,7 +420,7 @@ TEST(deserializer_stdvec_scalar, corr_constrain) { theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); double lp = 0; - auto ret = deserializer.read_corr, false>(lp, 4); + auto ret = deserializer.read_corr, false>(lp, 4); EXPECT_FLOAT_EQ(tanh(-2.0), ret[0]); EXPECT_FLOAT_EQ(tanh(3.0), ret[1]); EXPECT_FLOAT_EQ(tanh(-1.0), ret[2]); @@ -422,7 +436,7 @@ TEST(deserializer_stdvec_scalar, corr_constrain_jacobian) { theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); double lp = -10.0; - auto ret = deserializer.read_corr, true>(lp, 4); + auto ret = deserializer.read_corr, true>(lp, 4); EXPECT_FLOAT_EQ(tanh(-2.0), ret[0]); EXPECT_FLOAT_EQ(tanh(3.0), ret[1]); EXPECT_FLOAT_EQ(tanh(-1.0), ret[2]); @@ -487,9 +501,14 @@ TEST(deserializer_stdvec_vector, unit_vector_exception) { theta[3] = -sqrt(0.01); theta[4] = sqrt(1.0); theta[5] = sqrt(1.0); - EXPECT_NO_THROW(deserializer.read_unit_vector>(1, 4)); - EXPECT_THROW(deserializer.read_unit_vector>(1, 2), std::domain_error); - EXPECT_THROW(deserializer.read_unit_vector>(1, 0), std::invalid_argument); + EXPECT_NO_THROW( + deserializer.read_unit_vector>(1, 4)); + EXPECT_THROW( + deserializer.read_unit_vector>(1, 2), + std::domain_error); + EXPECT_THROW( + deserializer.read_unit_vector>(1, 0), + std::invalid_argument); } TEST(deserializer_stdvec_vector, simplex) { @@ -522,9 +541,12 @@ TEST(deserializer_stdvec_vector, simplex_exception) { theta[7] = 0.01; theta[8] = 1.0; theta[9] = 1.0; - EXPECT_NO_THROW(deserializer.read_simplex>(2, 4)); - EXPECT_THROW(deserializer.read_simplex>(2, 2), std::domain_error); - EXPECT_THROW(deserializer.read_simplex>(2, 0), std::invalid_argument); + EXPECT_NO_THROW( + deserializer.read_simplex>(2, 4)); + EXPECT_THROW(deserializer.read_simplex>(2, 2), + std::domain_error); + EXPECT_THROW(deserializer.read_simplex>(2, 0), + std::invalid_argument); } TEST(deserializer_stdvec_vector, ordered) { @@ -564,7 +586,8 @@ TEST(deserializer_stdvec_vector, ordered_constrain) { double v3 = v2 + exp(0.0); stan::io::deserializer deserializer(theta, theta_i); double lp = 0; - auto phi(deserializer.read_ordered, false>(lp, 2, 4)); + auto phi( + deserializer.read_ordered, false>(lp, 2, 4)); EXPECT_EQ(2, phi.size()); for (int i = 0; i < 2; ++i) { EXPECT_EQ(4, phi[i].rows()); @@ -593,7 +616,8 @@ TEST(deserializer_stdvec_vector, ordered_constrain_jacobian) { stan::io::deserializer deserializer(theta, theta_i); double lp = -101.1; double expected_lp = lp - 1.0 - 2.0 + 0.0 - 1.0 - 2.0 + 0.0; - auto phi(deserializer.read_ordered, true>(lp, 2, 4)); + auto phi( + deserializer.read_ordered, true>(lp, 2, 4)); EXPECT_FLOAT_EQ(v0, phi[0][0]); EXPECT_FLOAT_EQ(v1, phi[0][1]); EXPECT_FLOAT_EQ(v2, phi[0][2]); @@ -612,7 +636,8 @@ TEST(deserializer_stdvec_vector, positive_ordered) { theta.push_back(static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); EXPECT_FLOAT_EQ(0.0, deserializer.read()); // throw away theta[0] - auto y = deserializer.read_positive_ordered>(5, 2); + auto y + = deserializer.read_positive_ordered>(5, 2); EXPECT_EQ(5, y.size()); double sentinal = 1; for (int i = 0; i < 5; ++i) { @@ -642,7 +667,9 @@ TEST(deserializer_stdvec_vector, positive_ordered_constrain) { double v3 = v2 + exp(0.0); stan::io::deserializer deserializer(theta, theta_i); double lp = 0; - auto phi(deserializer.read_positive_ordered, false>(lp, 2, 4)); + auto phi( + deserializer.read_positive_ordered, false>( + lp, 2, 4)); EXPECT_FLOAT_EQ(v0, phi[0][0]); EXPECT_FLOAT_EQ(v1, phi[0][1]); EXPECT_FLOAT_EQ(v2, phi[0][2]); @@ -671,7 +698,9 @@ TEST(deserializer_stdvec_vector, positive_ordered_constrain_jacobian) { stan::io::deserializer deserializer(theta, theta_i); double lp = -101.1; double expected_lp = lp + 3.0 - 1.0 - 2.0 + 0.0 + 3.0 - 1.0 - 2.0 + 0.0; - auto phi(deserializer.read_positive_ordered, true>(lp, 2, 4)); + auto phi( + deserializer.read_positive_ordered, true>( + lp, 2, 4)); EXPECT_FLOAT_EQ(v0, phi[0][0]); EXPECT_FLOAT_EQ(v1, phi[0][1]); EXPECT_FLOAT_EQ(v2, phi[0][2]); @@ -709,7 +738,6 @@ TEST(deserializer_stdvec_matrix, read) { } } - TEST(deserializer_stdvec_matrix, matrix_lb) { std::vector theta_i; std::vector theta; @@ -746,7 +774,8 @@ TEST(deserializer_stdvec_matrix, matrix_lb_constrain) { } double lb = -1.5; double lp = 0; - auto y = deserializer.read_lb, false>(lb, lp, 2, 3, 2); + auto y = deserializer.read_lb, false>(lb, lp, 2, + 3, 2); EXPECT_EQ(2, y.size()); double sentinal = 7; for (int i = 0; i < 2; ++i) { @@ -771,8 +800,8 @@ TEST(deserializer_stdvec_matrix, matrix_lb_constrain_lp) { } double lb = -1.5; double lp = -5.0; - auto y - = deserializer.read_lb, true>(lb, lp, 2, 3, 2); + auto y = deserializer.read_lb, true>(lb, lp, 2, + 3, 2); EXPECT_EQ(2, y.size()); double sentinal = 7; for (int i = 0; i < 2; ++i) { @@ -821,7 +850,8 @@ TEST(deserializer_stdvec_matrix, matrix_ub_constrain) { } double ub = 14.1; double lp = 0; - auto y = deserializer.read_ub, false>(ub, lp, 2, 3, 2); + auto y = deserializer.read_ub, false>(ub, lp, 2, + 3, 2); EXPECT_EQ(2, y.size()); double sentinal = 7; for (int i = 0; i < 2; ++i) { @@ -846,7 +876,8 @@ TEST(deserializer_stdvec_matrix, matrix_ub_constrain_lp) { } double ub = 12.1; double lp = -5.0; - auto y = deserializer.read_ub, true>(ub, lp, 2, 3, 2); + auto y = deserializer.read_ub, true>(ub, lp, 2, + 3, 2); EXPECT_EQ(2, y.size()); double sentinal = 7; for (int i = 0; i < 2; ++i) { @@ -897,7 +928,8 @@ TEST(deserializer_stdvec_matrix, matrix_lub_constrain) { double lb = 3.5; double ub = 14.1; double lp = 0; - auto y = deserializer.read_lub, false>(lb, ub, lp, 2, 3, 2); + auto y = deserializer.read_lub, false>( + lb, ub, lp, 2, 3, 2); EXPECT_EQ(2, y.size()); double sentinal = 7; for (int i = 0; i < 2; ++i) { @@ -923,7 +955,8 @@ TEST(deserializer_stdvec_matrix, matrix_lub_constrain_lp) { double lb = 4.1; double ub = 12.1; double lp = -5.0; - auto y = deserializer.read_lub, true>(lb, ub, lp, 2,3, 2); + auto y = deserializer.read_lub, true>(lb, ub, lp, + 2, 3, 2); EXPECT_EQ(2, y.size()); double sentinal = 7; for (int i = 0; i < 2; ++i) { @@ -975,8 +1008,10 @@ TEST(deserializer_stdvec_matrix, corr_matrix_exception) { theta[3] = 0.0; theta[4] = 1.0; stan::io::deserializer deserializer(theta, theta_i); - EXPECT_THROW(deserializer.read_corr>(1, 1), std::domain_error); - EXPECT_THROW(deserializer.read_corr>(2, 3), std::domain_error); + EXPECT_THROW(deserializer.read_corr>(1, 1), + std::domain_error); + EXPECT_THROW(deserializer.read_corr>(2, 3), + std::domain_error); } TEST(deserializer_stdvec_matrix, corr_matrix_constrain) { using Eigen::Dynamic; @@ -999,7 +1034,8 @@ TEST(deserializer_stdvec_matrix, corr_matrix_constrain) { theta.push_back(1.0); stan::io::deserializer deserializer(theta, theta_i); double lp = 0; - auto R(deserializer.read_corr, false>(lp, 2, 3U)); + auto R( + deserializer.read_corr, false>(lp, 2, 3U)); EXPECT_EQ(2, R.size()); for (int k = 0; k < 2; k++) { EXPECT_EQ(3, R[k].rows()); @@ -1035,7 +1071,7 @@ TEST(deserializer_stdvec_matrix, corr_matrix_constrain_jacobian) { theta.push_back(1.0); stan::io::deserializer deserializer(theta, theta_i); double lp = -9.2; - auto R(deserializer.read_corr, true>(lp, 2, 3U)); + auto R(deserializer.read_corr, true>(lp, 2, 3U)); EXPECT_EQ(2, R.size()); for (int k = 0; k < 2; k++) { EXPECT_EQ(3, R[k].rows()); @@ -1092,8 +1128,10 @@ TEST(deserializer_stdvec_matrix, cov_matrix_exception) { theta[2] = 0.6; theta[3] = 1.9; stan::io::deserializer deserializer(theta, theta_i); - EXPECT_THROW(deserializer.read_cov_matrix>(2, 2), std::domain_error); - EXPECT_THROW(deserializer.read_cov_matrix>(2, 0), std::invalid_argument); + EXPECT_THROW(deserializer.read_cov_matrix>(2, 2), + std::domain_error); + EXPECT_THROW(deserializer.read_cov_matrix>(2, 0), + std::invalid_argument); } TEST(deserializer_stdvec_matrix, cov_matrix_constrain) { @@ -1115,7 +1153,8 @@ TEST(deserializer_stdvec_matrix, cov_matrix_constrain) { theta.push_back(1.0); stan::io::deserializer deserializer(theta, theta_i); double lp = 0; - auto S(deserializer.read_cov_matrix, false>(lp, 2, 3U)); + auto S(deserializer.read_cov_matrix, false>( + lp, 2, 3U)); EXPECT_EQ(2, S.size()); for (int k = 0; k < 2; ++k) { EXPECT_EQ(3, S[k].rows()); @@ -1153,7 +1192,8 @@ TEST(deserializer_stdvec_matrix, cov_matrix_constrain_jacobian) { stan::io::deserializer deserializer(theta, theta_i); double lp = -3.1; - auto S(deserializer.read_cov_matrix, true>(lp, 2, 3U)); + auto S(deserializer.read_cov_matrix, true>(lp, 2, + 3U)); EXPECT_EQ(2, S.size()); for (int k = 0; k < 2; ++k) { @@ -1203,7 +1243,8 @@ TEST(deserializer_stdvec_matrix, cholesky_factor_cov) { theta[17] = 6; stan::io::deserializer deserializer(theta, theta_i); - auto S = deserializer.read_cholesky_factor_cov>(2, 3, 3); + auto S = deserializer.read_cholesky_factor_cov>( + 2, 3, 3); EXPECT_FLOAT_EQ(theta[0], S[0](0, 0)); EXPECT_FLOAT_EQ(theta[1], S[0](1, 0)); EXPECT_FLOAT_EQ(theta[7], S[0](1, 2)); @@ -1232,7 +1273,8 @@ TEST(deserializer_stdvec_matrix, cholesky_factor_cov_asymmetric) { theta[11] = 5; stan::io::deserializer deserializer(theta, theta_i); - auto S = deserializer.read_cholesky_factor_cov>(2, 3, 2); + auto S = deserializer.read_cholesky_factor_cov>( + 2, 3, 2); EXPECT_FLOAT_EQ(theta[0], S[0](0, 0)); EXPECT_FLOAT_EQ(theta[1], S[0](1, 0)); EXPECT_FLOAT_EQ(theta[2], S[0](2, 0)); @@ -1249,11 +1291,20 @@ TEST(deserializer_stdvec_matrix, cholesky_factor_cov_exception) { theta.push_back(static_cast(i)); theta[0] = -6.3; stan::io::deserializer deserializer(theta, theta_i); - EXPECT_THROW(deserializer.read_cholesky_factor_cov>(2, 2, 2), std::domain_error); - EXPECT_THROW(deserializer.read_cholesky_factor_cov>(2, 0, 0), std::domain_error); + EXPECT_THROW( + deserializer.read_cholesky_factor_cov>(2, 2, + 2), + std::domain_error); + EXPECT_THROW( + deserializer.read_cholesky_factor_cov>(2, 0, + 0), + std::domain_error); theta[0] = 1; - EXPECT_THROW(deserializer.read_cholesky_factor_cov>(2, 2, 3), std::domain_error); + EXPECT_THROW( + deserializer.read_cholesky_factor_cov>(2, 2, + 3), + std::domain_error); } TEST(deserializer_stdvec_matrix, cholesky_factor_cov_constrain) { std::vector theta_i; @@ -1262,7 +1313,9 @@ TEST(deserializer_stdvec_matrix, cholesky_factor_cov_constrain) { theta.push_back(-static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); double lp = 0; - auto L(deserializer.read_cholesky_factor_cov, false>(lp, 2U, 3U, 3U)); + auto L(deserializer + .read_cholesky_factor_cov, false>( + lp, 2U, 3U, 3U)); EXPECT_NO_THROW(stan::math::check_cholesky_factor( "test_cholesky_factor_constrain", "L", L[0])); EXPECT_EQ(2, L.size()); @@ -1271,7 +1324,6 @@ TEST(deserializer_stdvec_matrix, cholesky_factor_cov_constrain) { EXPECT_EQ(9, L[0].size()); } - TEST(deserializer_stdvec_matrix, cholesky_factor_cov_constrain_asymmetric) { std::vector theta_i; std::vector theta; @@ -1279,7 +1331,9 @@ TEST(deserializer_stdvec_matrix, cholesky_factor_cov_constrain_asymmetric) { theta.push_back(-static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); double lp = 0; - auto L(deserializer.read_cholesky_factor_cov, false>(lp, 2U, 3U, 2U)); + auto L(deserializer + .read_cholesky_factor_cov, false>( + lp, 2U, 3U, 2U)); EXPECT_NO_THROW(stan::math::check_cholesky_factor( "test_cholesky_factor_constrain", "L", L[0])); EXPECT_EQ(2, L.size()); @@ -1294,32 +1348,39 @@ TEST(deserializer_stdvec_matrix, cholesky_factor_cov_constrain_jacobian) { theta.push_back(-static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); double lp = 1.9; - auto L(deserializer.read_cholesky_factor_cov, true>(lp, 2U, 3U, 3U)); + auto L( + deserializer.read_cholesky_factor_cov, true>( + lp, 2U, 3U, 3U)); EXPECT_NO_THROW(stan::math::check_cholesky_factor( "test_cholesky_factor_constrain", "L", L[0])); EXPECT_EQ(2, L.size()); EXPECT_EQ(3, L[0].rows()); EXPECT_EQ(3, L[0].cols()); EXPECT_EQ(9, L[0].size()); - EXPECT_EQ(1.9 + log(L[0](0, 0)) + log(L[0](1, 1)) + log(L[0](2, 2)) + - + log(L[1](0, 0)) + log(L[1](1, 1)) + log(L[1](2, 2)), lp); + EXPECT_EQ(1.9 + log(L[0](0, 0)) + log(L[0](1, 1)) + log(L[0](2, 2)) + + +log(L[1](0, 0)) + log(L[1](1, 1)) + log(L[1](2, 2)), + lp); } -TEST(deserializer_stdvec_matrix, cholesky_factor_cov_constrain_jacobian_asymmetric) { +TEST(deserializer_stdvec_matrix, + cholesky_factor_cov_constrain_jacobian_asymmetric) { std::vector theta_i; std::vector theta; for (int i = 0; i < 24; ++i) theta.push_back(-static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); double lp = 1.9; - auto L(deserializer.read_cholesky_factor_cov, true>(lp, 2U, 4U, 3U)); + auto L( + deserializer.read_cholesky_factor_cov, true>( + lp, 2U, 4U, 3U)); EXPECT_NO_THROW(stan::math::check_cholesky_factor( "test_cholesky_factor_constrain", "L", L[0])); EXPECT_EQ(2, L.size()); EXPECT_EQ(4, L[0].rows()); EXPECT_EQ(3, L[0].cols()); EXPECT_EQ(12, L[0].size()); - EXPECT_EQ(1.9 + log(L[0](0, 0)) + log(L[0](1, 1)) + log(L[0](2, 2)) + - + log(L[1](0, 0)) + log(L[1](1, 1)) + log(L[1](2, 2)), lp); + EXPECT_EQ(1.9 + log(L[0](0, 0)) + log(L[0](1, 1)) + log(L[0](2, 2)) + + +log(L[1](0, 0)) + log(L[1](1, 1)) + log(L[1](2, 2)), + lp); } TEST(deserializer_stdvec_matrix, cholesky_factor_corr) { @@ -1350,7 +1411,8 @@ TEST(deserializer_stdvec_matrix, cholesky_factor_corr) { theta[17] = 1; stan::io::deserializer deserializer(theta, theta_i); - auto S = deserializer.read_cholesky_factor_corr>(2, 3); + auto S = deserializer.read_cholesky_factor_corr>( + 2, 3); EXPECT_FLOAT_EQ(theta[0], S[0](0, 0)); EXPECT_FLOAT_EQ(theta[1], S[0](1, 0)); EXPECT_FLOAT_EQ(theta[4], S[0](1, 1)); @@ -1388,7 +1450,10 @@ TEST(deserializer_stdvec_matrix, cholesky_factor_corr_exception) { theta[16] = 0; theta[17] = 1; stan::io::deserializer deserializer(theta, theta_i); - EXPECT_THROW(deserializer.read_cholesky_factor_corr>(2, 3), std::domain_error); + EXPECT_THROW( + deserializer.read_cholesky_factor_corr>(2, + 3), + std::domain_error); } TEST(deserializer_stdvec_matrix, cholesky_factor_corr_constrain) { std::vector theta_i; @@ -1397,7 +1462,9 @@ TEST(deserializer_stdvec_matrix, cholesky_factor_corr_constrain) { theta.push_back(-static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); double lp = 0; - auto L(deserializer.read_cholesky_factor_corr, false>(lp, 2U, 3U)); + auto L(deserializer + .read_cholesky_factor_corr, false>( + lp, 2U, 3U)); EXPECT_NO_THROW(stan::math::check_cholesky_factor_corr( "test_cholesky_factor_corr_constrain", "L", L[0])); EXPECT_EQ(3, L[0].rows()); diff --git a/src/test/unit/io/deserializer_test.cpp b/src/test/unit/io/deserializer_test.cpp index 3cea7ebcab5..40a078b6ed0 100644 --- a/src/test/unit/io/deserializer_test.cpp +++ b/src/test/unit/io/deserializer_test.cpp @@ -30,10 +30,11 @@ TEST(deserializer, zeroSizeVecs) { EXPECT_EQ(0, deserializer.read(0).size()); EXPECT_EQ(0, deserializer.read(0, 3).size()); EXPECT_EQ(0, deserializer.read(3, 0).size()); - EXPECT_EQ(0, deserializer.read>>(0, 0, 0, 0).size()); + EXPECT_EQ(0, deserializer + .read>>(0, 0, 0, 0) + .size()); } - TEST(deserializer, eos_exception) { std::vector theta; theta.push_back(1.0); @@ -68,7 +69,8 @@ TEST(deserializer_rowvector, read) { double x = deserializer.read(); EXPECT_FLOAT_EQ(static_cast(i), x); } - Eigen::Matrix y = deserializer.read(4); + Eigen::Matrix y + = deserializer.read(4); EXPECT_EQ(4, y.cols()); EXPECT_EQ(1, y.rows()); EXPECT_EQ(4, y.size()); @@ -125,10 +127,14 @@ TEST(deserializer_scalar, read_lb_constrain) { theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); double lp = 0.0; - EXPECT_FLOAT_EQ(1.0 + exp(-2.0), (deserializer.read_lb(1.0, lp))); - EXPECT_FLOAT_EQ(5.0 + exp(3.0), (deserializer.read_lb(5.0, lp))); - EXPECT_FLOAT_EQ(-2.0 + exp(-1.0), (deserializer.read_lb(-2.0, lp))); - EXPECT_FLOAT_EQ(15.0 + exp(0.0), (deserializer.read_lb(15.0, lp))); + EXPECT_FLOAT_EQ(1.0 + exp(-2.0), + (deserializer.read_lb(1.0, lp))); + EXPECT_FLOAT_EQ(5.0 + exp(3.0), + (deserializer.read_lb(5.0, lp))); + EXPECT_FLOAT_EQ(-2.0 + exp(-1.0), + (deserializer.read_lb(-2.0, lp))); + EXPECT_FLOAT_EQ(15.0 + exp(0.0), + (deserializer.read_lb(15.0, lp))); } TEST(deserializer_scalar, read_lb_constrain_jacobian) { std::vector theta_i; @@ -139,10 +145,14 @@ TEST(deserializer_scalar, read_lb_constrain_jacobian) { theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); double lp = -1.5; - EXPECT_FLOAT_EQ(1.0 + exp(-2.0), (deserializer.read_lb(1.0, lp))); - EXPECT_FLOAT_EQ(5.0 + exp(3.0), (deserializer.read_lb(5.0, lp))); - EXPECT_FLOAT_EQ(-2.0 + exp(-1.0), (deserializer.read_lb(-2.0, lp))); - EXPECT_FLOAT_EQ(15.0 + exp(0.0), (deserializer.read_lb(15.0, lp))); + EXPECT_FLOAT_EQ(1.0 + exp(-2.0), + (deserializer.read_lb(1.0, lp))); + EXPECT_FLOAT_EQ(5.0 + exp(3.0), + (deserializer.read_lb(5.0, lp))); + EXPECT_FLOAT_EQ(-2.0 + exp(-1.0), + (deserializer.read_lb(-2.0, lp))); + EXPECT_FLOAT_EQ(15.0 + exp(0.0), + (deserializer.read_lb(15.0, lp))); EXPECT_FLOAT_EQ(-1.5 - 2.0 + 3.0 - 1.0, lp); } @@ -179,10 +189,14 @@ TEST(deserializer_scalar, read_ub_constrain) { theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); double lp = 0; - EXPECT_FLOAT_EQ(1.0 - exp(-2.0), (deserializer.read_ub(1.0, lp))); - EXPECT_FLOAT_EQ(5.0 - exp(3.0), (deserializer.read_ub(5.0, lp))); - EXPECT_FLOAT_EQ(-2.0 - exp(-1.0), (deserializer.read_ub(-2.0, lp))); - EXPECT_FLOAT_EQ(15.0 - exp(0.0), (deserializer.read_ub(15.0, lp))); + EXPECT_FLOAT_EQ(1.0 - exp(-2.0), + (deserializer.read_ub(1.0, lp))); + EXPECT_FLOAT_EQ(5.0 - exp(3.0), + (deserializer.read_ub(5.0, lp))); + EXPECT_FLOAT_EQ(-2.0 - exp(-1.0), + (deserializer.read_ub(-2.0, lp))); + EXPECT_FLOAT_EQ(15.0 - exp(0.0), + (deserializer.read_ub(15.0, lp))); } TEST(deserializer_scalar, read_ub_constrain_jacobian) { std::vector theta_i; @@ -193,16 +207,19 @@ TEST(deserializer_scalar, read_ub_constrain_jacobian) { theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); double lp = -12.9; - EXPECT_FLOAT_EQ(1.0 - exp(-2.0), (deserializer.read_ub(1.0, lp))); - EXPECT_FLOAT_EQ(5.0 - exp(3.0), (deserializer.read_ub(5.0, lp))); - EXPECT_FLOAT_EQ(-2.0 - exp(-1.0), (deserializer.read_ub(-2.0, lp))); - EXPECT_FLOAT_EQ(15.0 - exp(0.0), (deserializer.read_ub(15.0, lp))); + EXPECT_FLOAT_EQ(1.0 - exp(-2.0), + (deserializer.read_ub(1.0, lp))); + EXPECT_FLOAT_EQ(5.0 - exp(3.0), + (deserializer.read_ub(5.0, lp))); + EXPECT_FLOAT_EQ(-2.0 - exp(-1.0), + (deserializer.read_ub(-2.0, lp))); + EXPECT_FLOAT_EQ(15.0 - exp(0.0), + (deserializer.read_ub(15.0, lp))); EXPECT_FLOAT_EQ(-12.9 - 2.0 + 3.0 - 1.0, lp); } // lub - TEST(deserializer_scalar, read_lub) { std::vector theta_i; std::vector theta; @@ -239,7 +256,8 @@ TEST(deserializer_scalar, read_lub_constrain) { theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); double lp = 0; - EXPECT_FLOAT_EQ(inv_logit_m2, (deserializer.read_lub(0.0, 1.0, lp))); + EXPECT_FLOAT_EQ(inv_logit_m2, + (deserializer.read_lub(0.0, 1.0, lp))); EXPECT_FLOAT_EQ(3.0 + 2.0 * inv_logit_3, (deserializer.read_lub(3.0, 5.0, lp))); EXPECT_FLOAT_EQ(-3.0 + 5.0 * inv_logit_m1, @@ -295,8 +313,9 @@ TEST(deserializer_scalar, offset_multiplier_exception) { stan::io::deserializer deserializer(theta, theta_i); double lp = 0; EXPECT_NO_THROW(deserializer.read_offset_multiplier(-2.0, -2.0)); - EXPECT_THROW((deserializer.read_offset_multiplier(-2.0, -2.0, lp)), - std::domain_error); + EXPECT_THROW( + (deserializer.read_offset_multiplier(-2.0, -2.0, lp)), + std::domain_error); } TEST(deserializer_scalar, offset_multiplier_constrain) { @@ -308,13 +327,16 @@ TEST(deserializer_scalar, offset_multiplier_constrain) { theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); double lp = 0; - EXPECT_FLOAT_EQ(-2.0, (deserializer.read_offset_multiplier(0.0, 1.0, lp))); - EXPECT_FLOAT_EQ(3.0 + 5.0 * 3.0, - (deserializer.read_offset_multiplier(3.0, 5.0, lp))); - EXPECT_FLOAT_EQ(-3.0 + 2.0 * -1.0, - (deserializer.read_offset_multiplier(-3.0, 2.0, lp))); - EXPECT_FLOAT_EQ(-15.0, - (deserializer.read_offset_multiplier(-15.0, 15.0, lp))); + EXPECT_FLOAT_EQ( + -2.0, (deserializer.read_offset_multiplier(0.0, 1.0, lp))); + EXPECT_FLOAT_EQ( + 3.0 + 5.0 * 3.0, + (deserializer.read_offset_multiplier(3.0, 5.0, lp))); + EXPECT_FLOAT_EQ( + -3.0 + 2.0 * -1.0, + (deserializer.read_offset_multiplier(-3.0, 2.0, lp))); + EXPECT_FLOAT_EQ(-15.0, (deserializer.read_offset_multiplier( + -15.0, 15.0, lp))); } TEST(deserializer_scalar, offset_multiplier_constrain_jacobian) { std::vector theta_i; @@ -325,14 +347,16 @@ TEST(deserializer_scalar, offset_multiplier_constrain_jacobian) { theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); double lp = -7.2; - EXPECT_FLOAT_EQ(-2.0, - (deserializer.read_offset_multiplier(0.0, 1.0, lp))); - EXPECT_FLOAT_EQ(3.0 + 5.0 * 3.0, - (deserializer.read_offset_multiplier(3.0, 5.0, lp))); - EXPECT_FLOAT_EQ(-3.0 + 2.0 * -1.0, - (deserializer.read_offset_multiplier(-3.0, 2.0, lp))); - EXPECT_FLOAT_EQ(-15.0, - (deserializer.read_offset_multiplier(-15.0, 15.0, lp))); + EXPECT_FLOAT_EQ( + -2.0, (deserializer.read_offset_multiplier(0.0, 1.0, lp))); + EXPECT_FLOAT_EQ( + 3.0 + 5.0 * 3.0, + (deserializer.read_offset_multiplier(3.0, 5.0, lp))); + EXPECT_FLOAT_EQ( + -3.0 + 2.0 * -1.0, + (deserializer.read_offset_multiplier(-3.0, 2.0, lp))); + EXPECT_FLOAT_EQ(-15.0, (deserializer.read_offset_multiplier( + -15.0, 15.0, lp))); double expected_lp = -7.2 + log(1.0) + log(5.0) + log(2.0) + log(15.0); EXPECT_FLOAT_EQ(expected_lp, lp); } @@ -455,7 +479,6 @@ TEST(deserializer_scalar, corr_constrain_jacobian) { // var matrix - TEST(deserializer_varmat, var_vector) { using stan::math::var; using stan::math::var_value; diff --git a/src/test/unit/io/deserializer_varmat_test.cpp b/src/test/unit/io/deserializer_varmat_test.cpp index 71798118491..2d9cc200ae7 100644 --- a/src/test/unit/io/deserializer_varmat_test.cpp +++ b/src/test/unit/io/deserializer_varmat_test.cpp @@ -53,8 +53,10 @@ TEST(deserializer_var_vector, unit_vector_exception) { theta[4] = sqrt(1.0); theta[5] = sqrt(1.0); EXPECT_NO_THROW(deserializer.read_unit_vector(4)); - EXPECT_THROW(deserializer.read_unit_vector(2), std::domain_error); - EXPECT_THROW(deserializer.read_unit_vector(0), std::invalid_argument); + EXPECT_THROW(deserializer.read_unit_vector(2), + std::domain_error); + EXPECT_THROW(deserializer.read_unit_vector(0), + std::invalid_argument); } TEST(deserializer_var_vector, simplex) { @@ -82,7 +84,8 @@ TEST(deserializer_var_vector, simplex_exception) { theta[5] = 1.0; EXPECT_NO_THROW(deserializer.read_simplex(4)); EXPECT_THROW(deserializer.read_simplex(2), std::domain_error); - EXPECT_THROW(deserializer.read_simplex(0), std::invalid_argument); + EXPECT_THROW(deserializer.read_simplex(0), + std::invalid_argument); } TEST(deserializer_var_vector, ordered) { @@ -91,7 +94,8 @@ TEST(deserializer_var_vector, ordered) { for (int i = 0; i < 100.0; ++i) theta.push_back(static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); - EXPECT_FLOAT_EQ(0.0, deserializer.read().val()); // throw away theta[0] + EXPECT_FLOAT_EQ( + 0.0, deserializer.read().val()); // throw away theta[0] var_vector_t y = deserializer.read_ordered(5); EXPECT_EQ(5, y.size()); EXPECT_FLOAT_EQ(1.0, y.val()[0]); @@ -105,7 +109,8 @@ TEST(deserializer_var_vector, ordered_exception) { for (int i = 0; i < 100.0; ++i) theta.push_back(static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); - EXPECT_FLOAT_EQ(0.0, deserializer.read().val()); // throw away theta[0] + EXPECT_FLOAT_EQ( + 0.0, deserializer.read().val()); // throw away theta[0] var_vector_t y = deserializer.read_ordered(5); EXPECT_EQ(5, y.size()); EXPECT_FLOAT_EQ(1.0, y.val()[0]); @@ -160,7 +165,8 @@ TEST(deserializer_var_vector, positive_ordered) { for (int i = 0; i < 100.0; ++i) theta.push_back(static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); - EXPECT_FLOAT_EQ(0.0, deserializer.read().val()); // throw away theta[0] + EXPECT_FLOAT_EQ( + 0.0, deserializer.read().val()); // throw away theta[0] var_vector_t y = deserializer.read_positive_ordered(5); EXPECT_EQ(5, y.size()); EXPECT_FLOAT_EQ(1.0, y.val()[0]); @@ -239,7 +245,6 @@ TEST(deserializer_var_matrix, read) { EXPECT_FLOAT_EQ(13.0, a.val()); } - TEST(deserializer_var_matrix, matrix_lb) { std::vector theta_i; std::vector theta; @@ -277,8 +282,7 @@ TEST(deserializer_var_matrix, matrix_lb_constrain) { } stan::math::var lb = -1.5; stan::math::var lp = 0; - var_matrix_t y - = deserializer.read_lb(lb, lp, 3, 2); + var_matrix_t y = deserializer.read_lb(lb, lp, 3, 2); EXPECT_EQ(3, y.rows()); EXPECT_EQ(2, y.cols()); EXPECT_FLOAT_EQ(stan::math::lb_constrain(7.0, lb).val(), y.val()(0, 0)); @@ -304,8 +308,7 @@ TEST(deserializer_var_matrix, matrix_lb_constrain_lp) { } stan::math::var lb = -1.5; stan::math::var lp = -5.0; - var_matrix_t y - = deserializer.read_lb(lb, lp, 3, 2); + var_matrix_t y = deserializer.read_lb(lb, lp, 3, 2); EXPECT_EQ(3, y.rows()); EXPECT_EQ(2, y.cols()); EXPECT_FLOAT_EQ(stan::math::lb_constrain(7.0, lb, lp).val(), y.val()(0, 0)); @@ -330,8 +333,7 @@ TEST(deserializer_var_matrix, matrix_ub) { EXPECT_FLOAT_EQ(static_cast(i), x.val()); } stan::math::var ub = 12.5; - var_matrix_t y - = deserializer.read_ub(ub, 3, 2); + var_matrix_t y = deserializer.read_ub(ub, 3, 2); EXPECT_EQ(3, y.rows()); EXPECT_EQ(2, y.cols()); EXPECT_FLOAT_EQ(7.0, y.val()(0, 0)); @@ -357,8 +359,7 @@ TEST(deserializer_var_matrix, matrix_ub_constrain) { } stan::math::var ub = 14.1; stan::math::var lp = 0; - var_matrix_t y - = deserializer.read_ub(ub, lp, 3, 2); + var_matrix_t y = deserializer.read_ub(ub, lp, 3, 2); EXPECT_EQ(3, y.rows()); EXPECT_EQ(2, y.cols()); EXPECT_FLOAT_EQ(stan::math::ub_constrain(7.0, ub).val(), y.val()(0, 0)); @@ -384,8 +385,7 @@ TEST(deserializer_var_matrix, matrix_ub_constrain_lp) { } stan::math::var ub = 12.1; stan::math::var lp = -5.0; - var_matrix_t y - = deserializer.read_ub(ub, lp, 3, 2); + var_matrix_t y = deserializer.read_ub(ub, lp, 3, 2); EXPECT_EQ(3, y.rows()); EXPECT_EQ(2, y.cols()); EXPECT_FLOAT_EQ(stan::math::ub_constrain(7.0, ub, lp).val(), y.val()(0, 0)); @@ -438,8 +438,7 @@ TEST(deserializer_var_matrix, matrix_lub_constrain) { stan::math::var lb = 3.5; stan::math::var ub = 14.1; stan::math::var lp = 0; - var_matrix_t y - = deserializer.read_lub(lb, ub, lp, 3, 2); + var_matrix_t y = deserializer.read_lub(lb, ub, lp, 3, 2); EXPECT_EQ(3, y.rows()); EXPECT_EQ(2, y.cols()); EXPECT_FLOAT_EQ(stan::math::lub_constrain(7.0, lb, ub).val(), y.val()(0, 0)); @@ -466,16 +465,21 @@ TEST(deserializer_var_matrix, matrix_lub_constrain_lp) { stan::math::var lb = 4.1; stan::math::var ub = 12.1; stan::math::var lp = -5.0; - var_matrix_t y - = deserializer.read_lub(lb, ub, lp, 3, 2); + var_matrix_t y = deserializer.read_lub(lb, ub, lp, 3, 2); EXPECT_EQ(3, y.rows()); EXPECT_EQ(2, y.cols()); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(7.0, lb, ub, lp).val(), y.val()(0, 0)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(8.0, lb, ub, lp).val(), y.val()(1, 0)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(9.0, lb, ub, lp).val(), y.val()(2, 0)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(10.0, lb, ub, lp).val(), y.val()(0, 1)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(11.0, lb, ub, lp).val(), y.val()(1, 1)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(12.0, lb, ub, lp).val(), y.val()(2, 1)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(7.0, lb, ub, lp).val(), + y.val()(0, 0)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(8.0, lb, ub, lp).val(), + y.val()(1, 0)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(9.0, lb, ub, lp).val(), + y.val()(2, 0)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(10.0, lb, ub, lp).val(), + y.val()(0, 1)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(11.0, lb, ub, lp).val(), + y.val()(1, 1)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(12.0, lb, ub, lp).val(), + y.val()(2, 1)); stan::math::var a = deserializer.read(); EXPECT_FLOAT_EQ(13.0, a.val()); @@ -603,8 +607,10 @@ TEST(deserializer_var_matrix, cov_matrix_exception) { theta[2] = 0.6; theta[3] = 1.9; stan::io::deserializer deserializer(theta, theta_i); - EXPECT_THROW(deserializer.read_cov_matrix(2), std::domain_error); - EXPECT_THROW(deserializer.read_cov_matrix(0), std::invalid_argument); + EXPECT_THROW(deserializer.read_cov_matrix(2), + std::domain_error); + EXPECT_THROW(deserializer.read_cov_matrix(0), + std::invalid_argument); } TEST(deserializer_var_matrix, cov_matrix_constrain) { std::vector theta_i; @@ -618,8 +624,7 @@ TEST(deserializer_var_matrix, cov_matrix_constrain) { theta.push_back(1.0); stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp = 0; - var_matrix_t S( - deserializer.read_cov_matrix(lp, 3U)); + var_matrix_t S(deserializer.read_cov_matrix(lp, 3U)); EXPECT_EQ(3, S.rows()); EXPECT_EQ(3, S.cols()); EXPECT_EQ(9, S.size()); @@ -683,8 +688,7 @@ TEST(deserializer_var_matrix, cholesky_factor_cov) { theta[7] = 0; theta[8] = 6; stan::io::deserializer deserializer(theta, theta_i); - var_matrix_t S - = deserializer.read_cholesky_factor_cov(3, 3); + var_matrix_t S = deserializer.read_cholesky_factor_cov(3, 3); EXPECT_FLOAT_EQ(theta[0].val(), S.val()(0, 0)); EXPECT_FLOAT_EQ(theta[1].val(), S.val()(1, 0)); EXPECT_FLOAT_EQ(theta[7].val(), S.val()(1, 2)); @@ -705,8 +709,7 @@ TEST(deserializer_var_matrix, cholesky_factor_cov_asymmetric) { theta[5] = 5; stan::io::deserializer deserializer(theta, theta_i); - var_matrix_t S - = deserializer.read_cholesky_factor_cov(3, 2); + var_matrix_t S = deserializer.read_cholesky_factor_cov(3, 2); EXPECT_FLOAT_EQ(theta[0].val(), S.val()(0, 0)); EXPECT_FLOAT_EQ(theta[1].val(), S.val()(1, 0)); EXPECT_FLOAT_EQ(theta[2].val(), S.val()(2, 0)); @@ -723,11 +726,14 @@ TEST(deserializer_var_matrix, cholesky_factor_cov_exception) { theta.push_back(static_cast(i)); theta[0] = -6.3; stan::io::deserializer deserializer(theta, theta_i); - EXPECT_THROW(deserializer.read_cholesky_factor_cov(2, 2), std::domain_error); - EXPECT_THROW(deserializer.read_cholesky_factor_cov(0, 0), std::domain_error); + EXPECT_THROW(deserializer.read_cholesky_factor_cov(2, 2), + std::domain_error); + EXPECT_THROW(deserializer.read_cholesky_factor_cov(0, 0), + std::domain_error); theta[0] = 1; - EXPECT_THROW(deserializer.read_cholesky_factor_cov(2, 3), std::domain_error); + EXPECT_THROW(deserializer.read_cholesky_factor_cov(2, 3), + std::domain_error); } TEST(deserializer_var_matrix, cholesky_factor_cov_constrain) { std::vector theta_i; @@ -746,7 +752,6 @@ TEST(deserializer_var_matrix, cholesky_factor_cov_constrain) { EXPECT_EQ(2U, deserializer.available()); } - TEST(deserializer_var_matrix, cholesky_factor_cov_constrain_asymmetric) { std::vector theta_i; std::vector theta; @@ -778,9 +783,11 @@ TEST(deserializer_var_matrix, cholesky_factor_cov_constrain_jacobian) { EXPECT_EQ(3, L.cols()); EXPECT_EQ(9, L.size()); EXPECT_EQ(2U, deserializer.available()); - EXPECT_EQ(1.9 + log(L.val()(0, 0)) + log(L.val()(1, 1)) + log(L.val()(2, 2)), lp.val()); + EXPECT_EQ(1.9 + log(L.val()(0, 0)) + log(L.val()(1, 1)) + log(L.val()(2, 2)), + lp.val()); } -TEST(deserializer_var_matrix, cholesky_factor_cov_constrain_jacobian_asymmetric) { +TEST(deserializer_var_matrix, + cholesky_factor_cov_constrain_jacobian_asymmetric) { std::vector theta_i; std::vector theta; for (int i = 0; i < 12; ++i) @@ -795,7 +802,8 @@ TEST(deserializer_var_matrix, cholesky_factor_cov_constrain_jacobian_asymmetric) EXPECT_EQ(3, L.cols()); EXPECT_EQ(12, L.size()); EXPECT_EQ(3U, deserializer.available()); - EXPECT_EQ(1.9 + log(L.val()(0, 0)) + log(L.val()(1, 1)) + log(L.val()(2, 2)), lp.val()); + EXPECT_EQ(1.9 + log(L.val()(0, 0)) + log(L.val()(1, 1)) + log(L.val()(2, 2)), + lp.val()); } TEST(deserializer_var_matrix, cholesky_factor_corr) { @@ -814,8 +822,7 @@ TEST(deserializer_var_matrix, cholesky_factor_corr) { theta[7] = 0; theta[8] = 1; stan::io::deserializer deserializer(theta, theta_i); - var_matrix_t S - = deserializer.read_cholesky_factor_corr(3); + var_matrix_t S = deserializer.read_cholesky_factor_corr(3); EXPECT_FLOAT_EQ(theta[0].val(), S.val()(0, 0)); EXPECT_FLOAT_EQ(theta[1].val(), S.val()(1, 0)); EXPECT_FLOAT_EQ(theta[4].val(), S.val()(1, 1)); @@ -842,7 +849,8 @@ TEST(deserializer_var_matrix, cholesky_factor_corr_exception) { theta[7] = 0; theta[8] = 1; stan::io::deserializer deserializer(theta, theta_i); - EXPECT_THROW(deserializer.read_cholesky_factor_corr(3), std::domain_error); + EXPECT_THROW(deserializer.read_cholesky_factor_corr(3), + std::domain_error); } TEST(deserializer_var_matrix, cholesky_factor_corr_constrain) { std::vector theta_i; From cb3028b9dc61533b630bd04490710ff6c0b6814f Mon Sep 17 00:00:00 2001 From: Steve Bronder Date: Tue, 2 Mar 2021 17:53:06 -0500 Subject: [PATCH 10/29] adds vec and matrix tests for offset multiplier --- lib/stan_math | 2 +- .../unit/io/deserializer_stdvector_test.cpp | 204 ++-- src/test/unit/io/deserializer_test.cpp | 1013 +++++++++++++++-- src/test/unit/io/deserializer_varmat_test.cpp | 103 ++ 4 files changed, 1166 insertions(+), 156 deletions(-) diff --git a/lib/stan_math b/lib/stan_math index 796c0f0966e..9b5b156eddc 160000 --- a/lib/stan_math +++ b/lib/stan_math @@ -1 +1 @@ -Subproject commit 796c0f0966e03dfc92cc7bb68ca670770e3fe528 +Subproject commit 9b5b156eddc6ec086b540aa83608e3175aa14151 diff --git a/src/test/unit/io/deserializer_stdvector_test.cpp b/src/test/unit/io/deserializer_stdvector_test.cpp index c30dcd7572a..7b9c62e1994 100644 --- a/src/test/unit/io/deserializer_stdvector_test.cpp +++ b/src/test/unit/io/deserializer_stdvector_test.cpp @@ -712,6 +712,73 @@ TEST(deserializer_stdvec_vector, positive_ordered_constrain_jacobian) { EXPECT_FLOAT_EQ(expected_lp, lp); } + +TEST(deserializer_stdvec_vector, offset_multiplier) { + std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + auto phi(deserializer.read_offset_multiplier>(0, 1, 2, 4)); + for (int i = 0; i < 2; ++i) { + EXPECT_FLOAT_EQ(theta[0], phi[i][0]); + EXPECT_FLOAT_EQ(theta[1], phi[i][1]); + EXPECT_FLOAT_EQ(theta[2], phi[i][2]); + EXPECT_FLOAT_EQ(theta[3], phi[i][3]); + } +} + +TEST(deserializer_stdvec_vector, offset_multiplier_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0; + auto phi(deserializer.read_offset_multiplier, false>(0, 1, lp, 2, 4)); + for (int i = 0; i < 2; ++i) { + EXPECT_FLOAT_EQ(theta[0], phi[i][0]); + EXPECT_FLOAT_EQ(theta[1], phi[i][1]); + EXPECT_FLOAT_EQ(theta[2], phi[i][2]); + EXPECT_FLOAT_EQ(theta[3], phi[i][3]); + } +} + +TEST(deserializer_stdvec_vector, offset_multiplier_constrain_lp) { + std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0; + auto phi(deserializer.read_offset_multiplier, true>(0, 2, lp, 2, 4)); + for (int i = 0; i < 2; ++i) { + EXPECT_FLOAT_EQ(theta[0] * 2, phi[i][0]); + EXPECT_FLOAT_EQ(theta[1] * 2, phi[i][1]); + EXPECT_FLOAT_EQ(theta[2] * 2, phi[i][2]); + EXPECT_FLOAT_EQ(theta[3] * 2, phi[i][3]); + } + EXPECT_FLOAT_EQ(lp, std::log(2) * 8); +} + // matrix TEST(deserializer_stdvec_matrix, read) { @@ -1471,103 +1538,74 @@ TEST(deserializer_stdvec_matrix, cholesky_factor_corr_constrain) { EXPECT_EQ(3, L[0].cols()); EXPECT_EQ(9, L[0].size()); } -/* -// var matrix -TEST(deserializer_varmat, var_vector) { - using stan::math::var; - using stan::math::var_value; - using var_vec = var_value; - std::vector theta{0, 1, 2, 3, 4}; - std::vector theta_i; - stan::io::deserializer deserializer(theta, theta_i); - auto vec_x = deserializer.read(5); - EXPECT_TRUE((stan::is_var_vector::value)); - for (int i = 0; i < 5; ++i) { - EXPECT_EQ(vec_x.val()(i), i); - } - auto vec_x_empty = deserializer.read(0); - stan::math::recover_memory(); -} -TEST(deserializer_varmat, var_vector_double) { - using stan::math::var; - using stan::math::var_value; - using var_vec = var_value; - std::vector theta{0, 1, 2, 3, 4}; +TEST(deserializer_stdvec_matrix, offset_multiplier) { std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); - auto vec_x = deserializer.read(5); - EXPECT_TRUE( - (stan::is_eigen_vector::value - && std::is_arithmetic>::value)); - for (int i = 0; i < 5; ++i) { - EXPECT_EQ(vec_x.val()(i), i); - } -} - -TEST(deserializer_varmat, var_row_vector) { - using stan::math::var; - using stan::math::var_value; - using var_row_vec = var_value; - std::vector theta{0, 1, 2, 3, 4}; - std::vector theta_i; - stan::io::deserializer deserializer(theta, theta_i); - auto vec_x = deserializer.read(5); - EXPECT_TRUE((stan::is_var_row_vector::value)); - for (int i = 0; i < 5; ++i) { - EXPECT_EQ(vec_x.val()(i), i); + auto phi( + deserializer.read_offset_multiplier>(0, 1, 2, 2, 2)); + for (int i = 0; i < 2; ++i) { + EXPECT_FLOAT_EQ(theta[0], phi[i](0, 0)); + EXPECT_FLOAT_EQ(theta[1], phi[i](1, 0)); + EXPECT_FLOAT_EQ(theta[2], phi[i](0, 1)); + EXPECT_FLOAT_EQ(theta[3], phi[i](1, 1)); } - auto vec_x_empty = deserializer.read(0); } -TEST(deserializer_varmat, var_row_vector_double) { - using stan::math::var; - using stan::math::var_value; - using var_row_vec = var_value; - std::vector theta{0, 1, 2, 3, 4}; +TEST(deserializer_stdvec_matrix, offset_multiplier_constrain) { std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); - auto vec_x = deserializer.read(5); - EXPECT_TRUE( - (stan::is_eigen_row_vector::value - && std::is_arithmetic>::value)); - for (int i = 0; i < 5; ++i) { - EXPECT_EQ(vec_x.val()(i), i); - } - auto vec_x_empty = deserializer.read(0); -} - -TEST(deserializer_varmat, var_matrix) { - using stan::math::var; - using stan::math::var_value; - using var_matrix = var_value; - std::vector theta{0, 1, 2, 3, 4, 5, 6, 7, 8}; - std::vector theta_i; - stan::io::deserializer deserializer(theta, theta_i); - auto mat_x = deserializer.read(3, 3); - EXPECT_TRUE((stan::is_var_matrix::value)); - for (int i = 0; i < 9; ++i) { - EXPECT_EQ(mat_x.val()(i), i); + double lp = 0; + auto phi( + deserializer.read_offset_multiplier, false>(0, 1, lp, 2, 2, 2)); + for (int i = 0; i < 2; ++i) { + EXPECT_FLOAT_EQ(theta[0], phi[i](0, 0)); + EXPECT_FLOAT_EQ(theta[1], phi[i](1, 0)); + EXPECT_FLOAT_EQ(theta[2], phi[i](0, 1)); + EXPECT_FLOAT_EQ(theta[3], phi[i](1, 1)); } - auto mat_x_empty = deserializer.read(0, 0); } -TEST(deserializer_varmat, var_matrix_double) { - using stan::math::var; - using stan::math::var_value; - using var_matrix = var_value; - std::vector theta{0, 1, 2, 3, 4, 5, 6, 7, 8}; +TEST(deserializer_stdvec_matrix, offset_multiplier_constrain_lp) { std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); - auto mat_x = deserializer.read(3, 3); - EXPECT_TRUE( - (stan::is_eigen_dense_dynamic::value - && std::is_arithmetic>::value)); - for (int i = 0; i < 9; ++i) { - EXPECT_EQ(mat_x.val()(i), i); + double lp = 0; + auto phi( + deserializer.read_offset_multiplier, true>(0, 2, lp, 2, 2, 2)); + for (int i = 0; i < 2; ++i) { + EXPECT_FLOAT_EQ(theta[0] * 2, phi[i](0, 0)); + EXPECT_FLOAT_EQ(theta[1] * 2, phi[i](1, 0)); + EXPECT_FLOAT_EQ(theta[2] * 2, phi[i](0, 1)); + EXPECT_FLOAT_EQ(theta[3] * 2, phi[i](1, 1)); } - auto mat_x_empty = deserializer.read(0, 0); + EXPECT_FLOAT_EQ(lp, std::log(2) * 8); } -*/ diff --git a/src/test/unit/io/deserializer_test.cpp b/src/test/unit/io/deserializer_test.cpp index 40a078b6ed0..0d8261c3076 100644 --- a/src/test/unit/io/deserializer_test.cpp +++ b/src/test/unit/io/deserializer_test.cpp @@ -477,100 +477,969 @@ TEST(deserializer_scalar, corr_constrain_jacobian) { EXPECT_FLOAT_EQ(expected_lp, lp); } -// var matrix - -TEST(deserializer_varmat, var_vector) { - using stan::math::var; - using stan::math::var_value; - using var_vec = var_value; - std::vector theta{0, 1, 2, 3, 4}; - std::vector theta_i; - stan::io::deserializer deserializer(theta, theta_i); - auto vec_x = deserializer.read(5); - EXPECT_TRUE((stan::is_var_vector::value)); - for (int i = 0; i < 5; ++i) { - EXPECT_EQ(vec_x.val()(i), i); + +// vector + + +TEST(deserializer_vector, read) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100U; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (size_t i = 0; i < 7U; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); } - auto vec_x_empty = deserializer.read(0); - stan::math::recover_memory(); + Eigen::Matrix y = deserializer.read(4); + EXPECT_EQ(4, y.rows()); + EXPECT_EQ(1, y.cols()); + EXPECT_EQ(4, y.size()); + EXPECT_FLOAT_EQ(7.0, y[0]); + EXPECT_FLOAT_EQ(8.0, y[1]); + EXPECT_FLOAT_EQ(9.0, y[2]); + EXPECT_FLOAT_EQ(10.0, y[3]); + + double z = deserializer.read(); + EXPECT_FLOAT_EQ(11.0, z); +} + +TEST(deserializer_vector, unit_vector) { + std::vector theta_i(0); + std::vector theta(4, sqrt(0.25)); + stan::io::deserializer deserializer(theta, theta_i); + Eigen::VectorXd y = deserializer.read_unit_vector(4); + EXPECT_EQ(4, y.size()); + EXPECT_FLOAT_EQ(sqrt(0.25), y[0]); + EXPECT_FLOAT_EQ(sqrt(0.25), y[1]); + EXPECT_FLOAT_EQ(sqrt(0.25), y[2]); + EXPECT_FLOAT_EQ(sqrt(0.25), y[3]); +} + +TEST(deserializer_vector, unit_vector_exception) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + theta[0] = 0.00; + theta[1] = -sqrt(0.29); + theta[2] = sqrt(0.70); + theta[3] = -sqrt(0.01); + theta[4] = sqrt(1.0); + theta[5] = sqrt(1.0); + EXPECT_NO_THROW(deserializer.read_unit_vector(4)); + EXPECT_THROW(deserializer.read_unit_vector(2), std::domain_error); + EXPECT_THROW(deserializer.read_unit_vector(0), std::invalid_argument); +} + +TEST(deserializer_vector, simplex) { + std::vector theta_i(0); + std::vector theta(4, 0.25); + stan::io::deserializer deserializer(theta, theta_i); + Eigen::Matrix y = deserializer.read_simplex(4); + EXPECT_EQ(4, y.size()); + EXPECT_FLOAT_EQ(0.25, y[0]); + EXPECT_FLOAT_EQ(0.25, y[1]); + EXPECT_FLOAT_EQ(0.25, y[2]); + EXPECT_FLOAT_EQ(0.25, y[3]); +} +TEST(deserializer_vector, simplex_exception) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + theta[0] = 0.00; + theta[1] = 0.29; + theta[2] = 0.70; + theta[3] = 0.01; + theta[4] = 1.0; + theta[5] = 1.0; + EXPECT_NO_THROW(deserializer.read_simplex(4)); + EXPECT_THROW(deserializer.read_simplex(2), std::domain_error); + EXPECT_THROW(deserializer.read_simplex(0), std::invalid_argument); +} + +TEST(deserializer_vector, ordered) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_FLOAT_EQ(0.0, deserializer.read()); // throw away theta[0] + Eigen::Matrix y = deserializer.read_ordered(5); + EXPECT_EQ(5, y.size()); + EXPECT_FLOAT_EQ(1.0, y[0]); + EXPECT_FLOAT_EQ(2.0, y[1]); + EXPECT_FLOAT_EQ(5.0, y[4]); + EXPECT_FLOAT_EQ(6.0, deserializer.read()); +} +TEST(deserializer_vector, ordered_exception) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_FLOAT_EQ(0.0, deserializer.read()); // throw away theta[0] + Eigen::Matrix y = deserializer.read_ordered(5); + EXPECT_EQ(5, y.size()); + EXPECT_FLOAT_EQ(1.0, y[0]); + EXPECT_FLOAT_EQ(2.0, y[1]); + EXPECT_FLOAT_EQ(5.0, y[4]); + EXPECT_FLOAT_EQ(6.0, deserializer.read()); +} +TEST(deserializer_vector, ordered_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + double v0 = 3.0; + double v1 = v0 + exp(-1.0); + double v2 = v1 + exp(-2.0); + double v3 = v2 + exp(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0; + Eigen::Matrix phi(deserializer.read_ordered(lp, 4)); + EXPECT_FLOAT_EQ(v0, phi[0]); + EXPECT_FLOAT_EQ(v1, phi[1]); + EXPECT_FLOAT_EQ(v2, phi[2]); + EXPECT_FLOAT_EQ(v3, phi[3]); +} +TEST(deserializer_vector, ordered_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + double v0 = 3.0; + double v1 = v0 + exp(-1.0); + double v2 = v1 + exp(-2.0); + double v3 = v2 + exp(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = -101.1; + double expected_lp = lp - 1.0 - 2.0 + 0.0; + Eigen::Matrix phi(deserializer.read_ordered(lp, 4)); + EXPECT_FLOAT_EQ(v0, phi[0]); + EXPECT_FLOAT_EQ(v1, phi[1]); + EXPECT_FLOAT_EQ(v2, phi[2]); + EXPECT_FLOAT_EQ(v3, phi[3]); + EXPECT_FLOAT_EQ(expected_lp, lp); +} + +TEST(deserializer_vector, positive_ordered) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_FLOAT_EQ(0.0, deserializer.read()); // throw away theta[0] + Eigen::Matrix y = deserializer.read_positive_ordered(5); + EXPECT_EQ(5, y.size()); + EXPECT_FLOAT_EQ(1.0, y[0]); + EXPECT_FLOAT_EQ(2.0, y[1]); + EXPECT_FLOAT_EQ(5.0, y[4]); + EXPECT_FLOAT_EQ(6.0, deserializer.read()); } -TEST(deserializer_varmat, var_vector_double) { - using stan::math::var; - using stan::math::var_value; - using var_vec = var_value; - std::vector theta{0, 1, 2, 3, 4}; +TEST(deserializer_vector, positive_ordered_constrain) { std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + double v0 = exp(3.0); + double v1 = v0 + exp(-1.0); + double v2 = v1 + exp(-2.0); + double v3 = v2 + exp(0.0); stan::io::deserializer deserializer(theta, theta_i); - auto vec_x = deserializer.read(5); - EXPECT_TRUE( - (stan::is_eigen_vector::value - && std::is_arithmetic>::value)); - for (int i = 0; i < 5; ++i) { - EXPECT_EQ(vec_x.val()(i), i); + double lp = 0; + Eigen::Matrix phi( + deserializer.read_positive_ordered(lp, 4)); + EXPECT_FLOAT_EQ(v0, phi[0]); + EXPECT_FLOAT_EQ(v1, phi[1]); + EXPECT_FLOAT_EQ(v2, phi[2]); + EXPECT_FLOAT_EQ(v3, phi[3]); +} + +TEST(deserializer_vector, positive_ordered_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + double v0 = exp(3.0); + double v1 = v0 + exp(-1.0); + double v2 = v1 + exp(-2.0); + double v3 = v2 + exp(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = -101.1; + double expected_lp = lp + 3.0 - 1.0 - 2.0 + 0.0; + Eigen::Matrix phi( + deserializer.read_positive_ordered(lp, 4)); + EXPECT_FLOAT_EQ(v0, phi[0]); + EXPECT_FLOAT_EQ(v1, phi[1]); + EXPECT_FLOAT_EQ(v2, phi[2]); + EXPECT_FLOAT_EQ(v3, phi[3]); + EXPECT_FLOAT_EQ(expected_lp, lp); +} + +TEST(deserializer_vector, offset_multiplier) { + std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + Eigen::Matrix phi( + deserializer.read_offset_multiplier(0, 1, 4)); + EXPECT_FLOAT_EQ(theta[0], phi[0]); + EXPECT_FLOAT_EQ(theta[1], phi[1]); + EXPECT_FLOAT_EQ(theta[2], phi[2]); + EXPECT_FLOAT_EQ(theta[3], phi[3]); +} + +TEST(deserializer_vector, offset_multiplier_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0; + Eigen::Matrix phi( + deserializer.read_offset_multiplier(0, 1, lp, 4)); + EXPECT_FLOAT_EQ(theta[0], phi[0]); + EXPECT_FLOAT_EQ(theta[1], phi[1]); + EXPECT_FLOAT_EQ(theta[2], phi[2]); + EXPECT_FLOAT_EQ(theta[3], phi[3]); +} + +TEST(deserializer_vector, offset_multiplier_constrain_lp) { + std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0; + Eigen::Matrix phi( + deserializer.read_offset_multiplier(0, 2, lp, 4)); + EXPECT_FLOAT_EQ(theta[0] * 2, phi[0]); + EXPECT_FLOAT_EQ(theta[1] * 2, phi[1]); + EXPECT_FLOAT_EQ(theta[2] * 2, phi[2]); + EXPECT_FLOAT_EQ(theta[3] * 2, phi[3]); + EXPECT_FLOAT_EQ(lp, std::log(2) * 4); +} + +// matrix + +TEST(deserializer_matrix, read) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (int i = 0; i < 7; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); } + using eig_mat = Eigen::Matrix; + eig_mat y = deserializer.read(3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(7.0, y(0, 0)); + EXPECT_FLOAT_EQ(8.0, y(1, 0)); + EXPECT_FLOAT_EQ(9.0, y(2, 0)); + EXPECT_FLOAT_EQ(10.0, y(0, 1)); + EXPECT_FLOAT_EQ(11.0, y(1, 1)); + EXPECT_FLOAT_EQ(12.0, y(2, 1)); + + double a = deserializer.read(); + EXPECT_FLOAT_EQ(13.0, a); } -TEST(deserializer_varmat, var_row_vector) { - using stan::math::var; - using stan::math::var_value; - using var_row_vec = var_value; - std::vector theta{0, 1, 2, 3, 4}; + +TEST(deserializer_matrix, matrix_lb) { std::vector theta_i; - stan::io::deserializer deserializer(theta, theta_i); - auto vec_x = deserializer.read(5); - EXPECT_TRUE((stan::is_var_row_vector::value)); - for (int i = 0; i < 5; ++i) { - EXPECT_EQ(vec_x.val()(i), i); + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (int i = 0; i < 7; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); } - auto vec_x_empty = deserializer.read(0); + double lb = -1.5; + Eigen::Matrix y + = deserializer.read_lb(lb, 3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(7.0, y(0, 0)); + EXPECT_FLOAT_EQ(8.0, y(1, 0)); + EXPECT_FLOAT_EQ(9.0, y(2, 0)); + EXPECT_FLOAT_EQ(10.0, y(0, 1)); + EXPECT_FLOAT_EQ(11.0, y(1, 1)); + EXPECT_FLOAT_EQ(12.0, y(2, 1)); + + double a = deserializer.read(); + EXPECT_FLOAT_EQ(13.0, a); } -TEST(deserializer_varmat, var_row_vector_double) { - using stan::math::var; - using stan::math::var_value; - using var_row_vec = var_value; - std::vector theta{0, 1, 2, 3, 4}; +TEST(deserializer_matrix, matrix_lb_constrain) { std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); - auto vec_x = deserializer.read(5); - EXPECT_TRUE( - (stan::is_eigen_row_vector::value - && std::is_arithmetic>::value)); - for (int i = 0; i < 5; ++i) { - EXPECT_EQ(vec_x.val()(i), i); + for (int i = 0; i < 7; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); } - auto vec_x_empty = deserializer.read(0); + double lb = -1.5; + double lp = 0; + Eigen::Matrix y + = deserializer.read_lb(lb, lp, 3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(7.0, lb), y(0, 0)); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(8.0, lb), y(1, 0)); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(9.0, lb), y(2, 0)); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(10.0, lb), y(0, 1)); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(11.0, lb), y(1, 1)); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(12.0, lb), y(2, 1)); + + double a = deserializer.read(); + EXPECT_FLOAT_EQ(13.0, a); } -TEST(deserializer_varmat, var_matrix) { - using stan::math::var; - using stan::math::var_value; - using var_matrix = var_value; - std::vector theta{0, 1, 2, 3, 4, 5, 6, 7, 8}; +TEST(deserializer_matrix, matrix_lb_constrain_lp) { std::vector theta_i; - stan::io::deserializer deserializer(theta, theta_i); - auto mat_x = deserializer.read(3, 3); - EXPECT_TRUE((stan::is_var_matrix::value)); - for (int i = 0; i < 9; ++i) { - EXPECT_EQ(mat_x.val()(i), i); + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (int i = 0; i < 7; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); } - auto mat_x_empty = deserializer.read(0, 0); + double lb = -1.5; + double lp = -5.0; + Eigen::Matrix y + = deserializer.read_lb(lb, lp, 3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(7.0, lb, lp), y(0, 0)); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(8.0, lb, lp), y(1, 0)); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(9.0, lb, lp), y(2, 0)); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(10.0, lb, lp), y(0, 1)); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(11.0, lb, lp), y(1, 1)); + EXPECT_FLOAT_EQ(stan::math::lb_constrain(12.0, lb, lp), y(2, 1)); + + double a = deserializer.read(); + EXPECT_FLOAT_EQ(13.0, a); } -TEST(deserializer_varmat, var_matrix_double) { - using stan::math::var; - using stan::math::var_value; - using var_matrix = var_value; - std::vector theta{0, 1, 2, 3, 4, 5, 6, 7, 8}; +TEST(deserializer_matrix, matrix_ub) { std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); - auto mat_x = deserializer.read(3, 3); - EXPECT_TRUE( - (stan::is_eigen_dense_dynamic::value - && std::is_arithmetic>::value)); - for (int i = 0; i < 9; ++i) { - EXPECT_EQ(mat_x.val()(i), i); + for (int i = 0; i < 7; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + double ub = 12.5; + Eigen::Matrix y + = deserializer.read_ub(ub, 3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(7.0, y(0, 0)); + EXPECT_FLOAT_EQ(8.0, y(1, 0)); + EXPECT_FLOAT_EQ(9.0, y(2, 0)); + EXPECT_FLOAT_EQ(10.0, y(0, 1)); + EXPECT_FLOAT_EQ(11.0, y(1, 1)); + EXPECT_FLOAT_EQ(12.0, y(2, 1)); + + double a = deserializer.read(); + EXPECT_FLOAT_EQ(13.0, a); +} + +TEST(deserializer_matrix, matrix_ub_constrain) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (int i = 0; i < 7; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); } - auto mat_x_empty = deserializer.read(0, 0); + double ub = 14.1; + double lp = 0; + Eigen::Matrix y + = deserializer.read_ub(ub, lp, 3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(7.0, ub), y(0, 0)); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(8.0, ub), y(1, 0)); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(9.0, ub), y(2, 0)); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(10.0, ub), y(0, 1)); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(11.0, ub), y(1, 1)); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(12.0, ub), y(2, 1)); + + double a = deserializer.read(); + EXPECT_FLOAT_EQ(13.0, a); +} + +TEST(deserializer_matrix, matrix_ub_constrain_lp) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (int i = 0; i < 7; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + double ub = 12.1; + double lp = -5.0; + Eigen::Matrix y + = deserializer.read_ub(ub, lp, 3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(7.0, ub, lp), y(0, 0)); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(8.0, ub, lp), y(1, 0)); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(9.0, ub, lp), y(2, 0)); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(10.0, ub, lp), y(0, 1)); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(11.0, ub, lp), y(1, 1)); + EXPECT_FLOAT_EQ(stan::math::ub_constrain(12.0, ub, lp), y(2, 1)); + + double a = deserializer.read(); + EXPECT_FLOAT_EQ(13.0, a); +} + +TEST(deserializer_matrix, matrix_lub) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (int i = 0; i < 7; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + double lb = 6.9; + double ub = 12.5; + Eigen::Matrix y + = deserializer.read_lub(lb, ub, 3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(7.0, y(0, 0)); + EXPECT_FLOAT_EQ(8.0, y(1, 0)); + EXPECT_FLOAT_EQ(9.0, y(2, 0)); + EXPECT_FLOAT_EQ(10.0, y(0, 1)); + EXPECT_FLOAT_EQ(11.0, y(1, 1)); + EXPECT_FLOAT_EQ(12.0, y(2, 1)); + + double a = deserializer.read(); + EXPECT_FLOAT_EQ(13.0, a); +} + +TEST(deserializer_matrix, matrix_lub_constrain) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (int i = 0; i < 7; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + double lb = 3.5; + double ub = 14.1; + double lp = 0; + Eigen::Matrix y + = deserializer.read_lub(lb, ub, lp, 3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(7.0, lb, ub), y(0, 0)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(8.0, lb, ub), y(1, 0)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(9.0, lb, ub), y(2, 0)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(10.0, lb, ub), y(0, 1)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(11.0, lb, ub), y(1, 1)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(12.0, lb, ub), y(2, 1)); + + double a = deserializer.read(); + EXPECT_FLOAT_EQ(13.0, a); +} + +TEST(deserializer_matrix, matrix_lub_constrain_lp) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (int i = 0; i < 7; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + double lb = 4.1; + double ub = 12.1; + double lp = -5.0; + Eigen::Matrix y + = deserializer.read_lub(lb, ub, lp, 3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(7.0, lb, ub, lp), y(0, 0)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(8.0, lb, ub, lp), y(1, 0)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(9.0, lb, ub, lp), y(2, 0)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(10.0, lb, ub, lp), y(0, 1)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(11.0, lb, ub, lp), y(1, 1)); + EXPECT_FLOAT_EQ(stan::math::lub_constrain(12.0, lb, ub, lp), y(2, 1)); + + double a = deserializer.read(); + EXPECT_FLOAT_EQ(13.0, a); +} + +TEST(deserializer_matrix, corr_matrix) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + theta[0] = 1.0000000000000000; + theta[1] = 0.1817621852191252; + theta[2] = 0.8620926037637362; + theta[3] = 0.1817621852191252; + theta[4] = 1.0000000000000000; + theta[5] = 0.2248293054822660; + theta[6] = 0.8620926037637362; + theta[7] = 0.2248293054822660; + theta[8] = 1.0000000000000001; // allow some tolerance + stan::io::deserializer deserializer(theta, theta_i); + Eigen::Matrix S + = deserializer.read_corr(3); + EXPECT_FLOAT_EQ(theta[0], S(0, 0)); +} +TEST(deserializer_matrix, corr_matrix_exception) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + theta[0] = 1.5; + theta[1] = 1.0; + theta[2] = 2.0; + theta[3] = 0.0; + theta[4] = 1.0; + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_THROW(deserializer.read_corr(1), std::domain_error); + EXPECT_THROW(deserializer.read_corr(2), std::domain_error); +} +TEST(deserializer_matrix, corr_matrix_constrain) { + using Eigen::Dynamic; + using Eigen::Matrix; + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(-1.0); + theta.push_back(0.0); + theta.push_back(0.5); + theta.push_back(1.0); + theta.push_back(2.0); + theta.push_back(1.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0; + Matrix R(deserializer.read_corr(lp, 3U)); + EXPECT_EQ(3, R.rows()); + EXPECT_EQ(3, R.cols()); + EXPECT_EQ(9, R.size()); + EXPECT_EQ(4U, deserializer.available()); + for (size_t i = 0; i < 3U; ++i) { + EXPECT_FLOAT_EQ(1.0, R(i, i)); + for (size_t j = i + 1; j < 3U; ++j) + EXPECT_FLOAT_EQ(R(i, j), R(j, i)); + } + Eigen::SelfAdjointEigenSolver< + Eigen::Matrix> + solver(R, Eigen::EigenvaluesOnly); + assert(solver.eigenvalues()[0] > 1E-10); +} +TEST(deserializer_matrix, corr_matrix_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(-1.0); + theta.push_back(0.0); + theta.push_back(0.5); + theta.push_back(1.0); + theta.push_back(2.0); + theta.push_back(1.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = -9.2; + Eigen::Matrix R( + deserializer.read_corr(lp, 3U)); + EXPECT_EQ(3, R.rows()); + EXPECT_EQ(3, R.cols()); + EXPECT_EQ(9, R.size()); + EXPECT_EQ(4U, deserializer.available()); + for (size_t i = 0; i < 3U; ++i) { + EXPECT_FLOAT_EQ(1.0, R(i, i)); + for (size_t j = i + 1; j < 3U; ++j) + EXPECT_FLOAT_EQ(R(i, j), R(j, i)); + } + Eigen::SelfAdjointEigenSolver< + Eigen::Matrix> + solver(R, Eigen::EigenvaluesOnly); + assert(solver.eigenvalues()[0] > 1E-10); + // FIXME: test jacobian +} + +TEST(deserializer_matrix, cov_matrix) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + theta[0] = 6.3295234356180128; + theta[1] = 0.6351775806192667; + theta[2] = 3.8081029582054304; + theta[3] = 0.6351775806192667; + theta[4] = 1.9293554162496527; + theta[5] = 0.5483126868366485; + theta[6] = 3.8081029582054304; + theta[7] = 0.5483126868366485; + theta[8] = 3.0827514661973088; + stan::io::deserializer deserializer(theta, theta_i); + Eigen::Matrix S + = deserializer.read_cov_matrix(3); + EXPECT_FLOAT_EQ(theta[0], S(0, 0)); + EXPECT_FLOAT_EQ(theta[1], S(1, 0)); + EXPECT_FLOAT_EQ(theta[7], S(2, 1)); + EXPECT_FLOAT_EQ(theta[8], S(2, 2)); +} +TEST(deserializer_matrix, cov_matrix_exception) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + theta[0] = 6.3; + theta[1] = 0.7; + theta[2] = 0.6; + theta[3] = 1.9; + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_THROW(deserializer.read_cov_matrix(2), std::domain_error); + EXPECT_THROW(deserializer.read_cov_matrix(0), std::invalid_argument); +} +TEST(deserializer_matrix, cov_matrix_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(-1.0); + theta.push_back(0.0); + theta.push_back(0.5); + theta.push_back(1.0); + theta.push_back(2.0); + theta.push_back(1.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0; + Eigen::Matrix S( + deserializer.read_cov_matrix(lp, 3U)); + EXPECT_EQ(3, S.rows()); + EXPECT_EQ(3, S.cols()); + EXPECT_EQ(9, S.size()); + EXPECT_EQ(1U, deserializer.available()); + for (size_t i = 0; i < 3U; ++i) + for (size_t j = i + 1; j < 3U; ++j) + EXPECT_FLOAT_EQ(S(i, j), S(j, i)); + Eigen::SelfAdjointEigenSolver< + Eigen::Matrix> + solver(S, Eigen::EigenvaluesOnly); + assert(solver.eigenvalues()[0] + > 1E-10); // check positive definite with smallest eigenvalue > 0 +} +TEST(deserializer_matrix, cov_matrix_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(-1.0); + theta.push_back(0.0); + theta.push_back(0.5); + theta.push_back(1.0); + theta.push_back(2.0); + theta.push_back(1.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = -3.1; + + Eigen::Matrix S( + deserializer.read_cov_matrix(lp, 3U)); + + EXPECT_EQ(3, S.rows()); + EXPECT_EQ(3, S.cols()); + EXPECT_EQ(9, S.size()); + EXPECT_EQ(1U, deserializer.available()); + for (size_t i = 0; i < 3U; ++i) + for (size_t j = i + 1; j < 3U; ++j) + EXPECT_FLOAT_EQ(S(i, j), S(j, i)); + Eigen::SelfAdjointEigenSolver< + Eigen::Matrix> + solver(S, Eigen::EigenvaluesOnly); + assert(solver.eigenvalues()[0] + > 1E-10); // check positive definite with smallest eigenvalue > 0 + // FIXME: test Jacobian +} + +TEST(deserializer_matrix, cholesky_factor_cov) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + // column major + theta[0] = 1; + theta[1] = 2; + theta[2] = 3; + + theta[3] = 0; + theta[4] = 4; + theta[5] = 5; + + theta[6] = 0; + theta[7] = 0; + theta[8] = 6; + stan::io::deserializer deserializer(theta, theta_i); + Eigen::Matrix S + = deserializer.read_cholesky_factor_cov(3, 3); + EXPECT_FLOAT_EQ(theta[0], S(0, 0)); + EXPECT_FLOAT_EQ(theta[1], S(1, 0)); + EXPECT_FLOAT_EQ(theta[7], S(1, 2)); + EXPECT_FLOAT_EQ(theta[8], S(2, 2)); +} +TEST(deserializer_matrix, cholesky_factor_cov_asymmetric) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + // column major + theta[0] = 1; + theta[1] = 2; + theta[2] = 3; + + theta[3] = 0; + theta[4] = 4; + theta[5] = 5; + + stan::io::deserializer deserializer(theta, theta_i); + Eigen::Matrix S + = deserializer.read_cholesky_factor_cov(3, 2); + EXPECT_FLOAT_EQ(theta[0], S(0, 0)); + EXPECT_FLOAT_EQ(theta[1], S(1, 0)); + EXPECT_FLOAT_EQ(theta[2], S(2, 0)); + + EXPECT_FLOAT_EQ(theta[3], S(0, 1)); + EXPECT_FLOAT_EQ(theta[4], S(1, 1)); + EXPECT_FLOAT_EQ(theta[5], S(2, 1)); +} + +TEST(deserializer_matrix, cholesky_factor_cov_exception) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + theta[0] = -6.3; + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_THROW(deserializer.read_cholesky_factor_cov(2, 2), std::domain_error); + EXPECT_THROW(deserializer.read_cholesky_factor_cov(0, 0), std::domain_error); + + theta[0] = 1; + EXPECT_THROW(deserializer.read_cholesky_factor_cov(2, 3), std::domain_error); +} +TEST(deserializer_matrix, cholesky_factor_cov_constrain) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 8; ++i) + theta.push_back(-static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0; + Eigen::Matrix L( + deserializer.read_cholesky_factor_cov(lp, 3U, 3U)); + EXPECT_NO_THROW(stan::math::check_cholesky_factor( + "test_cholesky_factor_constrain", "L", L)); + EXPECT_EQ(3, L.rows()); + EXPECT_EQ(3, L.cols()); + EXPECT_EQ(9, L.size()); + EXPECT_EQ(2U, deserializer.available()); +} + + +TEST(deserializer_matrix, cholesky_factor_cov_constrain_asymmetric) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 8; ++i) + theta.push_back(-static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0; + Eigen::Matrix L( + deserializer.read_cholesky_factor_cov(lp, 3U, 2U)); + EXPECT_NO_THROW(stan::math::check_cholesky_factor( + "test_cholesky_factor_constrain", "L", L)); + EXPECT_EQ(3, L.rows()); + EXPECT_EQ(2, L.cols()); + EXPECT_EQ(6, L.size()); + EXPECT_EQ(3U, deserializer.available()); +} +TEST(deserializer_matrix, cholesky_factor_cov_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 8; ++i) + theta.push_back(-static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 1.9; + Eigen::Matrix L( + deserializer.read_cholesky_factor_cov(lp, 3U, 3U)); + EXPECT_NO_THROW(stan::math::check_cholesky_factor( + "test_cholesky_factor_constrain", "L", L)); + EXPECT_EQ(3, L.rows()); + EXPECT_EQ(3, L.cols()); + EXPECT_EQ(9, L.size()); + EXPECT_EQ(2U, deserializer.available()); + EXPECT_EQ(1.9 + log(L(0, 0)) + log(L(1, 1)) + log(L(2, 2)), lp); +} +TEST(deserializer_matrix, cholesky_factor_cov_constrain_jacobian_asymmetric) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 12; ++i) + theta.push_back(-static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 1.9; + Eigen::Matrix L( + deserializer.read_cholesky_factor_cov(lp, 4U, 3U)); + EXPECT_NO_THROW(stan::math::check_cholesky_factor( + "test_cholesky_factor_constrain", "L", L)); + EXPECT_EQ(4, L.rows()); + EXPECT_EQ(3, L.cols()); + EXPECT_EQ(12, L.size()); + EXPECT_EQ(3U, deserializer.available()); + EXPECT_EQ(1.9 + log(L(0, 0)) + log(L(1, 1)) + log(L(2, 2)), lp); +} + +TEST(deserializer_matrix, cholesky_factor_corr) { + std::vector theta_i; + std::vector theta(9); + // column major + theta[0] = 1; + theta[1] = 0; + theta[2] = 0; + + theta[3] = 0; + theta[4] = 1; + theta[5] = 0; + + theta[6] = 0; + theta[7] = 0; + theta[8] = 1; + stan::io::deserializer deserializer(theta, theta_i); + Eigen::Matrix S + = deserializer.read_cholesky_factor_corr(3); + EXPECT_FLOAT_EQ(theta[0], S(0, 0)); + EXPECT_FLOAT_EQ(theta[1], S(1, 0)); + EXPECT_FLOAT_EQ(theta[4], S(1, 1)); + EXPECT_FLOAT_EQ(theta[7], S(1, 2)); + EXPECT_FLOAT_EQ(theta[8], S(2, 2)); +} + +TEST(deserializer_matrix, cholesky_factor_corr_exception) { + std::vector theta_i; + std::vector theta(9); + Eigen::Matrix S; + + // non lower-triangular matrix (column major) + // the rest of these tests are with check_cholesky_factor_corr + theta[0] = 1; + theta[1] = 0; + theta[2] = 0; + + theta[3] = 0.5; + theta[4] = 1; + theta[5] = 0; + + theta[6] = 0; + theta[7] = 0; + theta[8] = 1; + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_THROW(deserializer.read_cholesky_factor_corr(3), std::domain_error); +} +TEST(deserializer_matrix, cholesky_factor_corr_constrain) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 8; ++i) + theta.push_back(-static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0; + Eigen::Matrix L( + deserializer.read_cholesky_factor_corr(lp, 3U)); + EXPECT_NO_THROW(stan::math::check_cholesky_factor_corr( + "test_cholesky_factor_corr_constrain", "L", L)); + EXPECT_EQ(3, L.rows()); + EXPECT_EQ(3, L.cols()); + EXPECT_EQ(9, L.size()); + EXPECT_EQ(5U, deserializer.available()); +} + + +TEST(deserializer_matrix, offset_multiplier) { + std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + Eigen::Matrix phi( + deserializer.read_offset_multiplier(0, 1, 2, 2)); + EXPECT_FLOAT_EQ(theta[0], phi(0, 0)); + EXPECT_FLOAT_EQ(theta[1], phi(1, 0)); + EXPECT_FLOAT_EQ(theta[2], phi(0, 1)); + EXPECT_FLOAT_EQ(theta[3], phi(1, 1)); +} + +TEST(deserializer_matrix, offset_multiplier_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0; + Eigen::Matrix phi( + deserializer.read_offset_multiplier(0, 1, lp, 2, 2)); + EXPECT_FLOAT_EQ(theta[0], phi(0, 0)); + EXPECT_FLOAT_EQ(theta[1], phi(1, 0)); + EXPECT_FLOAT_EQ(theta[2], phi(0, 1)); + EXPECT_FLOAT_EQ(theta[3], phi(1, 1)); +} + +TEST(deserializer_matrix, offset_multiplier_constrain_lp) { + std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0; + Eigen::Matrix phi( + deserializer.read_offset_multiplier(0, 2, lp, 2, 2)); + EXPECT_FLOAT_EQ(theta[0] * 2, phi(0, 0)); + EXPECT_FLOAT_EQ(theta[1] * 2, phi(1, 0)); + EXPECT_FLOAT_EQ(theta[2] * 2, phi(0, 1)); + EXPECT_FLOAT_EQ(theta[3] * 2, phi(1, 1)); + EXPECT_FLOAT_EQ(lp, std::log(2) * 4); } diff --git a/src/test/unit/io/deserializer_varmat_test.cpp b/src/test/unit/io/deserializer_varmat_test.cpp index 2d9cc200ae7..0d5c3aabfa6 100644 --- a/src/test/unit/io/deserializer_varmat_test.cpp +++ b/src/test/unit/io/deserializer_varmat_test.cpp @@ -219,6 +219,58 @@ TEST(deserializer_var_vector, positive_ordered_constrain_jacobian) { EXPECT_FLOAT_EQ(expected_lp, lp.val()); } + +TEST(deserializer_vector, offset_multiplier) { + std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + var_vector_t phi( + deserializer.read_offset_multiplier(0, 1, 4)); + EXPECT_FLOAT_EQ(theta[0].val(), phi.val()[0]); + EXPECT_FLOAT_EQ(theta[1].val(), phi.val()[1]); + EXPECT_FLOAT_EQ(theta[2].val(), phi.val()[2]); + EXPECT_FLOAT_EQ(theta[3].val(), phi.val()[3]); +} + +TEST(deserializer_vector, offset_multiplier_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp = 0; + var_vector_t phi( + deserializer.read_offset_multiplier(0, 1, lp, 4)); + EXPECT_FLOAT_EQ(theta[0].val(), phi.val()[0]); + EXPECT_FLOAT_EQ(theta[1].val(), phi.val()[1]); + EXPECT_FLOAT_EQ(theta[2].val(), phi.val()[2]); + EXPECT_FLOAT_EQ(theta[3].val(), phi.val()[3]); +} + +TEST(deserializer_vector, offset_multiplier_constrain_lp) { + std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp = 0; + var_vector_t phi( + deserializer.read_offset_multiplier(0, 2, lp, 4)); + EXPECT_FLOAT_EQ(theta[0].val() * 2, phi.val()[0]); + EXPECT_FLOAT_EQ(theta[1].val() * 2, phi.val()[1]); + EXPECT_FLOAT_EQ(theta[2].val() * 2, phi.val()[2]); + EXPECT_FLOAT_EQ(theta[3].val() * 2, phi.val()[3]); + EXPECT_FLOAT_EQ(lp.val(), std::log(2) * 4); +} + // matrix TEST(deserializer_var_matrix, read) { @@ -868,3 +920,54 @@ TEST(deserializer_var_matrix, cholesky_factor_corr_constrain) { EXPECT_EQ(9, L.size()); EXPECT_EQ(5U, deserializer.available()); } + +TEST(deserializer_var_matrix, offset_multiplier) { + std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + var_matrix_t phi( + deserializer.read_offset_multiplier(0, 1, 2, 2)); + EXPECT_FLOAT_EQ(theta[0].val(), phi.val()(0, 0)); + EXPECT_FLOAT_EQ(theta[1].val(), phi.val()(1, 0)); + EXPECT_FLOAT_EQ(theta[2].val(), phi.val()(0, 1)); + EXPECT_FLOAT_EQ(theta[3].val(), phi.val()(1, 1)); +} + +TEST(deserializer_var_matrix, offset_multiplier_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp = 0; + var_matrix_t phi( + deserializer.read_offset_multiplier(0, 1, lp, 2, 2)); + EXPECT_FLOAT_EQ(theta[0].val(), phi.val()(0, 0)); + EXPECT_FLOAT_EQ(theta[1].val(), phi.val()(1, 0)); + EXPECT_FLOAT_EQ(theta[2].val(), phi.val()(0, 1)); + EXPECT_FLOAT_EQ(theta[3].val(), phi.val()(1, 1)); +} + +TEST(deserializer_var_matrix, offset_multiplier_constrain_lp) { + std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp = 0; + var_matrix_t phi( + deserializer.read_offset_multiplier(0, 2, lp, 2, 2)); + EXPECT_FLOAT_EQ(theta[0].val() * 2, phi.val()(0, 0)); + EXPECT_FLOAT_EQ(theta[1].val() * 2, phi.val()(1, 0)); + EXPECT_FLOAT_EQ(theta[2].val() * 2, phi.val()(0, 1)); + EXPECT_FLOAT_EQ(theta[3].val() * 2, phi.val()(1, 1)); + EXPECT_FLOAT_EQ(lp.val(), std::log(2) * 4); +} From a6b757b8682c9137074c53c4e3002dd478349eab Mon Sep 17 00:00:00 2001 From: Stan Jenkins Date: Wed, 3 Mar 2021 04:37:41 +0000 Subject: [PATCH 11/29] [Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.04.1 (tags/RELEASE_600/final) --- .../unit/io/deserializer_stdvector_test.cpp | 24 +++--- src/test/unit/io/deserializer_test.cpp | 73 ++++++++++++------- src/test/unit/io/deserializer_varmat_test.cpp | 4 +- 3 files changed, 60 insertions(+), 41 deletions(-) diff --git a/src/test/unit/io/deserializer_stdvector_test.cpp b/src/test/unit/io/deserializer_stdvector_test.cpp index 7b9c62e1994..077ef69166b 100644 --- a/src/test/unit/io/deserializer_stdvector_test.cpp +++ b/src/test/unit/io/deserializer_stdvector_test.cpp @@ -712,7 +712,6 @@ TEST(deserializer_stdvec_vector, positive_ordered_constrain_jacobian) { EXPECT_FLOAT_EQ(expected_lp, lp); } - TEST(deserializer_stdvec_vector, offset_multiplier) { std::vector theta_i; std::vector theta; @@ -725,7 +724,8 @@ TEST(deserializer_stdvec_vector, offset_multiplier) { theta.push_back(-2.0); theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); - auto phi(deserializer.read_offset_multiplier>(0, 1, 2, 4)); + auto phi(deserializer.read_offset_multiplier>( + 0, 1, 2, 4)); for (int i = 0; i < 2; ++i) { EXPECT_FLOAT_EQ(theta[0], phi[i][0]); EXPECT_FLOAT_EQ(theta[1], phi[i][1]); @@ -747,7 +747,9 @@ TEST(deserializer_stdvec_vector, offset_multiplier_constrain) { theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); double lp = 0; - auto phi(deserializer.read_offset_multiplier, false>(0, 1, lp, 2, 4)); + auto phi( + deserializer.read_offset_multiplier, false>( + 0, 1, lp, 2, 4)); for (int i = 0; i < 2; ++i) { EXPECT_FLOAT_EQ(theta[0], phi[i][0]); EXPECT_FLOAT_EQ(theta[1], phi[i][1]); @@ -769,7 +771,9 @@ TEST(deserializer_stdvec_vector, offset_multiplier_constrain_lp) { theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); double lp = 0; - auto phi(deserializer.read_offset_multiplier, true>(0, 2, lp, 2, 4)); + auto phi( + deserializer.read_offset_multiplier, true>( + 0, 2, lp, 2, 4)); for (int i = 0; i < 2; ++i) { EXPECT_FLOAT_EQ(theta[0] * 2, phi[i][0]); EXPECT_FLOAT_EQ(theta[1] * 2, phi[i][1]); @@ -1539,8 +1543,6 @@ TEST(deserializer_stdvec_matrix, cholesky_factor_corr_constrain) { EXPECT_EQ(9, L[0].size()); } - - TEST(deserializer_stdvec_matrix, offset_multiplier) { std::vector theta_i; std::vector theta; @@ -1553,8 +1555,8 @@ TEST(deserializer_stdvec_matrix, offset_multiplier) { theta.push_back(-2.0); theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); - auto phi( - deserializer.read_offset_multiplier>(0, 1, 2, 2, 2)); + auto phi(deserializer.read_offset_multiplier>( + 0, 1, 2, 2, 2)); for (int i = 0; i < 2; ++i) { EXPECT_FLOAT_EQ(theta[0], phi[i](0, 0)); EXPECT_FLOAT_EQ(theta[1], phi[i](1, 0)); @@ -1577,7 +1579,8 @@ TEST(deserializer_stdvec_matrix, offset_multiplier_constrain) { stan::io::deserializer deserializer(theta, theta_i); double lp = 0; auto phi( - deserializer.read_offset_multiplier, false>(0, 1, lp, 2, 2, 2)); + deserializer.read_offset_multiplier, false>( + 0, 1, lp, 2, 2, 2)); for (int i = 0; i < 2; ++i) { EXPECT_FLOAT_EQ(theta[0], phi[i](0, 0)); EXPECT_FLOAT_EQ(theta[1], phi[i](1, 0)); @@ -1600,7 +1603,8 @@ TEST(deserializer_stdvec_matrix, offset_multiplier_constrain_lp) { stan::io::deserializer deserializer(theta, theta_i); double lp = 0; auto phi( - deserializer.read_offset_multiplier, true>(0, 2, lp, 2, 2, 2)); + deserializer.read_offset_multiplier, true>( + 0, 2, lp, 2, 2, 2)); for (int i = 0; i < 2; ++i) { EXPECT_FLOAT_EQ(theta[0] * 2, phi[i](0, 0)); EXPECT_FLOAT_EQ(theta[1] * 2, phi[i](1, 0)); diff --git a/src/test/unit/io/deserializer_test.cpp b/src/test/unit/io/deserializer_test.cpp index 0d8261c3076..4ffeb48233c 100644 --- a/src/test/unit/io/deserializer_test.cpp +++ b/src/test/unit/io/deserializer_test.cpp @@ -477,10 +477,8 @@ TEST(deserializer_scalar, corr_constrain_jacobian) { EXPECT_FLOAT_EQ(expected_lp, lp); } - // vector - TEST(deserializer_vector, read) { std::vector theta_i; std::vector theta; @@ -491,7 +489,8 @@ TEST(deserializer_vector, read) { double x = deserializer.read(); EXPECT_FLOAT_EQ(static_cast(i), x); } - Eigen::Matrix y = deserializer.read(4); + Eigen::Matrix y + = deserializer.read(4); EXPECT_EQ(4, y.rows()); EXPECT_EQ(1, y.cols()); EXPECT_EQ(4, y.size()); @@ -529,15 +528,18 @@ TEST(deserializer_vector, unit_vector_exception) { theta[4] = sqrt(1.0); theta[5] = sqrt(1.0); EXPECT_NO_THROW(deserializer.read_unit_vector(4)); - EXPECT_THROW(deserializer.read_unit_vector(2), std::domain_error); - EXPECT_THROW(deserializer.read_unit_vector(0), std::invalid_argument); + EXPECT_THROW(deserializer.read_unit_vector(2), + std::domain_error); + EXPECT_THROW(deserializer.read_unit_vector(0), + std::invalid_argument); } TEST(deserializer_vector, simplex) { std::vector theta_i(0); std::vector theta(4, 0.25); stan::io::deserializer deserializer(theta, theta_i); - Eigen::Matrix y = deserializer.read_simplex(4); + Eigen::Matrix y + = deserializer.read_simplex(4); EXPECT_EQ(4, y.size()); EXPECT_FLOAT_EQ(0.25, y[0]); EXPECT_FLOAT_EQ(0.25, y[1]); @@ -557,8 +559,10 @@ TEST(deserializer_vector, simplex_exception) { theta[4] = 1.0; theta[5] = 1.0; EXPECT_NO_THROW(deserializer.read_simplex(4)); - EXPECT_THROW(deserializer.read_simplex(2), std::domain_error); - EXPECT_THROW(deserializer.read_simplex(0), std::invalid_argument); + EXPECT_THROW(deserializer.read_simplex(2), + std::domain_error); + EXPECT_THROW(deserializer.read_simplex(0), + std::invalid_argument); } TEST(deserializer_vector, ordered) { @@ -568,7 +572,8 @@ TEST(deserializer_vector, ordered) { theta.push_back(static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); EXPECT_FLOAT_EQ(0.0, deserializer.read()); // throw away theta[0] - Eigen::Matrix y = deserializer.read_ordered(5); + Eigen::Matrix y + = deserializer.read_ordered(5); EXPECT_EQ(5, y.size()); EXPECT_FLOAT_EQ(1.0, y[0]); EXPECT_FLOAT_EQ(2.0, y[1]); @@ -582,7 +587,8 @@ TEST(deserializer_vector, ordered_exception) { theta.push_back(static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); EXPECT_FLOAT_EQ(0.0, deserializer.read()); // throw away theta[0] - Eigen::Matrix y = deserializer.read_ordered(5); + Eigen::Matrix y + = deserializer.read_ordered(5); EXPECT_EQ(5, y.size()); EXPECT_FLOAT_EQ(1.0, y[0]); EXPECT_FLOAT_EQ(2.0, y[1]); @@ -602,7 +608,8 @@ TEST(deserializer_vector, ordered_constrain) { double v3 = v2 + exp(0.0); stan::io::deserializer deserializer(theta, theta_i); double lp = 0; - Eigen::Matrix phi(deserializer.read_ordered(lp, 4)); + Eigen::Matrix phi( + deserializer.read_ordered(lp, 4)); EXPECT_FLOAT_EQ(v0, phi[0]); EXPECT_FLOAT_EQ(v1, phi[1]); EXPECT_FLOAT_EQ(v2, phi[2]); @@ -622,7 +629,8 @@ TEST(deserializer_vector, ordered_constrain_jacobian) { stan::io::deserializer deserializer(theta, theta_i); double lp = -101.1; double expected_lp = lp - 1.0 - 2.0 + 0.0; - Eigen::Matrix phi(deserializer.read_ordered(lp, 4)); + Eigen::Matrix phi( + deserializer.read_ordered(lp, 4)); EXPECT_FLOAT_EQ(v0, phi[0]); EXPECT_FLOAT_EQ(v1, phi[1]); EXPECT_FLOAT_EQ(v2, phi[2]); @@ -637,7 +645,8 @@ TEST(deserializer_vector, positive_ordered) { theta.push_back(static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); EXPECT_FLOAT_EQ(0.0, deserializer.read()); // throw away theta[0] - Eigen::Matrix y = deserializer.read_positive_ordered(5); + Eigen::Matrix y + = deserializer.read_positive_ordered(5); EXPECT_EQ(5, y.size()); EXPECT_FLOAT_EQ(1.0, y[0]); EXPECT_FLOAT_EQ(2.0, y[1]); @@ -767,7 +776,6 @@ TEST(deserializer_matrix, read) { EXPECT_FLOAT_EQ(13.0, a); } - TEST(deserializer_matrix, matrix_lb) { std::vector theta_i; std::vector theta; @@ -1058,7 +1066,8 @@ TEST(deserializer_matrix, corr_matrix_constrain) { theta.push_back(1.0); stan::io::deserializer deserializer(theta, theta_i); double lp = 0; - Matrix R(deserializer.read_corr(lp, 3U)); + Matrix R( + deserializer.read_corr(lp, 3U)); EXPECT_EQ(3, R.rows()); EXPECT_EQ(3, R.cols()); EXPECT_EQ(9, R.size()); @@ -1119,7 +1128,7 @@ TEST(deserializer_matrix, cov_matrix) { theta[8] = 3.0827514661973088; stan::io::deserializer deserializer(theta, theta_i); Eigen::Matrix S - = deserializer.read_cov_matrix(3); + = deserializer.read_cov_matrix(3); EXPECT_FLOAT_EQ(theta[0], S(0, 0)); EXPECT_FLOAT_EQ(theta[1], S(1, 0)); EXPECT_FLOAT_EQ(theta[7], S(2, 1)); @@ -1135,8 +1144,10 @@ TEST(deserializer_matrix, cov_matrix_exception) { theta[2] = 0.6; theta[3] = 1.9; stan::io::deserializer deserializer(theta, theta_i); - EXPECT_THROW(deserializer.read_cov_matrix(2), std::domain_error); - EXPECT_THROW(deserializer.read_cov_matrix(0), std::invalid_argument); + EXPECT_THROW(deserializer.read_cov_matrix(2), + std::domain_error); + EXPECT_THROW(deserializer.read_cov_matrix(0), + std::invalid_argument); } TEST(deserializer_matrix, cov_matrix_constrain) { std::vector theta_i; @@ -1254,11 +1265,14 @@ TEST(deserializer_matrix, cholesky_factor_cov_exception) { theta.push_back(static_cast(i)); theta[0] = -6.3; stan::io::deserializer deserializer(theta, theta_i); - EXPECT_THROW(deserializer.read_cholesky_factor_cov(2, 2), std::domain_error); - EXPECT_THROW(deserializer.read_cholesky_factor_cov(0, 0), std::domain_error); + EXPECT_THROW(deserializer.read_cholesky_factor_cov(2, 2), + std::domain_error); + EXPECT_THROW(deserializer.read_cholesky_factor_cov(0, 0), + std::domain_error); theta[0] = 1; - EXPECT_THROW(deserializer.read_cholesky_factor_cov(2, 3), std::domain_error); + EXPECT_THROW(deserializer.read_cholesky_factor_cov(2, 3), + std::domain_error); } TEST(deserializer_matrix, cholesky_factor_cov_constrain) { std::vector theta_i; @@ -1268,7 +1282,8 @@ TEST(deserializer_matrix, cholesky_factor_cov_constrain) { stan::io::deserializer deserializer(theta, theta_i); double lp = 0; Eigen::Matrix L( - deserializer.read_cholesky_factor_cov(lp, 3U, 3U)); + deserializer.read_cholesky_factor_cov(lp, 3U, + 3U)); EXPECT_NO_THROW(stan::math::check_cholesky_factor( "test_cholesky_factor_constrain", "L", L)); EXPECT_EQ(3, L.rows()); @@ -1277,7 +1292,6 @@ TEST(deserializer_matrix, cholesky_factor_cov_constrain) { EXPECT_EQ(2U, deserializer.available()); } - TEST(deserializer_matrix, cholesky_factor_cov_constrain_asymmetric) { std::vector theta_i; std::vector theta; @@ -1286,7 +1300,8 @@ TEST(deserializer_matrix, cholesky_factor_cov_constrain_asymmetric) { stan::io::deserializer deserializer(theta, theta_i); double lp = 0; Eigen::Matrix L( - deserializer.read_cholesky_factor_cov(lp, 3U, 2U)); + deserializer.read_cholesky_factor_cov(lp, 3U, + 2U)); EXPECT_NO_THROW(stan::math::check_cholesky_factor( "test_cholesky_factor_constrain", "L", L)); EXPECT_EQ(3, L.rows()); @@ -1373,7 +1388,8 @@ TEST(deserializer_matrix, cholesky_factor_corr_exception) { theta[7] = 0; theta[8] = 1; stan::io::deserializer deserializer(theta, theta_i); - EXPECT_THROW(deserializer.read_cholesky_factor_corr(3), std::domain_error); + EXPECT_THROW(deserializer.read_cholesky_factor_corr(3), + std::domain_error); } TEST(deserializer_matrix, cholesky_factor_corr_constrain) { std::vector theta_i; @@ -1392,7 +1408,6 @@ TEST(deserializer_matrix, cholesky_factor_corr_constrain) { EXPECT_EQ(5U, deserializer.available()); } - TEST(deserializer_matrix, offset_multiplier) { std::vector theta_i; std::vector theta; @@ -1419,7 +1434,8 @@ TEST(deserializer_matrix, offset_multiplier_constrain) { stan::io::deserializer deserializer(theta, theta_i); double lp = 0; Eigen::Matrix phi( - deserializer.read_offset_multiplier(0, 1, lp, 2, 2)); + deserializer.read_offset_multiplier(0, 1, lp, 2, + 2)); EXPECT_FLOAT_EQ(theta[0], phi(0, 0)); EXPECT_FLOAT_EQ(theta[1], phi(1, 0)); EXPECT_FLOAT_EQ(theta[2], phi(0, 1)); @@ -1436,7 +1452,8 @@ TEST(deserializer_matrix, offset_multiplier_constrain_lp) { stan::io::deserializer deserializer(theta, theta_i); double lp = 0; Eigen::Matrix phi( - deserializer.read_offset_multiplier(0, 2, lp, 2, 2)); + deserializer.read_offset_multiplier(0, 2, lp, 2, + 2)); EXPECT_FLOAT_EQ(theta[0] * 2, phi(0, 0)); EXPECT_FLOAT_EQ(theta[1] * 2, phi(1, 0)); EXPECT_FLOAT_EQ(theta[2] * 2, phi(0, 1)); diff --git a/src/test/unit/io/deserializer_varmat_test.cpp b/src/test/unit/io/deserializer_varmat_test.cpp index 0d5c3aabfa6..6f7024f2274 100644 --- a/src/test/unit/io/deserializer_varmat_test.cpp +++ b/src/test/unit/io/deserializer_varmat_test.cpp @@ -219,7 +219,6 @@ TEST(deserializer_var_vector, positive_ordered_constrain_jacobian) { EXPECT_FLOAT_EQ(expected_lp, lp.val()); } - TEST(deserializer_vector, offset_multiplier) { std::vector theta_i; std::vector theta; @@ -228,8 +227,7 @@ TEST(deserializer_vector, offset_multiplier) { theta.push_back(-2.0); theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); - var_vector_t phi( - deserializer.read_offset_multiplier(0, 1, 4)); + var_vector_t phi(deserializer.read_offset_multiplier(0, 1, 4)); EXPECT_FLOAT_EQ(theta[0].val(), phi.val()[0]); EXPECT_FLOAT_EQ(theta[1].val(), phi.val()[1]); EXPECT_FLOAT_EQ(theta[2].val(), phi.val()[2]); From e33f868787591e115dd9430766a09fcb00cd1aff Mon Sep 17 00:00:00 2001 From: Steve Bronder Date: Wed, 3 Mar 2021 20:14:00 -0500 Subject: [PATCH 12/29] use newest offset_mul branch for math --- lib/stan_math | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/stan_math b/lib/stan_math index acf940c6e81..06c93577864 160000 --- a/lib/stan_math +++ b/lib/stan_math @@ -1 +1 @@ -Subproject commit acf940c6e81acca41edb23ed6425ff3940087d5d +Subproject commit 06c9357786489c7468c2dbe10d75197307155565 From 0c1057af8fc9fe5dbd1aaadb9fe6cdf3ef4acbf3 Mon Sep 17 00:00:00 2001 From: Steve Bronder Date: Thu, 4 Mar 2021 11:04:17 -0500 Subject: [PATCH 13/29] update to develop math --- lib/stan_math | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/stan_math b/lib/stan_math index 06c93577864..fbe53a96f68 160000 --- a/lib/stan_math +++ b/lib/stan_math @@ -1 +1 @@ -Subproject commit 06c9357786489c7468c2dbe10d75197307155565 +Subproject commit fbe53a96f68e4144c7c0dd24a3e678ff9167588d From 3f966ebc083bd89d54a956f523617e7415ddce02 Mon Sep 17 00:00:00 2001 From: Steve Bronder Date: Fri, 5 Mar 2021 02:01:07 -0500 Subject: [PATCH 14/29] adds tests for complex scalar, vector, and matrix reads --- src/stan/io/deserializer.hpp | 19 ++++--- src/test/unit/io/deserializer_test.cpp | 69 +++++++++++++++++++++++++- 2 files changed, 79 insertions(+), 9 deletions(-) diff --git a/src/stan/io/deserializer.hpp b/src/stan/io/deserializer.hpp index 35a7407de06..ff9b7c9849d 100644 --- a/src/stan/io/deserializer.hpp +++ b/src/stan/io/deserializer.hpp @@ -158,8 +158,8 @@ class deserializer { template * = nullptr> auto read() { check_r_capacity(); - return std::complex(data_r_.coeffRef(pos_r_++), - data_r_.coeffRef(pos_r_++)); + return std::complex{data_r_.coeffRef(pos_r_++), + data_r_.coeffRef(pos_r_++)}; } /** @@ -205,9 +205,10 @@ class deserializer { } else { Ret ret(m); for (Eigen::Index i = 0; i < m; ++i) { - ret.coeffRef(i) = std::complex(data_r_.coeffRef(pos_r_++), - data_r_.coeffRef(pos_r_++)); + ret.coeffRef(i) = std::complex{data_r_.coeffRef(pos_r_++), + data_r_.coeffRef(pos_r_++)}; } + return ret; } } @@ -243,9 +244,10 @@ class deserializer { } else { Ret ret(m); for (Eigen::Index i = 0; i < m; ++i) { - ret.coeffRef(i) = std::complex(data_r_.coeffRef(pos_r_++), - data_r_.coeffRef(pos_r_++)); + ret.coeffRef(i) = std::complex{data_r_.coeffRef(pos_r_++), + data_r_.coeffRef(pos_r_++)}; } + return ret; } } @@ -285,9 +287,10 @@ class deserializer { } else { Ret ret(rows, cols); for (Eigen::Index i = 0; i < rows * cols; ++i) { - ret.coeffRef(i) = std::complex(data_r_.coeffRef(pos_r_++), - data_r_.coeffRef(pos_r_++)); + ret.coeffRef(i) = std::complex{data_r_.coeffRef(pos_r_++), + data_r_.coeffRef(pos_r_++)}; } + return ret; } } diff --git a/src/test/unit/io/deserializer_test.cpp b/src/test/unit/io/deserializer_test.cpp index 4ffeb48233c..78351fe9ef5 100644 --- a/src/test/unit/io/deserializer_test.cpp +++ b/src/test/unit/io/deserializer_test.cpp @@ -97,6 +97,23 @@ TEST(deserializer_scalar, read) { EXPECT_EQ(0U, deserializer.available()); } +TEST(deserializer_scalar, complex_read) { + std::vector theta_i; + std::vector theta; + theta.push_back(1.0); + theta.push_back(2.0); + theta.push_back(3.0); + theta.push_back(4.0); + stan::io::deserializer deserializer(theta, theta_i); + std::complex x = deserializer.read>(); + EXPECT_FLOAT_EQ(1.0, x.real()); + EXPECT_FLOAT_EQ(2.0, x.imag()); + std::complex y = deserializer.read>(); + EXPECT_FLOAT_EQ(3.0, y.real()); + EXPECT_FLOAT_EQ(4.0, y.imag()); + EXPECT_EQ(0U, deserializer.available()); +} + TEST(deserializer_scalar, read_lb) { std::vector theta_i; std::vector theta; @@ -503,6 +520,33 @@ TEST(deserializer_vector, read) { EXPECT_FLOAT_EQ(11.0, z); } +TEST(deserializer_vector, complex_read) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100U; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (size_t i = 0; i < 7U; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + using complex_vec = Eigen::Matrix, Eigen::Dynamic, 1>; + complex_vec y = deserializer.read(4); + EXPECT_EQ(4, y.rows()); + EXPECT_EQ(1, y.cols()); + EXPECT_EQ(4, y.size()); + double sentinal = 7; + for (int i = 0; i < y.size(); ++i) { + EXPECT_FLOAT_EQ(sentinal, y[i].real()); + ++sentinal; + EXPECT_FLOAT_EQ(sentinal, y[i].imag()); + ++sentinal; + } + + double z = deserializer.read(); + EXPECT_FLOAT_EQ(15.0, z); +} + TEST(deserializer_vector, unit_vector) { std::vector theta_i(0); std::vector theta(4, sqrt(0.25)); @@ -724,7 +768,7 @@ TEST(deserializer_vector, offset_multiplier_constrain) { stan::io::deserializer deserializer(theta, theta_i); double lp = 0; Eigen::Matrix phi( - deserializer.read_offset_multiplier(0, 1, lp, 4)); + deserializer.read_offset_multiplier(0.0, 1.0, lp, 4)); EXPECT_FLOAT_EQ(theta[0], phi[0]); EXPECT_FLOAT_EQ(theta[1], phi[1]); EXPECT_FLOAT_EQ(theta[2], phi[2]); @@ -776,6 +820,29 @@ TEST(deserializer_matrix, read) { EXPECT_FLOAT_EQ(13.0, a); } +TEST(deserializer_matrix, complex_read) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (int i = 0; i < 7; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + using eig_mat = Eigen::Matrix, Eigen::Dynamic, Eigen::Dynamic>; + eig_mat y = deserializer.read(3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + double sentinal = 7; + for (int i = 0; i < y.size(); ++i) { + EXPECT_FLOAT_EQ(sentinal, y(i).real()); + sentinal++; + EXPECT_FLOAT_EQ(sentinal, y(i).imag()); + sentinal++; + } +} + TEST(deserializer_matrix, matrix_lb) { std::vector theta_i; std::vector theta; From 7359b50366e876b7722b79f639966d60a0a5756d Mon Sep 17 00:00:00 2001 From: Stan Jenkins Date: Fri, 5 Mar 2021 07:01:35 +0000 Subject: [PATCH 15/29] [Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.04.1 (tags/RELEASE_600/final) --- src/test/unit/io/deserializer_test.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/test/unit/io/deserializer_test.cpp b/src/test/unit/io/deserializer_test.cpp index 78351fe9ef5..a2186c1643e 100644 --- a/src/test/unit/io/deserializer_test.cpp +++ b/src/test/unit/io/deserializer_test.cpp @@ -768,7 +768,8 @@ TEST(deserializer_vector, offset_multiplier_constrain) { stan::io::deserializer deserializer(theta, theta_i); double lp = 0; Eigen::Matrix phi( - deserializer.read_offset_multiplier(0.0, 1.0, lp, 4)); + deserializer.read_offset_multiplier(0.0, 1.0, lp, + 4)); EXPECT_FLOAT_EQ(theta[0], phi[0]); EXPECT_FLOAT_EQ(theta[1], phi[1]); EXPECT_FLOAT_EQ(theta[2], phi[2]); @@ -830,7 +831,8 @@ TEST(deserializer_matrix, complex_read) { double x = deserializer.read(); EXPECT_FLOAT_EQ(static_cast(i), x); } - using eig_mat = Eigen::Matrix, Eigen::Dynamic, Eigen::Dynamic>; + using eig_mat + = Eigen::Matrix, Eigen::Dynamic, Eigen::Dynamic>; eig_mat y = deserializer.read(3, 2); EXPECT_EQ(3, y.rows()); EXPECT_EQ(2, y.cols()); From d1760b0e9a679cc3278b01b9e4cfd4e9eafdcce0 Mon Sep 17 00:00:00 2001 From: Steve Bronder Date: Sat, 6 Mar 2021 21:18:02 -0500 Subject: [PATCH 16/29] removes read functions from deserializer that just check if constraints are satisfied. Removes template Size for Eigen::Index or size_t type. Uses value_type_t and removes unneeded methods --- src/stan/io/deserializer.hpp | 927 ++---------------- .../unit/io/deserializer_stdvector_test.cpp | 621 +----------- src/test/unit/io/deserializer_test.cpp | 544 +--------- src/test/unit/io/deserializer_varmat_test.cpp | 429 +------- 4 files changed, 93 insertions(+), 2428 deletions(-) diff --git a/src/stan/io/deserializer.hpp b/src/stan/io/deserializer.hpp index ff9b7c9849d..ef31a061dfc 100644 --- a/src/stan/io/deserializer.hpp +++ b/src/stan/io/deserializer.hpp @@ -31,16 +31,12 @@ namespace io { template class deserializer { private: - Eigen::Map> data_r_; // map of reals. - Eigen::Map> data_i_; // map of integers. - size_t r_size_{0}; // size of reals available. - size_t i_size_{0}; // size of integers available. + Eigen::Map> map_r_; // map of reals. + Eigen::Map> map_i_; // map of integers. + size_t r_size_{0}; // size of reals available. + size_t i_size_{0}; // size of integers available. size_t pos_r_{0}; // current position in map of reals. size_t pos_i_{0}; // current position in map of integers. - /** - * Return pointer to current scalar. - */ - inline T& scalar_ptr() { return data_r_.coeffRef(pos_r_); } /** * Return pointer to current scalar and incriment the internal counter. @@ -48,22 +44,9 @@ class deserializer { */ inline T& scalar_ptr_increment(size_t m) { pos_r_ += m; - return data_r_.coeffRef(pos_r_ - m); + return map_r_.coeffRef(pos_r_ - m); } - /** - * Return pointer to current integer. - */ - inline int& int_ptr() { return data_i_.coeffRef(pos_i_); } - - /** - * Return pointer to current integer and incriment the internal counter. - * @param m amount to move `pos_i_` up. - */ - inline int& int_ptr_increment(size_t m) { - pos_i_ += m; - return data_i_.coeffRef(pos_i_ - m); - } /** * Check if there is anything left to read for scalars. */ @@ -125,8 +108,8 @@ class deserializer { template * = nullptr> deserializer(RVec& data_r, IntVec& data_i) - : data_r_(data_r.data(), data_r.size()), - data_i_(data_i.data(), data_i.size()), + : map_r_(data_r.data(), data_r.size()), + map_i_(data_i.data(), data_i.size()), r_size_(data_r.size()), i_size_(data_i.size()) {} @@ -150,16 +133,16 @@ class deserializer { * @return Next scalar value. */ template >* = nullptr> - auto read() { + inline auto read() { check_r_capacity(); - return data_r_.coeffRef(pos_r_++); + return map_r_.coeffRef(pos_r_++); } template * = nullptr> - auto read() { + inline auto read() { check_r_capacity(); - return std::complex{data_r_.coeffRef(pos_r_++), - data_r_.coeffRef(pos_r_++)}; + return std::complex{map_r_.coeffRef(pos_r_++), + map_r_.coeffRef(pos_r_++)}; } /** @@ -168,21 +151,19 @@ class deserializer { * @return Next integer value. */ template * = nullptr> - auto read() { + inline auto read() { check_i_capacity(); - return data_i_.coeffRef(pos_i_++); + return map_i_.coeffRef(pos_i_++); } /** * Return an Eigen column vector of size `m`. - * @tparam Size an integral type * @tparam Ret The type to return. * @param m Size of column vector. */ - template * = nullptr, + template * = nullptr, require_not_vt_complex* = nullptr> - auto read(Size m) { + inline auto read(Eigen::Index m) { if (unlikely(m == 0)) { return map_vector_t(nullptr, m); } else { @@ -192,21 +173,19 @@ class deserializer { /** * Return an Eigen column vector of size `m` with inner complex type. - * @tparam Size an integral type * @tparam Ret The type to return. * @param m Size of column vector. */ - template * = nullptr, + template * = nullptr, require_vt_complex* = nullptr> - auto read(Size m) { + inline auto read(Eigen::Index m) { if (unlikely(m == 0)) { return Ret(map_vector_t(nullptr, m)); } else { Ret ret(m); for (Eigen::Index i = 0; i < m; ++i) { - ret.coeffRef(i) = std::complex{data_r_.coeffRef(pos_r_++), - data_r_.coeffRef(pos_r_++)}; + ret.coeffRef(i) = std::complex{map_r_.coeffRef(pos_r_++), + map_r_.coeffRef(pos_r_++)}; } return ret; } @@ -214,14 +193,12 @@ class deserializer { /** * Return an Eigen row vector of size `m`. - * @tparam Size an integral type * @tparam Ret The type to return. * @param m Size of row vector. */ - template * = nullptr, + template * = nullptr, require_not_vt_complex* = nullptr> - auto read(Size m) { + inline auto read(Eigen::Index m) { if (unlikely(m == 0)) { return map_row_vector_t(nullptr, m); } else { @@ -231,21 +208,19 @@ class deserializer { /** * Return an Eigen row vector of size `m` with inner complex type. - * @tparam Size an integral type * @tparam Ret The type to return. * @param m Size of row vector. */ - template * = nullptr, + template * = nullptr, require_vt_complex* = nullptr> - auto read(Size m) { + inline auto read(Eigen::Index m) { if (unlikely(m == 0)) { return Ret(map_row_vector_t(nullptr, m)); } else { Ret ret(m); for (Eigen::Index i = 0; i < m; ++i) { - ret.coeffRef(i) = std::complex{data_r_.coeffRef(pos_r_++), - data_r_.coeffRef(pos_r_++)}; + ret.coeffRef(i) = std::complex{map_r_.coeffRef(pos_r_++), + map_r_.coeffRef(pos_r_++)}; } return ret; } @@ -253,16 +228,14 @@ class deserializer { /** * Return an Eigen matrix of size `(rows, cols)`. - * @tparam Rows Integral type. - * @tparam Cols Integral type. * @tparam Ret The type to return. * @param rows The size of the rows of the matrix. * @param cols The size of the cols of the matrix. */ - template * = nullptr, require_not_vt_complex* = nullptr> - auto read(Rows rows, Cols cols) { + inline auto read(Eigen::Index rows, Eigen::Index cols) { if (rows == 0 || cols == 0) { return map_matrix_t(nullptr, rows, cols); } else { @@ -272,23 +245,21 @@ class deserializer { /** * Return an Eigen matrix of size `(rows, cols)` with complex inner type. - * @tparam Rows Integral type. - * @tparam Cols Integral type. * @tparam Ret The type to return. * @param rows The size of the rows of the matrix. * @param cols The size of the cols of the matrix. */ - template * = nullptr, require_vt_complex* = nullptr> - auto read(Rows rows, Cols cols) { + inline auto read(Eigen::Index rows, Eigen::Index cols) { if (rows == 0 || cols == 0) { return Ret(map_matrix_t(nullptr, rows, cols)); } else { Ret ret(rows, cols); for (Eigen::Index i = 0; i < rows * cols; ++i) { - ret.coeffRef(i) = std::complex{data_r_.coeffRef(pos_r_++), - data_r_.coeffRef(pos_r_++)}; + ret.coeffRef(i) = std::complex{map_r_.coeffRef(pos_r_++), + map_r_.coeffRef(pos_r_++)}; } return ret; } @@ -305,9 +276,9 @@ class deserializer { */ template * = nullptr, require_var_matrix_t* = nullptr> - auto read(Sizes... sizes) { - using value_t = typename std::decay_t::value_type; - using var_v_t = stan::math::promote_scalar_t; + inline auto read(Sizes... sizes) { + using stan::math::promote_scalar_t; + using var_v_t = promote_scalar_t>; return stan::math::to_var_value(this->read(sizes...)); } @@ -323,102 +294,33 @@ class deserializer { template * = nullptr, require_var_matrix_t* = nullptr> - auto read(Sizes... sizes) { - using value_t = typename std::decay_t::value_type; - return this->read(sizes...); + inline auto read(Sizes... sizes) { + return this->read>(sizes...); } /** * Return an `std::vector` * @tparam Ret The type to return. - * @tparam Size an integral type. * @tparam Sizes integral types. * @param m The size of the vector. * @param dims a possible set of inner container sizes passed to subsequent * `read` functions. */ - template * = nullptr> - inline auto read(Size m, Sizes... dims) { + inline auto read(Eigen::Index m, Sizes... dims) { if (unlikely(m == 0)) { return Ret(); } else { std::decay_t ret_vec; ret_vec.reserve(m); - for (Size i = 0; i < m; ++i) { + for (size_t i = 0; i < m; ++i) { ret_vec.emplace_back(this->read>(dims...)); } return ret_vec; } } - /** - * Return the next object, checking that it's elements are - * greater than or equal to the specified lower bound. - * - *

See stan::math::check_greater_or_equal(T,double). - * - * @tparam Ret The type to return. - * @tparam LB Type of lower bound. - * @tparam Sizes A pack of possible sizes to construct the object from. - * @param lb Lower bound. - * @param sizes a pack of sizes to use to construct the return. - * @throw std::runtime_error if the scalar is less than the - * specified lower bound - */ - template * = nullptr> - auto read_lb(const LB& lb, Sizes... sizes) { - auto ret = this->read(sizes...); - using stan::math::check_greater_or_equal; - using stan::math::value_of; - check_greater_or_equal("io deserializer", "Lower Bound", value_of(ret), - value_of(lb)); - return ret; - } - - /** - * Overload for `std::vector` return type and a non-`std::vector` lower bound. - * @tparam Ret The type to return. - * @tparam LB Type of lower bound. - * @tparam Sizes A pack of possible sizes to construct the object from. - * @param lb Lower bound. - * @param sizes a pack of sizes to use to construct the return. - * @throw std::runtime_error if the scalar is less than the - * specified lower bound - */ - template * = nullptr> - auto read_lb(const LB& lb, size_t vecsize, Sizes... sizes) { - std::decay_t ret; - ret.reserve(vecsize); - for (size_t i = 0; i < vecsize; ++i) { - ret.emplace_back(this->read_lb>(lb, sizes...)); - } - return ret; - } - - /** - * Overload for `std::vector` return type and a `std::vector` lower bound. - * @tparam Ret The type to return. - * @tparam LB Type of lower bound. - * @tparam Sizes A pack of possible sizes to construct the object from. - * @param lb Lower bound. - * @param sizes a pack of sizes to use to construct the return. - * @throw std::runtime_error if the scalar is less than the - * specified lower bound - */ - template * = nullptr> - auto read_lb(const std::vector& lb, size_t vecsize, Sizes... sizes) { - std::decay_t ret; - ret.reserve(vecsize); - for (size_t i = 0; i < vecsize; ++i) { - ret.emplace_back(this->read_lb>(lb[i], sizes...)); - } - return ret; - } - /** * Return the next object transformed to have the specified * lower bound, possibly incrementing the specified reference with the @@ -438,7 +340,7 @@ class deserializer { */ template - auto read_lb(const LB& lb, LP& lp, Sizes... sizes) { + inline auto read_lb(const LB& lb, LP& lp, Sizes... sizes) { if (Jacobian) { return stan::math::lb_constrain(this->read(sizes...), lb, lp); } else { @@ -446,77 +348,6 @@ class deserializer { } } - /** - * Return the next object, checking that it is - * less than or equal to the specified upper bound. - * - *

See stan::math::check_less_or_equal(T,double). - * - * @tparam Ret The type to return. - * @tparam UB Type of upper bound. - * @tparam Sizes A parameter pack of integral types. - * @param ub Lower bound. - * @param sizes A parameter pack of dimensions. - * @throw std::runtime_error if the scalar is less than the - * specified lower bound - */ - template * = nullptr> - auto read_ub(const UB& ub, Sizes... sizes) { - auto ret = this->read(sizes...); - using stan::math::check_less_or_equal; - using stan::math::value_of; - check_less_or_equal("io deserializer", "Upper Bound", value_of(ret), - value_of(ub)); - return ret; - } - - /** - * Specialization for `std::vector` return type and non-`std::vector` lower - * bound. - * @tparam Ret The type to return. - * @tparam UB Type of upper bound. - * @tparam Sizes A parameter pack of integral types. - * @param ub Lower bound. - * @param vecsize The size of the return `std::vector`. - * @param sizes A parameter pack of dimensions. - * @throw std::runtime_error if the scalar is less than the - * specified lower bound - */ - template * = nullptr> - auto read_ub(const UB& ub, size_t vecsize, Sizes... sizes) { - std::decay_t ret; - ret.reserve(vecsize); - for (size_t i = 0; i < vecsize; ++i) { - ret.emplace_back(this->read_ub>(ub, sizes...)); - } - return ret; - } - - /** - * Specialization for `std::vector` return type and an `std::vector` lower - * bound. - * @tparam Ret The type to return. - * @tparam UB Type of upper bound. - * @tparam Sizes A parameter pack of integral types. - * @param ub Lower bound. - * @param vecsize The size of the return `std::vector`. - * @param sizes A parameter pack of dimensions. - * @throw std::runtime_error if the scalar is less than the - * specified lower bound - */ - template * = nullptr> - auto read_ub(const std::vector& ub, size_t vecsize, Sizes... sizes) { - std::decay_t ret; - ret.reserve(vecsize); - for (size_t i = 0; i < vecsize; ++i) { - ret.emplace_back(this->read_ub>(ub[i], sizes...)); - } - return ret; - } - /** * Return the next object transformed to have the specified * upper bound, possibly incrementing the specified reference with the @@ -535,7 +366,7 @@ class deserializer { */ template - auto read_ub(const UB& ub, LP& lp, Sizes... sizes) { + inline auto read_ub(const UB& ub, LP& lp, Sizes... sizes) { if (Jacobian) { return stan::math::ub_constrain(this->read(sizes...), ub, lp); } else { @@ -543,143 +374,6 @@ class deserializer { } } - /** - * Return the next object, checking that it's elements is between - * the specified lower and upper bound. - * - *

See stan::math::check_bounded(T, LB, UB). - * - * @tparam Ret The type to return. - * @tparam LB Type of lower bound. - * @tparam UB Type of upper bound. - * @tparam Sizes A parameter pack of integral types. - * @param lb Lower bound. - * @param ub Upper bound. - * @param sizes The dimensions for the inner type. - * @throw std::runtime_error if the scalar is not between the specified - * lower and upper bounds. - */ - template * = nullptr> - auto read_lub(const LB& lb, const UB& ub, Sizes... sizes) { - auto ret = this->read(sizes...); - using stan::math::check_bounded; - using stan::math::value_of; - check_bounded( - "io deserializer", "Upper and Lower Bound", value_of(ret), value_of(lb), - value_of(ub)); - return ret; - } - - /** - * Specialization for `lub` constrain with an `std::vector` return type - * and non-`std::vector` lower and upper bounds. - * - * @tparam Ret The type to return. - * @tparam LB Type of lower bound. - * @tparam UB Type of upper bound. - * @tparam Sizes A parameter pack of integral types. - * @param lb Lower bound. - * @param ub Upper bound. - * @param vecsize The size of the return `std::vector` - * @param sizes The dimensions for the inner type. - * @throw std::runtime_error if the scalar is not between the specified - * lower and upper bounds. - */ - template * = nullptr> - auto read_lub(const LB& lb, const UB& ub, size_t vecsize, Sizes... sizes) { - std::decay_t ret; - ret.reserve(vecsize); - for (size_t i = 0; i < vecsize; ++i) { - ret.emplace_back(this->read_lub>(lb, ub, sizes...)); - } - return ret; - } - - /** - * Specialization for `lub` constrain with an `std::vector` return type - * with `std::vector` lower bound and non-`std::vector` upper bound. - * - * @tparam Ret The type to return. - * @tparam LB Type of lower bound. - * @tparam UB Type of upper bound. - * @tparam Sizes A parameter pack of integral types. - * @param lb Lower bound. - * @param ub Upper bound. - * @param vecsize The size of the return `std::vector` - * @param sizes The dimensions for the inner type. - * @throw std::runtime_error if the scalar is not between the specified - * lower and upper bounds. - */ - template * = nullptr> - auto read_lub(const std::vector& lb, const UB& ub, size_t vecsize, - Sizes... sizes) { - std::decay_t ret; - ret.reserve(vecsize); - for (size_t i = 0; i < vecsize; ++i) { - ret.emplace_back(this->read_lub>(lb[i], ub, sizes...)); - } - return ret; - } - - /** - * Specialization for `lub` constrain with an `std::vector` return type - * with a non-`std::vector` lower bound and an `std::vector` upper bound. - * - * @tparam Ret The type to return. - * @tparam LB Type of lower bound. - * @tparam UB Type of upper bound. - * @tparam Sizes A parameter pack of integral types. - * @param lb Lower bound. - * @param ub Upper bound. - * @param vecsize The size of the return `std::vector` - * @param sizes The dimensions for the inner type. - * @throw std::runtime_error if the scalar is not between the specified - * lower and upper bounds. - */ - template * = nullptr> - auto read_lub(const LB& lb, const std::vector& ub, size_t vecsize, - Sizes... sizes) { - std::decay_t ret; - ret.reserve(vecsize); - for (size_t i = 0; i < vecsize; ++i) { - ret.emplace_back(this->read_lub>(lb, ub[i], sizes...)); - } - return ret; - } - - /** - * Specialization for `lub` constrain with an `std::vector` return type - * with `std::vector` lower bound and upper bound. - * - * @tparam Ret The type to return. - * @tparam LB Type of lower bound. - * @tparam UB Type of upper bound. - * @tparam Sizes A parameter pack of integral types. - * @param lb Lower bound. - * @param ub Upper bound. - * @param vecsize The size of the return `std::vector` - * @param sizes The dimensions for the inner type. - * @throw std::runtime_error if the scalar is not between the specified - * lower and upper bounds. - */ - template * = nullptr> - auto read_lub(const std::vector& lb, const std::vector& ub, - size_t vecsize, Sizes... sizes) { - std::decay_t ret; - ret.reserve(vecsize); - for (size_t i = 0; i < vecsize; ++i) { - ret.emplace_back( - this->read_lub>(lb[i], ub[i], sizes...)); - } - return ret; - } - /** * Return the next object transformed to be between the * the specified lower and upper bounds. @@ -700,7 +394,7 @@ class deserializer { */ template - auto read_lub(const LB& lb, const UB& ub, LP& lp, Sizes... sizes) { + inline auto read_lub(const LB& lb, const UB& ub, LP& lp, Sizes... sizes) { if (Jacobian) { return stan::math::lub_constrain(this->read(sizes...), lb, ub, lp); } else { @@ -708,26 +402,6 @@ class deserializer { } } - /** - * Return the next object, checking that it's elements are positive. - * - *

See stan::math::check_positive(T). - * - * @tparam Ret The type to return. - * @tparam Sizes A parameter pack of integral types. - * @param sizes Pack of integrals to use to construct the return's type. - * - * @throw std::runtime_error if x is not positive - */ - template - auto read_pos(Sizes... sizes) { - auto ret = read(sizes...); - using stan::math::check_positive; - using stan::math::value_of; - check_positive("deserializer", "Positive Constrained", value_of(ret)); - return ret; - } - /** * Return the next object transformed to be positive, possibly * incrementing the specified reference with the log absolute @@ -745,7 +419,7 @@ class deserializer { */ template * = nullptr> - auto read_pos(LP& lp, Sizes... sizes) { + inline auto read_pos(LP& lp, Sizes... sizes) { if (Jacobian) { return stan::math::positive_constrain(this->read(sizes...), lp); } else { @@ -767,7 +441,7 @@ class deserializer { */ template * = nullptr> - auto read_pos(LP& lp, const size_t vecsize, Sizes... sizes) { + inline auto read_pos(LP& lp, size_t vecsize, Sizes... sizes) { std::decay_t ret; ret.reserve(vecsize); for (size_t i = 0; i < vecsize; ++i) { @@ -777,24 +451,6 @@ class deserializer { return ret; } - /** - * This is just returns the requested type as there's nothing to check. - * @tparam Ret The type to return. - * @tparam Jacobian Whether to increment the log of the absolute Jacobian - * determinant of the transform. - * @tparam Offset Type of offset. - * @tparam Mult Type of multiplier. - * @tparam Sizes A parameter pack of integral types. - * @param offset Offset. - * @param multiplier Multiplier. - * @param sizes Pack of integrals to use to construct the return's type. - */ - template - auto read_offset_multiplier(const Offset& offset, const Mult& multiplier, - Sizes... sizes) { - return read(sizes...); - } - /** * Return the next object transformed to have the specified offset and * multiplier. @@ -819,8 +475,9 @@ class deserializer { template * = nullptr> - auto read_offset_multiplier(const Offset& offset, const Mult& multiplier, - LP& lp, Sizes... sizes) { + inline auto read_offset_multiplier(const Offset& offset, + const Mult& multiplier, LP& lp, + Sizes... sizes) { using stan::math::offset_multiplier_constrain; if (Jacobian) { return offset_multiplier_constrain(this->read(sizes...), offset, @@ -855,8 +512,9 @@ class deserializer { template * = nullptr> - auto read_offset_multiplier(const Offset& offset, const Mult& multiplier, - LP& lp, const size_t vecsize, Sizes... sizes) { + inline auto read_offset_multiplier(const Offset& offset, + const Mult& multiplier, LP& lp, + const size_t vecsize, Sizes... sizes) { std::decay_t ret; ret.reserve(vecsize); for (size_t i = 0; i < vecsize; ++i) { @@ -891,9 +549,10 @@ class deserializer { template * = nullptr> - auto read_offset_multiplier(const std::vector& offset, - const std::vector& multiplier, LP& lp, - const size_t vecsize, Sizes... sizes) { + inline auto read_offset_multiplier(const std::vector& offset, + const std::vector& multiplier, + LP& lp, const size_t vecsize, + Sizes... sizes) { std::decay_t ret; ret.reserve(vecsize); for (size_t i = 0; i < vecsize; ++i) { @@ -928,9 +587,9 @@ class deserializer { template * = nullptr> - auto read_offset_multiplier(const std::vector& offset, - const Mult& multiplier, LP& lp, - const size_t vecsize, Sizes... sizes) { + inline auto read_offset_multiplier(const std::vector& offset, + const Mult& multiplier, LP& lp, + const size_t vecsize, Sizes... sizes) { std::decay_t ret; ret.reserve(vecsize); for (size_t i = 0; i < vecsize; ++i) { @@ -965,9 +624,10 @@ class deserializer { template * = nullptr> - auto read_offset_multiplier(const Offset& offset, - const std::vector& multiplier, LP& lp, - const size_t vecsize, Sizes... sizes) { + inline auto read_offset_multiplier(const Offset& offset, + const std::vector& multiplier, + LP& lp, const size_t vecsize, + Sizes... sizes) { std::decay_t ret; ret.reserve(vecsize); for (size_t i = 0; i < vecsize; ++i) { @@ -978,27 +638,6 @@ class deserializer { return ret; } - /** - * Return the next object, checking that it is a valid value for - * a probability, between 0 (inclusive) and 1 (inclusive). - * - *

See stan::math::check_bounded(T). - * - * @tparam Ret The type to return. - * @tparam Sizes A parameter pack of integral types. - * @param sizes Pack of integrals to use to construct the return's type. - * @return Next probability value. - */ - template - auto read_prob(Sizes... sizes) { - auto ret = read(sizes...); - using stan::math::check_bounded; - using stan::math::value_of; - check_bounded( - "deserializer", "Constrained probability", value_of(ret), 0, 1); - return ret; - } - /** * Return the next object transformed to be a probability * between 0 and 1, incrementing the specified reference with @@ -1017,7 +656,7 @@ class deserializer { */ template * = nullptr> - auto read_prob(LP& lp, Sizes... sizes) { + inline auto read_prob(LP& lp, Sizes... sizes) { if (Jacobian) { return stan::math::prob_constrain(this->read(sizes...), lp); } else { @@ -1041,7 +680,7 @@ class deserializer { */ template * = nullptr> - auto read_prob(LP& lp, const size_t vecsize, Sizes... sizes) { + inline auto read_prob(LP& lp, const size_t vecsize, Sizes... sizes) { std::decay_t ret; ret.reserve(vecsize); for (size_t i = 0; i < vecsize; ++i) { @@ -1051,69 +690,6 @@ class deserializer { return ret; } - /** - * Return the next object, checking that it is a valid - * value for a correlation, between -1 (inclusive) and - * 1 (inclusive). - * - *

See stan::math::check_bounded(T). - * - * @tparam Ret The type to return. - * @tparam Sizes A parameter pack of integral types. - * @param sizes Pack of integrals to use to construct the return's type. - * @return Next correlation value. - * @throw std::runtime_error if the value is not valid - * for a correlation - */ - template * = nullptr, - require_not_std_vector_t* = nullptr> - auto read_corr(Sizes... sizes) { - auto ret = read(sizes...); - using stan::math::check_bounded; - using stan::math::value_of; - check_bounded( - "deserializer", "Correlation value", value_of(ret), -1, 1); - return ret; - } - - /** - * Specialization of `read_corr` for `std::vector` returns - * @tparam Ret The type to return. - * @tparam Sizes A parameter pack of integral types. - * @param sizes Pack of integrals to use to construct the return's type. - * @return Next correlation value. - * @throw std::runtime_error if the value is not valid - * for a correlation - */ - template * = nullptr> - auto read_corr(size_t vecsize, Sizes... sizes) { - std::decay_t ret; - ret.reserve(vecsize); - for (size_t i = 0; i < vecsize; ++i) { - ret.emplace_back(this->read_corr>(sizes...)); - } - return ret; - } - - /** - * Specialization of `read_corr` for matrix returns - * @tparam Ret The type to return. - * @param k the rows and column size of the return matrix. - * @throw std::runtime_error if the value is not valid - * for a correlation - */ - template * = nullptr> - auto read_corr(size_t k) { - auto ret = read(k, k); - using stan::math::check_corr_matrix; - using stan::math::value_of; - check_corr_matrix("stan::math::corr_matrix", "Constrained matrix", - value_of(ret)); - return ret; - } - /** * Return the next object transformed to be a (partial) * correlation between -1 and 1, incrementing the specified @@ -1134,7 +710,7 @@ class deserializer { template * = nullptr, require_not_matrix_t* = nullptr> - auto read_corr(LP& lp, Sizes... sizes) { + inline auto read_corr(LP& lp, Sizes... sizes) { using stan::math::corr_constrain; if (Jacobian) { return corr_constrain(this->read(sizes...), lp); @@ -1161,7 +737,7 @@ class deserializer { template * = nullptr, require_matrix_t* = nullptr> - auto read_corr(LP& lp, size_t k) { + inline auto read_corr(LP& lp, Eigen::Index k) { using stan::math::corr_matrix_constrain; if (Jacobian) { return corr_matrix_constrain( @@ -1192,7 +768,7 @@ class deserializer { */ template * = nullptr> - auto read_corr(LP& lp, const size_t vecsize, Sizes... sizes) { + inline auto read_corr(LP& lp, const size_t vecsize, Sizes... sizes) { std::decay_t ret; ret.reserve(vecsize); for (size_t i = 0; i < vecsize; ++i) { @@ -1202,57 +778,6 @@ class deserializer { return ret; } - /** - * Return a unit_vector of the specified size made up of the - * next scalars. - * - *

See stan::math::check_unit_vector. - * - * @tparam Ret The type to return. - * @param k Size of returned unit_vector - * @return unit_vector read from the specified size number of scalars - * @throw std::runtime_error if the next k values is not a unit_vector - * @throw std::invalid_argument if k is zero - */ - template * = nullptr> - auto read_unit_vector(size_t k) { - if (unlikely(k == 0)) { - []() STAN_COLD_PATH { - std::string msg = "deserializer: unit vectors cannot be size 0."; - throw std::invalid_argument(msg); - }(); - } - auto ret = read(k); - using stan::math::check_unit_vector; - using stan::math::value_of; - check_unit_vector("deserializer", "Unit Vector", value_of(ret)); - return ret; - } - - /** - * Specialization of `read_unit_vector` for an `std::vector` of unit vectors. - * - *

See stan::math::check_unit_vector. - * - * @tparam Ret The type to return. - * @tparam Sizes A parameter pack of integral types. - * @param sizes Pack of integrals to use to construct the return's type. - * @param vecsize The size of the return vector. - * @return unit_vector read from the specified size number of scalars - * @throw std::runtime_error if the next k values is not a unit_vector - * @throw std::invalid_argument if k is zero - */ - template * = nullptr> - auto read_unit_vector(size_t vecsize, Sizes... sizes) { - std::decay_t ret; - ret.reserve(vecsize); - for (size_t i = 0; i < vecsize; ++i) { - ret.emplace_back(this->read_unit_vector>(sizes...)); - } - return ret; - } - /** * Return the next unit_vector of the specified size (using one fewer * unconstrained scalars), incrementing the specified reference with the @@ -1273,7 +798,7 @@ class deserializer { */ template * = nullptr> - auto read_unit_vector(LP& lp, Sizes... sizes) { + inline auto read_unit_vector(LP& lp, Sizes... sizes) { using stan::math::unit_vector_constrain; if (Jacobian) { return unit_vector_constrain(this->read(sizes...), lp); @@ -1303,7 +828,7 @@ class deserializer { */ template * = nullptr> - auto read_unit_vector(LP& lp, const size_t vecsize, Sizes... sizes) { + inline auto read_unit_vector(LP& lp, const size_t vecsize, Sizes... sizes) { std::decay_t ret; ret.reserve(vecsize); for (size_t i = 0; i < vecsize; ++i) { @@ -1313,60 +838,6 @@ class deserializer { return ret; } - /** - * Return a simplex of the specified size made up of the - * next scalars. - * - *

See stan::math::check_simplex. - * - * @tparam Ret The type to return. - * @param k Size of returned simplex. - * @return Simplex read from the specified size number of scalars. - * @throw std::runtime_error if the k values is not a simplex. - * @throw std::invalid_argument if k is zero - */ - template * = nullptr, - require_not_std_vector_t* = nullptr> - auto read_simplex(size_t k) { - if (unlikely(k == 0)) { - []() STAN_COLD_PATH { - std::string msg = "deserializer: simplex vectors cannot be size 0."; - throw std::invalid_argument(msg); - }(); - } - auto ret = read(k); - using stan::math::check_simplex; - using stan::math::value_of; - check_simplex("deserializer", "Simplex", value_of(ret)); - return ret; - } - - /** - * Return a simplex of the specified size made up of the - * next scalars. - * - *

See stan::math::check_simplex. - * - * @tparam Ret The type to return. - * @tparam Sizes A parameter pack of integral types. - * @param vecsize The size of the return vector. - * @param sizes Pack of integrals to use to construct the return's type. - * probability to increment. - * @return Simplex read from the specified size number of scalars. - * @throw std::runtime_error if the k values is not a simplex. - * @throw std::invalid_argument if k is zero - */ - template * = nullptr> - auto read_simplex(size_t vecsize, Sizes... sizes) { - std::decay_t ret; - ret.reserve(vecsize); - for (size_t i = 0; i < vecsize; ++i) { - ret.emplace_back(this->read_simplex>(sizes...)); - } - return ret; - } - /** * Return the next simplex of the specified size (using one fewer * unconstrained scalars), incrementing the specified reference with the @@ -1387,7 +858,7 @@ class deserializer { */ template * = nullptr> - auto read_simplex(LP& lp, Sizes... sizes) { + inline auto read_simplex(LP& lp, Sizes... sizes) { using stan::math::simplex_constrain; if (Jacobian) { return simplex_constrain(this->read(sizes...), lp); @@ -1417,7 +888,7 @@ class deserializer { */ template * = nullptr> - auto read_simplex(LP& lp, const size_t vecsize, Sizes... sizes) { + inline auto read_simplex(LP& lp, const size_t vecsize, Sizes... sizes) { std::decay_t ret; ret.reserve(vecsize); for (size_t i = 0; i < vecsize; ++i) { @@ -1427,54 +898,6 @@ class deserializer { return ret; } - /** - * Return the next vector of specified size containing - * values in ascending order. - * - *

See stan::math::check_ordered(T) for - * behavior on failure. - * - * @tparam Ret The type to return. - * @tparam Sizes A parameter pack of integral types. - * @param sizes Pack of integrals to use to construct the return's type. - * probability to increment. - * @return Vector of positive values in ascending order. - */ - template * = nullptr> - auto read_ordered(Sizes... sizes) { - auto ret = read(sizes...); - using stan::math::check_ordered; - using stan::math::value_of; - check_ordered("deserializer", "Ordered", value_of(ret)); - return ret; - } - - /** - * Return the next vector of specified size containing - * values in ascending order. - * - *

See stan::math::check_ordered(T) for - * behavior on failure. - * - * @tparam Ret The type to return. - * @tparam Sizes A parameter pack of integral types. - * @param vecsize The size of the return vector. - * @param sizes Pack of integrals to use to construct the return's type. - * probability to increment. - * @return Vector of positive values in ascending order. - */ - template * = nullptr> - auto read_ordered(size_t vecsize, Sizes... sizes) { - std::decay_t ret; - ret.reserve(vecsize); - for (size_t i = 0; i < vecsize; ++i) { - ret.emplace_back(this->read_ordered>(sizes...)); - } - return ret; - } - /** * Return the next ordered vector of the specified * size, incrementing the specified reference with the log @@ -1494,7 +917,7 @@ class deserializer { */ template * = nullptr> - auto read_ordered(LP& lp, Sizes... sizes) { + inline auto read_ordered(LP& lp, Sizes... sizes) { using stan::math::ordered_constrain; if (Jacobian) { return ordered_constrain(this->read(sizes...), lp); @@ -1523,7 +946,7 @@ class deserializer { */ template * = nullptr> - auto read_ordered(LP& lp, const size_t vecsize, Sizes... sizes) { + inline auto read_ordered(LP& lp, const size_t vecsize, Sizes... sizes) { std::decay_t ret; ret.reserve(vecsize); for (size_t i = 0; i < vecsize; ++i) { @@ -1533,55 +956,6 @@ class deserializer { return ret; } - /** - * Return the next vector of specified size containing - * positive values in ascending order. - * - *

See stan::math::check_positive_ordered(T) for - * behavior on failure. - * - * @tparam Ret The type to return. - * @tparam Sizes A parameter pack of integral types. - * @param sizes Pack of integrals to use to construct the return's type. - * probability to increment. - * @return Vector of positive values in ascending order. - */ - template * = nullptr> - auto read_positive_ordered(Sizes... sizes) { - auto ret = read(sizes...); - using stan::math::check_positive_ordered; - using stan::math::value_of; - check_positive_ordered("deserializer", "Positive Ordered", value_of(ret)); - return ret; - } - - /** - * Return the next vector of specified size containing - * positive values in ascending order. - * - *

See stan::math::check_positive_ordered(T) for - * behavior on failure. - * - * @tparam Ret The type to return. - * @tparam Sizes A parameter pack of integral types. - * @param vecsize The size of the return vector. - * @param sizes Pack of integrals to use to construct the return's type. - * probability to increment. - * @return Vector of positive values in ascending order. - */ - template * = nullptr> - auto read_positive_ordered(size_t vecsize, Sizes... sizes) { - std::decay_t ret; - ret.reserve(vecsize); - for (size_t i = 0; i < vecsize; ++i) { - ret.emplace_back( - this->read_positive_ordered>(sizes...)); - } - return ret; - } - /** * Return the next positive_ordered vector of the specified * size, incrementing the specified reference with the log @@ -1602,7 +976,7 @@ class deserializer { */ template * = nullptr> - auto read_positive_ordered(LP& lp, Sizes... sizes) { + inline auto read_positive_ordered(LP& lp, Sizes... sizes) { using stan::math::positive_ordered_constrain; if (Jacobian) { return positive_ordered_constrain(this->read(sizes...), lp); @@ -1631,7 +1005,8 @@ class deserializer { */ template * = nullptr> - auto read_positive_ordered(LP& lp, const size_t vecsize, Sizes... sizes) { + inline auto read_positive_ordered(LP& lp, const size_t vecsize, + Sizes... sizes) { std::decay_t ret; ret.reserve(vecsize); for (size_t i = 0; i < vecsize; ++i) { @@ -1641,51 +1016,6 @@ class deserializer { return ret; } - /** - * Return the next Cholesky factor with the specified - * dimensionality, reading it directly without transforms. - * - * @tparam Ret The type to return. - * @param M Rows of Cholesky factor - * @param N Columns of Cholesky factor - * @return Next Cholesky factor. - * @throw std::domain_error if the matrix is not a valid - * Cholesky factor. - */ - template * = nullptr> - auto read_cholesky_factor_cov(size_t M, size_t N) { - auto ret = read(M, N); - using stan::math::check_cholesky_factor; - using stan::math::value_of; - check_cholesky_factor("deserializer", "Cholesky Factor Cov", value_of(ret)); - return ret; - } - - /** - * Return the next Cholesky factor with the specified - * dimensionality, reading it directly without transforms. - * - * @tparam Ret The type to return. - * @tparam Sizes A parameter pack of integral types. - * @param vecsize The size of the return vector. - * @param sizes Pack of integrals to use to construct the return's type. - * probability to increment. - * @return Next Cholesky factor. - * @throw std::domain_error if the matrix is not a valid - * Cholesky factor. - */ - template * = nullptr> - auto read_cholesky_factor_cov(size_t vecsize, Sizes... sizes) { - std::decay_t ret; - ret.reserve(vecsize); - for (size_t i = 0; i < vecsize; ++i) { - ret.emplace_back( - this->read_cholesky_factor_cov>(sizes...)); - } - return ret; - } - /** * Return the next Cholesky factor with the specified * dimensionality, reading from an unconstrained vector of the @@ -1705,7 +1035,7 @@ class deserializer { */ template * = nullptr> - auto read_cholesky_factor_cov(LP& lp, size_t M, size_t N) { + inline auto read_cholesky_factor_cov(LP& lp, Eigen::Index M, Eigen::Index N) { if (Jacobian) { return stan::math::cholesky_factor_constrain( this->read>((N * (N + 1)) / 2 @@ -1740,7 +1070,8 @@ class deserializer { */ template * = nullptr> - auto read_cholesky_factor_cov(LP& lp, const size_t vecsize, Sizes... sizes) { + inline auto read_cholesky_factor_cov(LP& lp, const size_t vecsize, + Sizes... sizes) { std::decay_t ret; ret.reserve(vecsize); for (size_t i = 0; i < vecsize; ++i) { @@ -1751,51 +1082,6 @@ class deserializer { return ret; } - /** - * Return the next Cholesky factor for a correlation matrix with - * the specified dimensionality, reading it directly without - * transforms. - * - * @param K Rows and columns of Cholesky factor - * @return Next Cholesky factor for a correlation matrix. - * @throw std::domain_error if the matrix is not a valid - * Cholesky factor for a correlation matrix. - */ - template * = nullptr> - auto read_cholesky_factor_corr(size_t K) { - auto ret = read(K, K); - using stan::math::check_cholesky_factor_corr; - using stan::math::value_of; - check_cholesky_factor_corr("deserializer", "Cholesky Factor Corr Matrix", - value_of(ret)); - return ret; - } - - /** - * Return the next Cholesky factor for a correlation matrix with - * the specified dimensionality, reading it directly without - * transforms. - * - * @tparam Ret The type to return. - * @tparam Sizes A parameter pack of integral types. - * @param vecsize The size of the return vector. - * @param sizes Pack of integrals to use to construct the return's type. - * probability to increment. - * @return Next Cholesky factor for a correlation matrix. - * @throw std::domain_error if the matrix is not a valid - * Cholesky factor for a correlation matrix. - */ - template * = nullptr> - auto read_cholesky_factor_corr(size_t vecsize, Sizes... sizes) { - std::decay_t ret; - for (size_t i = 0; i < vecsize; ++i) { - ret.emplace_back( - this->read_cholesky_factor_corr>(sizes...)); - } - return ret; - } - /** * Return the next Cholesky factor for a correlation matrix with * the specified dimensionality, reading from an unconstrained @@ -1815,7 +1101,7 @@ class deserializer { */ template * = nullptr> - auto read_cholesky_factor_corr(LP& lp, size_t K) { + inline auto read_cholesky_factor_corr(LP& lp, Eigen::Index K) { using stan::math::cholesky_corr_constrain; if (Jacobian) { return cholesky_corr_constrain( @@ -1850,7 +1136,8 @@ class deserializer { */ template * = nullptr> - auto read_cholesky_factor_corr(LP& lp, const size_t vecsize, Sizes... sizes) { + inline auto read_cholesky_factor_corr(LP& lp, const size_t vecsize, + Sizes... sizes) { std::decay_t ret; ret.reserve(vecsize); for (size_t i = 0; i < vecsize; ++i) { @@ -1861,54 +1148,6 @@ class deserializer { return ret; } - /** - * Return the next covariance matrix with the specified - * dimensionality. - * - *

See stan::math::check_cov_matrix(Matrix). - * - * @tparam Ret The type to return. - * @param k Dimensionality of covariance matrix. - * @return Next covariance matrix of the specified dimensionality. - * @throw std::runtime_error if the matrix is not a valid - * covariance matrix - */ - template * = nullptr> - auto read_cov_matrix(size_t k) { - auto ret = read(k, k); - using stan::math::check_cov_matrix; - using stan::math::value_of; - check_cov_matrix("stan::io::cov_matrix", "Constrained matrix", - value_of(ret)); - return ret; - } - - /** - * Return the next covariance matrix with the specified - * dimensionality. - * - *

See stan::math::check_cov_matrix(Matrix). - * - * @tparam Ret The type to return. - * @tparam Sizes A parameter pack of integral types. - * @param vecsize The size of the return vector. - * @param sizes Pack of integrals to use to construct the return's type. - * probability to increment. - * @return Next covariance matrix of the specified dimensionality. - * @throw std::runtime_error if the matrix is not a valid - * covariance matrix - */ - template * = nullptr> - auto read_cov_matrix(size_t vecsize, Sizes... sizes) { - std::decay_t ret; - ret.reserve(vecsize); - for (size_t i = 0; i < vecsize; ++i) { - ret.emplace_back(this->read_cov_matrix>(sizes...)); - } - return ret; - } - /** * Return the next covariance matrix of the specified dimensionality, * incrementing the specified reference with the log absolute Jacobian @@ -1926,7 +1165,7 @@ class deserializer { */ template * = nullptr> - auto read_cov_matrix(LP& lp, size_t k) { + inline auto read_cov_matrix(LP& lp, Eigen::Index k) { using stan::math::cov_matrix_constrain; if (Jacobian) { return cov_matrix_constrain( diff --git a/src/test/unit/io/deserializer_stdvector_test.cpp b/src/test/unit/io/deserializer_stdvector_test.cpp index 077ef69166b..5b932b98740 100644 --- a/src/test/unit/io/deserializer_stdvector_test.cpp +++ b/src/test/unit/io/deserializer_stdvector_test.cpp @@ -80,28 +80,6 @@ TEST(deserializer_stdvec_scalar, read) { EXPECT_EQ(0U, deserializer.available()); } -TEST(deserializer_stdvec_scalar, read_lb) { - std::vector theta_i; - std::vector theta; - theta.push_back(-1.0); - theta.push_back(2.0); - stan::io::deserializer deserializer(theta, theta_i); - auto x = deserializer.read_lb>( - std::vector{-2.0, 1.0}, 2); - EXPECT_FLOAT_EQ(-1.0, x[0]); - EXPECT_FLOAT_EQ(2.0, x[1]); - EXPECT_EQ(0U, deserializer.available()); -} -TEST(deserializer_stdvec_scalar, read_lb_exception) { - std::vector theta_i; - std::vector theta; - theta.push_back(-1.0); - theta.push_back(2.0); - stan::io::deserializer deserializer(theta, theta_i); - EXPECT_NO_THROW(deserializer.read_lb>(-1.0, 2)); - EXPECT_THROW(deserializer.read_lb>(3.0, 2), - std::runtime_error); -} TEST(deserializer_stdvec_scalar, read_lb_constrain) { std::vector theta_i; std::vector theta; @@ -138,27 +116,6 @@ TEST(deserializer_stdvec_scalar, read_lb_constrain_jacobian) { // ub -TEST(deserializer_stdvec_scalar, read_ub) { - std::vector theta_i; - std::vector theta; - theta.push_back(-1.0); - theta.push_back(3.0); - stan::io::deserializer deserializer(theta, theta_i); - auto x = deserializer.read_ub>(3.0, 2); - EXPECT_FLOAT_EQ(-1.0, x[0]); - EXPECT_FLOAT_EQ(3.0, x[1]); - EXPECT_EQ(0U, deserializer.available()); -} -TEST(deserializer_stdvec_scalar, read_ub_exception) { - std::vector theta_i; - std::vector theta; - theta.push_back(-1.0); - theta.push_back(2.0); - stan::io::deserializer deserializer(theta, theta_i); - EXPECT_NO_THROW(deserializer.read_ub>(3.0, 2)); - EXPECT_THROW(deserializer.read_ub>(1.0, 2), - std::runtime_error); -} TEST(deserializer_stdvec_scalar, read_ub_constrain) { std::vector theta_i; std::vector theta; @@ -195,28 +152,6 @@ TEST(deserializer_stdvec_scalar, read_ub_constrain_jacobian) { // lub -TEST(deserializer_stdvec_scalar, read_lub) { - std::vector theta_i; - std::vector theta; - theta.push_back(-1.0); - theta.push_back(2.0); - stan::io::deserializer deserializer(theta, theta_i); - auto x = deserializer.read_lub>(-3.0, 3.0, 2); - EXPECT_FLOAT_EQ(-1.0, x[0]); - EXPECT_FLOAT_EQ(2.0, x[1]); - - EXPECT_EQ(0U, deserializer.available()); -} -TEST(deserializer_stdvec_scalar, read_lub_exception) { - std::vector theta_i; - std::vector theta; - theta.push_back(-1.0); - theta.push_back(2.0); - stan::io::deserializer deserializer(theta, theta_i); - EXPECT_NO_THROW(deserializer.read_lub>(-2.0, 2.0, 2)); - EXPECT_THROW(deserializer.read_lub>(-1.0, 1.0, 2), - std::runtime_error); -} const double inv_logit_m2 = 0.1192029; // stan::math::inv_logit(-2.0) const double inv_logit_m1 = 0.2689414; // stan::math::inv_logit(-1.0) const double inv_logit_0 = 0.5; // stan::math::inv_logit(0) @@ -265,33 +200,6 @@ TEST(deserializer_stdvec_scalar, read_lub_constrain_jacobian) { // offset multiplier -TEST(deserializer_stdvec_scalar, read_offset_multiplier) { - std::vector theta_i; - std::vector theta; - theta.push_back(-1.0); - theta.push_back(2.0); - stan::io::deserializer deserializer(theta, theta_i); - auto x - = deserializer.read_offset_multiplier>(-3.0, 3.0, 2); - EXPECT_FLOAT_EQ(-1.0, x[0]); - EXPECT_FLOAT_EQ(2.0, x[1]); - - EXPECT_EQ(0U, deserializer.available()); -} -TEST(deserializer_stdvec_scalar, offset_multiplier_exception) { - std::vector theta_i; - std::vector theta; - theta.push_back(-1.0); - theta.push_back(2.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = 0; - EXPECT_NO_THROW( - deserializer.read_offset_multiplier>(-2.0, -2.0, 2)); - EXPECT_THROW((deserializer.read_offset_multiplier, false>( - -2.0, -2.0, lp, 2)), - std::runtime_error); -} - TEST(deserializer_stdvec_scalar, offset_multiplier_constrain) { std::vector theta_i; std::vector theta; @@ -333,20 +241,6 @@ TEST(deserializer_stdvec_scalar, offset_multiplier_constrain_jacobian) { // prob -TEST(deserializer_stdvec_scalar, prob) { - std::vector theta_i; - std::vector theta; - theta.push_back(0.9); - theta.push_back(0.1); - theta.push_back(0.0); - stan::io::deserializer deserializer(theta, theta_i); - auto p1 = deserializer.read_prob>(3); - EXPECT_FLOAT_EQ(0.9, p1[0]); - EXPECT_FLOAT_EQ(0.1, p1[1]); - EXPECT_FLOAT_EQ(0.0, p1[2]); - EXPECT_EQ(0U, deserializer.available()); -} - TEST(deserializer_stdvec_scalar, prob_constrain) { std::vector theta_i; std::vector theta; @@ -386,31 +280,6 @@ TEST(deserializer_stdvec_scalar, prob_constrain_jacobian) { // corr -TEST(deserializer_stdvec_scalar, corr) { - std::vector theta_i; - std::vector theta; - theta.push_back(-0.9); - theta.push_back(0.1); - theta.push_back(0.0); - stan::io::deserializer deserializer(theta, theta_i); - auto rho1 = deserializer.read_corr>(3); - EXPECT_FLOAT_EQ(-0.9, rho1[0]); - EXPECT_FLOAT_EQ(0.1, rho1[1]); - EXPECT_FLOAT_EQ(0.0, rho1[2]); - EXPECT_EQ(0U, deserializer.available()); -} -TEST(deserializer_stdvec_scalar, corr_exception) { - std::vector theta_i; - std::vector theta; - theta.push_back(-0.9); - theta.push_back(-1.1); - theta.push_back(1.1); - stan::io::deserializer deserializer(theta, theta_i); - double lp = 0; - EXPECT_NO_THROW((deserializer.read_corr, false>(lp, 3))); - EXPECT_THROW(deserializer.read_corr>(3), - std::runtime_error); -} TEST(deserializer_stdvec_scalar, corr_constrain) { std::vector theta_i; std::vector theta; @@ -473,101 +342,7 @@ TEST(deserializer_stdvec_vector, read) { } } -TEST(deserializer_stdvec_vector, unit_vector) { - std::vector theta_i(0); - std::vector theta(16, sqrt(0.25)); - stan::io::deserializer deserializer(theta, theta_i); - auto y = deserializer.read_unit_vector>(4, 4); - EXPECT_EQ(4, y.size()); - const double sqrt_qtr = sqrt(0.25); - for (int i = 0; i < 4; ++i) { - EXPECT_EQ(4, y[i].rows()); - EXPECT_EQ(1, y[i].cols()); - for (int j = 0; j < 4; ++j) { - EXPECT_FLOAT_EQ(sqrt_qtr, y[i][j]); - } - } -} - -TEST(deserializer_stdvec_vector, unit_vector_exception) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - theta[0] = 0.00; - theta[1] = -sqrt(0.29); - theta[2] = sqrt(0.70); - theta[3] = -sqrt(0.01); - theta[4] = sqrt(1.0); - theta[5] = sqrt(1.0); - EXPECT_NO_THROW( - deserializer.read_unit_vector>(1, 4)); - EXPECT_THROW( - deserializer.read_unit_vector>(1, 2), - std::domain_error); - EXPECT_THROW( - deserializer.read_unit_vector>(1, 0), - std::invalid_argument); -} - -TEST(deserializer_stdvec_vector, simplex) { - std::vector theta_i(0); - std::vector theta(8, 0.25); - stan::io::deserializer deserializer(theta, theta_i); - auto y = deserializer.read_simplex>(2, 4); - EXPECT_EQ(2, y.size()); - for (int i = 0; i < 2; ++i) { - EXPECT_EQ(4, y[i].rows()); - EXPECT_EQ(1, y[i].cols()); - for (int j = 0; j < 4; ++j) { - EXPECT_FLOAT_EQ(0.25, y[i][j]); - } - } -} -TEST(deserializer_stdvec_vector, simplex_exception) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - theta[0] = 0.00; - theta[1] = 0.29; - theta[2] = 0.70; - theta[3] = 0.01; - theta[4] = 0.00; - theta[5] = 0.29; - theta[6] = 0.70; - theta[7] = 0.01; - theta[8] = 1.0; - theta[9] = 1.0; - EXPECT_NO_THROW( - deserializer.read_simplex>(2, 4)); - EXPECT_THROW(deserializer.read_simplex>(2, 2), - std::domain_error); - EXPECT_THROW(deserializer.read_simplex>(2, 0), - std::invalid_argument); -} - -TEST(deserializer_stdvec_vector, ordered) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - EXPECT_FLOAT_EQ(0.0, deserializer.read()); // throw away theta[0] - auto y = deserializer.read_ordered>(5, 2); - EXPECT_EQ(5, y.size()); - double k = 1; - for (int i = 0; i < 5; ++i) { - EXPECT_EQ(2, y[i].rows()); - EXPECT_EQ(1, y[i].cols()); - for (int j = 0; j < 2; ++j) { - EXPECT_FLOAT_EQ(k, y[i][j]); - ++k; - } - } -} +// Need to add unit vector and simplex constrain/lp tests TEST(deserializer_stdvec_vector, ordered_constrain) { std::vector theta_i; @@ -629,27 +404,6 @@ TEST(deserializer_stdvec_vector, ordered_constrain_jacobian) { EXPECT_FLOAT_EQ(expected_lp, lp); } -TEST(deserializer_stdvec_vector, positive_ordered) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - EXPECT_FLOAT_EQ(0.0, deserializer.read()); // throw away theta[0] - auto y - = deserializer.read_positive_ordered>(5, 2); - EXPECT_EQ(5, y.size()); - double sentinal = 1; - for (int i = 0; i < 5; ++i) { - EXPECT_EQ(y[i].rows(), 2); - EXPECT_EQ(y[i].cols(), 1); - for (int j = 0; j < 2; ++j) { - EXPECT_FLOAT_EQ(sentinal, y[i][j]); - ++sentinal; - } - } -} - TEST(deserializer_stdvec_vector, positive_ordered_constrain) { std::vector theta_i; std::vector theta; @@ -712,28 +466,6 @@ TEST(deserializer_stdvec_vector, positive_ordered_constrain_jacobian) { EXPECT_FLOAT_EQ(expected_lp, lp); } -TEST(deserializer_stdvec_vector, offset_multiplier) { - std::vector theta_i; - std::vector theta; - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); - stan::io::deserializer deserializer(theta, theta_i); - auto phi(deserializer.read_offset_multiplier>( - 0, 1, 2, 4)); - for (int i = 0; i < 2; ++i) { - EXPECT_FLOAT_EQ(theta[0], phi[i][0]); - EXPECT_FLOAT_EQ(theta[1], phi[i][1]); - EXPECT_FLOAT_EQ(theta[2], phi[i][2]); - EXPECT_FLOAT_EQ(theta[3], phi[i][3]); - } -} - TEST(deserializer_stdvec_vector, offset_multiplier_constrain) { std::vector theta_i; std::vector theta; @@ -809,30 +541,6 @@ TEST(deserializer_stdvec_matrix, read) { } } -TEST(deserializer_stdvec_matrix, matrix_lb) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - for (int i = 0; i < 7; ++i) { - double x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - double lb = -1.5; - auto y = deserializer.read_lb>(lb, 2, 3, 2); - EXPECT_EQ(2, y.size()); - double sentinal = 7; - for (int i = 0; i < 2; ++i) { - EXPECT_EQ(3, y[i].rows()); - EXPECT_EQ(2, y[i].cols()); - for (int j = 0; j < y[i].size(); ++j) { - EXPECT_FLOAT_EQ(sentinal, y[i](j)); - ++sentinal; - } - } -} - TEST(deserializer_stdvec_matrix, matrix_lb_constrain) { std::vector theta_i; std::vector theta; @@ -885,30 +593,6 @@ TEST(deserializer_stdvec_matrix, matrix_lb_constrain_lp) { } } -TEST(deserializer_stdvec_matrix, matrix_ub) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - for (int i = 0; i < 7; ++i) { - double x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - double ub = 26.5; - auto y = deserializer.read_ub>(ub, 2, 3, 2); - EXPECT_EQ(2, y.size()); - double sentinal = 7; - for (int i = 0; i < 2; ++i) { - EXPECT_EQ(3, y[i].rows()); - EXPECT_EQ(2, y[i].cols()); - for (int j = 0; j < y[i].size(); ++j) { - EXPECT_FLOAT_EQ(sentinal, y[i](j)); - ++sentinal; - } - } -} - TEST(deserializer_stdvec_matrix, matrix_ub_constrain) { std::vector theta_i; std::vector theta; @@ -961,31 +645,6 @@ TEST(deserializer_stdvec_matrix, matrix_ub_constrain_lp) { } } -TEST(deserializer_stdvec_matrix, matrix_lub) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - for (int i = 0; i < 7; ++i) { - double x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - double lb = 6.9; - double ub = 32.5; - auto y = deserializer.read_lub>(lb, ub, 2, 3, 2); - EXPECT_EQ(2, y.size()); - double sentinal = 7; - for (int i = 0; i < 2; ++i) { - EXPECT_EQ(3, y[i].rows()); - EXPECT_EQ(2, y[i].cols()); - for (int j = 0; j < y[i].size(); ++j) { - EXPECT_FLOAT_EQ(sentinal, y[i](j)); - ++sentinal; - } - } -} - TEST(deserializer_stdvec_matrix, matrix_lub_constrain) { std::vector theta_i; std::vector theta; @@ -1040,50 +699,6 @@ TEST(deserializer_stdvec_matrix, matrix_lub_constrain_lp) { } } -TEST(deserializer_stdvec_matrix, corr_matrix) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - theta[0] = 1.0000000000000000; - theta[1] = 0.1817621852191252; - theta[2] = 0.8620926037637362; - theta[3] = 0.1817621852191252; - theta[4] = 1.0000000000000000; - theta[5] = 0.2248293054822660; - theta[6] = 0.8620926037637362; - theta[7] = 0.2248293054822660; - theta[8] = 1.0000000000000001; // allow some tolerance - theta[9] = 1.0000000000000000; - theta[10] = 0.1817621852191252; - theta[11] = 0.8620926037637362; - theta[12] = 0.1817621852191252; - theta[13] = 1.0000000000000000; - theta[14] = 0.2248293054822660; - theta[15] = 0.8620926037637362; - theta[16] = 0.2248293054822660; - theta[17] = 1.0000000000000001; // allow some tolerance - stan::io::deserializer deserializer(theta, theta_i); - auto S = deserializer.read_corr>(2, 3); - EXPECT_FLOAT_EQ(theta[0], S[0](0, 0)); -} - -TEST(deserializer_stdvec_matrix, corr_matrix_exception) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - theta[0] = 1.5; - theta[1] = 1.0; - theta[2] = 2.0; - theta[3] = 0.0; - theta[4] = 1.0; - stan::io::deserializer deserializer(theta, theta_i); - EXPECT_THROW(deserializer.read_corr>(1, 1), - std::domain_error); - EXPECT_THROW(deserializer.read_corr>(2, 3), - std::domain_error); -} TEST(deserializer_stdvec_matrix, corr_matrix_constrain) { using Eigen::Dynamic; using Eigen::Matrix; @@ -1159,52 +774,6 @@ TEST(deserializer_stdvec_matrix, corr_matrix_constrain_jacobian) { } } -TEST(deserializer_stdvec_matrix, cov_matrix) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - theta[0] = 6.3295234356180128; - theta[1] = 0.6351775806192667; - theta[2] = 3.8081029582054304; - theta[3] = 0.6351775806192667; - theta[4] = 1.9293554162496527; - theta[5] = 0.5483126868366485; - theta[6] = 3.8081029582054304; - theta[7] = 0.5483126868366485; - theta[8] = 3.0827514661973088; - theta[9] = 6.3295234356180128; - theta[10] = 0.6351775806192667; - theta[11] = 3.8081029582054304; - theta[12] = 0.6351775806192667; - theta[13] = 1.9293554162496527; - theta[14] = 0.5483126868366485; - theta[15] = 3.8081029582054304; - theta[16] = 0.5483126868366485; - theta[17] = 3.0827514661973088; - stan::io::deserializer deserializer(theta, theta_i); - auto S = deserializer.read_cov_matrix>(2, 3); - EXPECT_FLOAT_EQ(theta[0], S[0](0, 0)); - EXPECT_FLOAT_EQ(theta[1], S[0](1, 0)); - EXPECT_FLOAT_EQ(theta[7], S[0](2, 1)); - EXPECT_FLOAT_EQ(theta[8], S[0](2, 2)); -} -TEST(deserializer_stdvec_matrix, cov_matrix_exception) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - theta[0] = 6.3; - theta[1] = 0.7; - theta[2] = 0.6; - theta[3] = 1.9; - stan::io::deserializer deserializer(theta, theta_i); - EXPECT_THROW(deserializer.read_cov_matrix>(2, 2), - std::domain_error); - EXPECT_THROW(deserializer.read_cov_matrix>(2, 0), - std::invalid_argument); -} - TEST(deserializer_stdvec_matrix, cov_matrix_constrain) { std::vector theta_i; std::vector theta; @@ -1283,100 +852,6 @@ TEST(deserializer_stdvec_matrix, cov_matrix_constrain_jacobian) { } } -TEST(deserializer_stdvec_matrix, cholesky_factor_cov) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - // column major - theta[0] = 1; - theta[1] = 2; - theta[2] = 3; - - theta[3] = 0; - theta[4] = 4; - theta[5] = 5; - - theta[6] = 0; - theta[7] = 0; - theta[8] = 6; - - theta[9] = 1; - theta[10] = 2; - theta[11] = 3; - - theta[12] = 0; - theta[13] = 4; - theta[14] = 5; - - theta[15] = 0; - theta[16] = 0; - theta[17] = 6; - - stan::io::deserializer deserializer(theta, theta_i); - auto S = deserializer.read_cholesky_factor_cov>( - 2, 3, 3); - EXPECT_FLOAT_EQ(theta[0], S[0](0, 0)); - EXPECT_FLOAT_EQ(theta[1], S[0](1, 0)); - EXPECT_FLOAT_EQ(theta[7], S[0](1, 2)); - EXPECT_FLOAT_EQ(theta[8], S[0](2, 2)); -} -TEST(deserializer_stdvec_matrix, cholesky_factor_cov_asymmetric) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - // column major - theta[0] = 1; - theta[1] = 2; - theta[2] = 3; - - theta[3] = 0; - theta[4] = 4; - theta[5] = 5; - - theta[6] = 1; - theta[7] = 2; - theta[8] = 3; - - theta[9] = 0; - theta[10] = 4; - theta[11] = 5; - - stan::io::deserializer deserializer(theta, theta_i); - auto S = deserializer.read_cholesky_factor_cov>( - 2, 3, 2); - EXPECT_FLOAT_EQ(theta[0], S[0](0, 0)); - EXPECT_FLOAT_EQ(theta[1], S[0](1, 0)); - EXPECT_FLOAT_EQ(theta[2], S[0](2, 0)); - - EXPECT_FLOAT_EQ(theta[3], S[0](0, 1)); - EXPECT_FLOAT_EQ(theta[4], S[0](1, 1)); - EXPECT_FLOAT_EQ(theta[5], S[0](2, 1)); -} - -TEST(deserializer_stdvec_matrix, cholesky_factor_cov_exception) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - theta[0] = -6.3; - stan::io::deserializer deserializer(theta, theta_i); - EXPECT_THROW( - deserializer.read_cholesky_factor_cov>(2, 2, - 2), - std::domain_error); - EXPECT_THROW( - deserializer.read_cholesky_factor_cov>(2, 0, - 0), - std::domain_error); - - theta[0] = 1; - EXPECT_THROW( - deserializer.read_cholesky_factor_cov>(2, 2, - 3), - std::domain_error); -} TEST(deserializer_stdvec_matrix, cholesky_factor_cov_constrain) { std::vector theta_i; std::vector theta; @@ -1454,78 +929,6 @@ TEST(deserializer_stdvec_matrix, lp); } -TEST(deserializer_stdvec_matrix, cholesky_factor_corr) { - std::vector theta_i; - std::vector theta(18); - // column major - theta[0] = 1; - theta[1] = 0; - theta[2] = 0; - - theta[3] = 0; - theta[4] = 1; - theta[5] = 0; - - theta[6] = 0; - theta[7] = 0; - theta[8] = 1; - theta[9] = 1; - theta[10] = 0; - theta[11] = 0; - - theta[12] = 0; - theta[13] = 1; - theta[14] = 0; - - theta[15] = 0; - theta[16] = 0; - theta[17] = 1; - - stan::io::deserializer deserializer(theta, theta_i); - auto S = deserializer.read_cholesky_factor_corr>( - 2, 3); - EXPECT_FLOAT_EQ(theta[0], S[0](0, 0)); - EXPECT_FLOAT_EQ(theta[1], S[0](1, 0)); - EXPECT_FLOAT_EQ(theta[4], S[0](1, 1)); - EXPECT_FLOAT_EQ(theta[7], S[0](1, 2)); - EXPECT_FLOAT_EQ(theta[8], S[0](2, 2)); -} - -TEST(deserializer_stdvec_matrix, cholesky_factor_corr_exception) { - std::vector theta_i; - std::vector theta(18); - Eigen::Matrix S; - - // non lower-triangular matrix (column major) - // the rest of these tests are with check_cholesky_factor_corr - theta[0] = 1; - theta[1] = 0; - theta[2] = 0; - - theta[3] = 0.5; - theta[4] = 1; - theta[5] = 0; - - theta[6] = 0; - theta[7] = 0; - theta[8] = 1; - theta[9] = 1; - theta[10] = 0; - theta[11] = 0; - - theta[12] = 0.5; - theta[13] = 1; - theta[14] = 0; - - theta[15] = 0; - theta[16] = 0; - theta[17] = 1; - stan::io::deserializer deserializer(theta, theta_i); - EXPECT_THROW( - deserializer.read_cholesky_factor_corr>(2, - 3), - std::domain_error); -} TEST(deserializer_stdvec_matrix, cholesky_factor_corr_constrain) { std::vector theta_i; std::vector theta; @@ -1543,27 +946,7 @@ TEST(deserializer_stdvec_matrix, cholesky_factor_corr_constrain) { EXPECT_EQ(9, L[0].size()); } -TEST(deserializer_stdvec_matrix, offset_multiplier) { - std::vector theta_i; - std::vector theta; - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); - stan::io::deserializer deserializer(theta, theta_i); - auto phi(deserializer.read_offset_multiplier>( - 0, 1, 2, 2, 2)); - for (int i = 0; i < 2; ++i) { - EXPECT_FLOAT_EQ(theta[0], phi[i](0, 0)); - EXPECT_FLOAT_EQ(theta[1], phi[i](1, 0)); - EXPECT_FLOAT_EQ(theta[2], phi[i](0, 1)); - EXPECT_FLOAT_EQ(theta[3], phi[i](1, 1)); - } -} +// Need to add cholesky factor corr constrain lp test TEST(deserializer_stdvec_matrix, offset_multiplier_constrain) { std::vector theta_i; diff --git a/src/test/unit/io/deserializer_test.cpp b/src/test/unit/io/deserializer_test.cpp index a2186c1643e..1d6f5d5ace2 100644 --- a/src/test/unit/io/deserializer_test.cpp +++ b/src/test/unit/io/deserializer_test.cpp @@ -114,27 +114,6 @@ TEST(deserializer_scalar, complex_read) { EXPECT_EQ(0U, deserializer.available()); } -TEST(deserializer_scalar, read_lb) { - std::vector theta_i; - std::vector theta; - theta.push_back(-1.0); - theta.push_back(2.0); - stan::io::deserializer deserializer(theta, theta_i); - double x = deserializer.read_lb(-2.0); - EXPECT_FLOAT_EQ(-1.0, x); - double y = deserializer.read_lb(1.0); - EXPECT_FLOAT_EQ(2.0, y); - EXPECT_EQ(0U, deserializer.available()); -} -TEST(deserializer_scalar, read_lb_exception) { - std::vector theta_i; - std::vector theta; - theta.push_back(-1.0); - theta.push_back(2.0); - stan::io::deserializer deserializer(theta, theta_i); - EXPECT_NO_THROW(deserializer.read_lb(-1.0)); - EXPECT_THROW(deserializer.read_lb(3.0), std::domain_error); -} TEST(deserializer_scalar, read_lb_constrain) { std::vector theta_i; std::vector theta; @@ -153,6 +132,7 @@ TEST(deserializer_scalar, read_lb_constrain) { EXPECT_FLOAT_EQ(15.0 + exp(0.0), (deserializer.read_lb(15.0, lp))); } + TEST(deserializer_scalar, read_lb_constrain_jacobian) { std::vector theta_i; std::vector theta; @@ -175,28 +155,6 @@ TEST(deserializer_scalar, read_lb_constrain_jacobian) { // ub -TEST(deserializer_scalar, read_ub) { - std::vector theta_i; - std::vector theta; - theta.push_back(-1.0); - theta.push_back(2.0); - stan::io::deserializer deserializer(theta, theta_i); - double x = deserializer.read_ub(-0.5); - EXPECT_FLOAT_EQ(-1.0, x); - double y = deserializer.read_ub(5.0); - EXPECT_FLOAT_EQ(2.0, y); - - EXPECT_EQ(0U, deserializer.available()); -} -TEST(deserializer_scalar, read_ub_exception) { - std::vector theta_i; - std::vector theta; - theta.push_back(-1.0); - theta.push_back(2.0); - stan::io::deserializer deserializer(theta, theta_i); - EXPECT_NO_THROW(deserializer.read_ub(-1.0)); - EXPECT_THROW(deserializer.read_ub(1.0), std::domain_error); -} TEST(deserializer_scalar, read_ub_constrain) { std::vector theta_i; std::vector theta; @@ -237,28 +195,6 @@ TEST(deserializer_scalar, read_ub_constrain_jacobian) { // lub -TEST(deserializer_scalar, read_lub) { - std::vector theta_i; - std::vector theta; - theta.push_back(-1.0); - theta.push_back(2.0); - stan::io::deserializer deserializer(theta, theta_i); - double x = deserializer.read_lub(-3.0, 3.0); - EXPECT_FLOAT_EQ(-1.0, x); - double y = deserializer.read_lub(-3.0, 3.0); - EXPECT_FLOAT_EQ(2.0, y); - - EXPECT_EQ(0U, deserializer.available()); -} -TEST(deserializer_scalar, read_lub_exception) { - std::vector theta_i; - std::vector theta; - theta.push_back(-1.0); - theta.push_back(2.0); - stan::io::deserializer deserializer(theta, theta_i); - EXPECT_NO_THROW(deserializer.read_lub(-2.0, 2.0)); - EXPECT_THROW(deserializer.read_lub(-1.0, 1.0), std::domain_error); -} const double inv_logit_m2 = 0.1192029; // stan::math::inv_logit(-2.0) const double inv_logit_m1 = 0.2689414; // stan::math::inv_logit(-1.0) const double inv_logit_0 = 0.5; // stan::math::inv_logit(0) @@ -308,33 +244,6 @@ TEST(deserializer_scalar, read_lub_constrain_jacobian) { } // offset multiplier - -TEST(deserializer_scalar, read_offset_multiplier) { - std::vector theta_i; - std::vector theta; - theta.push_back(-1.0); - theta.push_back(2.0); - stan::io::deserializer deserializer(theta, theta_i); - double x = deserializer.read_offset_multiplier(-3.0, 3.0); - EXPECT_FLOAT_EQ(-1.0, x); - double y = deserializer.read_offset_multiplier(-3.0, 3.0); - EXPECT_FLOAT_EQ(2.0, y); - - EXPECT_EQ(0U, deserializer.available()); -} -TEST(deserializer_scalar, offset_multiplier_exception) { - std::vector theta_i; - std::vector theta; - theta.push_back(-1.0); - theta.push_back(2.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = 0; - EXPECT_NO_THROW(deserializer.read_offset_multiplier(-2.0, -2.0)); - EXPECT_THROW( - (deserializer.read_offset_multiplier(-2.0, -2.0, lp)), - std::domain_error); -} - TEST(deserializer_scalar, offset_multiplier_constrain) { std::vector theta_i; std::vector theta; @@ -379,23 +288,6 @@ TEST(deserializer_scalar, offset_multiplier_constrain_jacobian) { } // prob - -TEST(deserializer_scalar, prob) { - std::vector theta_i; - std::vector theta; - theta.push_back(0.9); - theta.push_back(0.1); - theta.push_back(0.0); - stan::io::deserializer deserializer(theta, theta_i); - double p1 = deserializer.read_prob(); - EXPECT_FLOAT_EQ(0.9, p1); - double p2 = deserializer.read_prob(); - EXPECT_FLOAT_EQ(0.1, p2); - double p3 = deserializer.read_prob(); - EXPECT_FLOAT_EQ(0.0, p3); - - EXPECT_EQ(0U, deserializer.available()); -} TEST(deserializer_scalar, prob_constrain) { std::vector theta_i; std::vector theta; @@ -410,6 +302,7 @@ TEST(deserializer_scalar, prob_constrain) { EXPECT_FLOAT_EQ(inv_logit_m1, (deserializer.read_prob(lp))); EXPECT_FLOAT_EQ(inv_logit_0, (deserializer.read_prob(lp))); } + TEST(deserializer_scalar, prob_constrain_jacobian) { std::vector theta_i; std::vector theta; @@ -431,34 +324,6 @@ TEST(deserializer_scalar, prob_constrain_jacobian) { } // corr - -TEST(deserializer_scalar, corr) { - std::vector theta_i; - std::vector theta; - theta.push_back(-0.9); - theta.push_back(0.1); - theta.push_back(0.0); - stan::io::deserializer deserializer(theta, theta_i); - double rho1 = deserializer.read_corr(); - EXPECT_FLOAT_EQ(-0.9, rho1); - double rho2 = deserializer.read_corr(); - EXPECT_FLOAT_EQ(0.1, rho2); - double rho3 = deserializer.read_corr(); - EXPECT_FLOAT_EQ(0.0, rho3); - - EXPECT_EQ(0U, deserializer.available()); -} -TEST(deserializer_scalar, corr_exception) { - std::vector theta_i; - std::vector theta; - theta.push_back(-0.9); - theta.push_back(-1.1); - theta.push_back(1.1); - stan::io::deserializer deserializer(theta, theta_i); - EXPECT_NO_THROW(deserializer.read_corr()); - EXPECT_THROW(deserializer.read_corr(), std::domain_error); - EXPECT_THROW(deserializer.read_corr(), std::domain_error); -} TEST(deserializer_scalar, corr_constrain) { std::vector theta_i; std::vector theta; @@ -473,6 +338,7 @@ TEST(deserializer_scalar, corr_constrain) { EXPECT_FLOAT_EQ(tanh(-1.0), (deserializer.read_corr(lp))); EXPECT_FLOAT_EQ(tanh(0.0), (deserializer.read_corr(lp))); } + TEST(deserializer_scalar, corr_constrain_jacobian) { using std::tanh; std::vector theta_i; @@ -495,7 +361,6 @@ TEST(deserializer_scalar, corr_constrain_jacobian) { } // vector - TEST(deserializer_vector, read) { std::vector theta_i; std::vector theta; @@ -547,98 +412,8 @@ TEST(deserializer_vector, complex_read) { EXPECT_FLOAT_EQ(15.0, z); } -TEST(deserializer_vector, unit_vector) { - std::vector theta_i(0); - std::vector theta(4, sqrt(0.25)); - stan::io::deserializer deserializer(theta, theta_i); - Eigen::VectorXd y = deserializer.read_unit_vector(4); - EXPECT_EQ(4, y.size()); - EXPECT_FLOAT_EQ(sqrt(0.25), y[0]); - EXPECT_FLOAT_EQ(sqrt(0.25), y[1]); - EXPECT_FLOAT_EQ(sqrt(0.25), y[2]); - EXPECT_FLOAT_EQ(sqrt(0.25), y[3]); -} +// need to add unit vector, simplex tests before merge -TEST(deserializer_vector, unit_vector_exception) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - theta[0] = 0.00; - theta[1] = -sqrt(0.29); - theta[2] = sqrt(0.70); - theta[3] = -sqrt(0.01); - theta[4] = sqrt(1.0); - theta[5] = sqrt(1.0); - EXPECT_NO_THROW(deserializer.read_unit_vector(4)); - EXPECT_THROW(deserializer.read_unit_vector(2), - std::domain_error); - EXPECT_THROW(deserializer.read_unit_vector(0), - std::invalid_argument); -} - -TEST(deserializer_vector, simplex) { - std::vector theta_i(0); - std::vector theta(4, 0.25); - stan::io::deserializer deserializer(theta, theta_i); - Eigen::Matrix y - = deserializer.read_simplex(4); - EXPECT_EQ(4, y.size()); - EXPECT_FLOAT_EQ(0.25, y[0]); - EXPECT_FLOAT_EQ(0.25, y[1]); - EXPECT_FLOAT_EQ(0.25, y[2]); - EXPECT_FLOAT_EQ(0.25, y[3]); -} -TEST(deserializer_vector, simplex_exception) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - theta[0] = 0.00; - theta[1] = 0.29; - theta[2] = 0.70; - theta[3] = 0.01; - theta[4] = 1.0; - theta[5] = 1.0; - EXPECT_NO_THROW(deserializer.read_simplex(4)); - EXPECT_THROW(deserializer.read_simplex(2), - std::domain_error); - EXPECT_THROW(deserializer.read_simplex(0), - std::invalid_argument); -} - -TEST(deserializer_vector, ordered) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - EXPECT_FLOAT_EQ(0.0, deserializer.read()); // throw away theta[0] - Eigen::Matrix y - = deserializer.read_ordered(5); - EXPECT_EQ(5, y.size()); - EXPECT_FLOAT_EQ(1.0, y[0]); - EXPECT_FLOAT_EQ(2.0, y[1]); - EXPECT_FLOAT_EQ(5.0, y[4]); - EXPECT_FLOAT_EQ(6.0, deserializer.read()); -} -TEST(deserializer_vector, ordered_exception) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - EXPECT_FLOAT_EQ(0.0, deserializer.read()); // throw away theta[0] - Eigen::Matrix y - = deserializer.read_ordered(5); - EXPECT_EQ(5, y.size()); - EXPECT_FLOAT_EQ(1.0, y[0]); - EXPECT_FLOAT_EQ(2.0, y[1]); - EXPECT_FLOAT_EQ(5.0, y[4]); - EXPECT_FLOAT_EQ(6.0, deserializer.read()); -} TEST(deserializer_vector, ordered_constrain) { std::vector theta_i; std::vector theta; @@ -682,22 +457,6 @@ TEST(deserializer_vector, ordered_constrain_jacobian) { EXPECT_FLOAT_EQ(expected_lp, lp); } -TEST(deserializer_vector, positive_ordered) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - EXPECT_FLOAT_EQ(0.0, deserializer.read()); // throw away theta[0] - Eigen::Matrix y - = deserializer.read_positive_ordered(5); - EXPECT_EQ(5, y.size()); - EXPECT_FLOAT_EQ(1.0, y[0]); - EXPECT_FLOAT_EQ(2.0, y[1]); - EXPECT_FLOAT_EQ(5.0, y[4]); - EXPECT_FLOAT_EQ(6.0, deserializer.read()); -} - TEST(deserializer_vector, positive_ordered_constrain) { std::vector theta_i; std::vector theta; @@ -742,22 +501,6 @@ TEST(deserializer_vector, positive_ordered_constrain_jacobian) { EXPECT_FLOAT_EQ(expected_lp, lp); } -TEST(deserializer_vector, offset_multiplier) { - std::vector theta_i; - std::vector theta; - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); - stan::io::deserializer deserializer(theta, theta_i); - Eigen::Matrix phi( - deserializer.read_offset_multiplier(0, 1, 4)); - EXPECT_FLOAT_EQ(theta[0], phi[0]); - EXPECT_FLOAT_EQ(theta[1], phi[1]); - EXPECT_FLOAT_EQ(theta[2], phi[2]); - EXPECT_FLOAT_EQ(theta[3], phi[3]); -} - TEST(deserializer_vector, offset_multiplier_constrain) { std::vector theta_i; std::vector theta; @@ -845,32 +588,6 @@ TEST(deserializer_matrix, complex_read) { } } -TEST(deserializer_matrix, matrix_lb) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - for (int i = 0; i < 7; ++i) { - double x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - double lb = -1.5; - Eigen::Matrix y - = deserializer.read_lb(lb, 3, 2); - EXPECT_EQ(3, y.rows()); - EXPECT_EQ(2, y.cols()); - EXPECT_FLOAT_EQ(7.0, y(0, 0)); - EXPECT_FLOAT_EQ(8.0, y(1, 0)); - EXPECT_FLOAT_EQ(9.0, y(2, 0)); - EXPECT_FLOAT_EQ(10.0, y(0, 1)); - EXPECT_FLOAT_EQ(11.0, y(1, 1)); - EXPECT_FLOAT_EQ(12.0, y(2, 1)); - - double a = deserializer.read(); - EXPECT_FLOAT_EQ(13.0, a); -} - TEST(deserializer_matrix, matrix_lb_constrain) { std::vector theta_i; std::vector theta; @@ -925,32 +642,6 @@ TEST(deserializer_matrix, matrix_lb_constrain_lp) { EXPECT_FLOAT_EQ(13.0, a); } -TEST(deserializer_matrix, matrix_ub) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - for (int i = 0; i < 7; ++i) { - double x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - double ub = 12.5; - Eigen::Matrix y - = deserializer.read_ub(ub, 3, 2); - EXPECT_EQ(3, y.rows()); - EXPECT_EQ(2, y.cols()); - EXPECT_FLOAT_EQ(7.0, y(0, 0)); - EXPECT_FLOAT_EQ(8.0, y(1, 0)); - EXPECT_FLOAT_EQ(9.0, y(2, 0)); - EXPECT_FLOAT_EQ(10.0, y(0, 1)); - EXPECT_FLOAT_EQ(11.0, y(1, 1)); - EXPECT_FLOAT_EQ(12.0, y(2, 1)); - - double a = deserializer.read(); - EXPECT_FLOAT_EQ(13.0, a); -} - TEST(deserializer_matrix, matrix_ub_constrain) { std::vector theta_i; std::vector theta; @@ -1005,33 +696,6 @@ TEST(deserializer_matrix, matrix_ub_constrain_lp) { EXPECT_FLOAT_EQ(13.0, a); } -TEST(deserializer_matrix, matrix_lub) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - for (int i = 0; i < 7; ++i) { - double x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - double lb = 6.9; - double ub = 12.5; - Eigen::Matrix y - = deserializer.read_lub(lb, ub, 3, 2); - EXPECT_EQ(3, y.rows()); - EXPECT_EQ(2, y.cols()); - EXPECT_FLOAT_EQ(7.0, y(0, 0)); - EXPECT_FLOAT_EQ(8.0, y(1, 0)); - EXPECT_FLOAT_EQ(9.0, y(2, 0)); - EXPECT_FLOAT_EQ(10.0, y(0, 1)); - EXPECT_FLOAT_EQ(11.0, y(1, 1)); - EXPECT_FLOAT_EQ(12.0, y(2, 1)); - - double a = deserializer.read(); - EXPECT_FLOAT_EQ(13.0, a); -} - TEST(deserializer_matrix, matrix_lub_constrain) { std::vector theta_i; std::vector theta; @@ -1088,39 +752,6 @@ TEST(deserializer_matrix, matrix_lub_constrain_lp) { EXPECT_FLOAT_EQ(13.0, a); } -TEST(deserializer_matrix, corr_matrix) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - theta[0] = 1.0000000000000000; - theta[1] = 0.1817621852191252; - theta[2] = 0.8620926037637362; - theta[3] = 0.1817621852191252; - theta[4] = 1.0000000000000000; - theta[5] = 0.2248293054822660; - theta[6] = 0.8620926037637362; - theta[7] = 0.2248293054822660; - theta[8] = 1.0000000000000001; // allow some tolerance - stan::io::deserializer deserializer(theta, theta_i); - Eigen::Matrix S - = deserializer.read_corr(3); - EXPECT_FLOAT_EQ(theta[0], S(0, 0)); -} -TEST(deserializer_matrix, corr_matrix_exception) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - theta[0] = 1.5; - theta[1] = 1.0; - theta[2] = 2.0; - theta[3] = 0.0; - theta[4] = 1.0; - stan::io::deserializer deserializer(theta, theta_i); - EXPECT_THROW(deserializer.read_corr(1), std::domain_error); - EXPECT_THROW(deserializer.read_corr(2), std::domain_error); -} TEST(deserializer_matrix, corr_matrix_constrain) { using Eigen::Dynamic; using Eigen::Matrix; @@ -1181,43 +812,6 @@ TEST(deserializer_matrix, corr_matrix_constrain_jacobian) { // FIXME: test jacobian } -TEST(deserializer_matrix, cov_matrix) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - theta[0] = 6.3295234356180128; - theta[1] = 0.6351775806192667; - theta[2] = 3.8081029582054304; - theta[3] = 0.6351775806192667; - theta[4] = 1.9293554162496527; - theta[5] = 0.5483126868366485; - theta[6] = 3.8081029582054304; - theta[7] = 0.5483126868366485; - theta[8] = 3.0827514661973088; - stan::io::deserializer deserializer(theta, theta_i); - Eigen::Matrix S - = deserializer.read_cov_matrix(3); - EXPECT_FLOAT_EQ(theta[0], S(0, 0)); - EXPECT_FLOAT_EQ(theta[1], S(1, 0)); - EXPECT_FLOAT_EQ(theta[7], S(2, 1)); - EXPECT_FLOAT_EQ(theta[8], S(2, 2)); -} -TEST(deserializer_matrix, cov_matrix_exception) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - theta[0] = 6.3; - theta[1] = 0.7; - theta[2] = 0.6; - theta[3] = 1.9; - stan::io::deserializer deserializer(theta, theta_i); - EXPECT_THROW(deserializer.read_cov_matrix(2), - std::domain_error); - EXPECT_THROW(deserializer.read_cov_matrix(0), - std::invalid_argument); -} TEST(deserializer_matrix, cov_matrix_constrain) { std::vector theta_i; std::vector theta; @@ -1276,73 +870,6 @@ TEST(deserializer_matrix, cov_matrix_constrain_jacobian) { // FIXME: test Jacobian } -TEST(deserializer_matrix, cholesky_factor_cov) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - // column major - theta[0] = 1; - theta[1] = 2; - theta[2] = 3; - - theta[3] = 0; - theta[4] = 4; - theta[5] = 5; - - theta[6] = 0; - theta[7] = 0; - theta[8] = 6; - stan::io::deserializer deserializer(theta, theta_i); - Eigen::Matrix S - = deserializer.read_cholesky_factor_cov(3, 3); - EXPECT_FLOAT_EQ(theta[0], S(0, 0)); - EXPECT_FLOAT_EQ(theta[1], S(1, 0)); - EXPECT_FLOAT_EQ(theta[7], S(1, 2)); - EXPECT_FLOAT_EQ(theta[8], S(2, 2)); -} -TEST(deserializer_matrix, cholesky_factor_cov_asymmetric) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - // column major - theta[0] = 1; - theta[1] = 2; - theta[2] = 3; - - theta[3] = 0; - theta[4] = 4; - theta[5] = 5; - - stan::io::deserializer deserializer(theta, theta_i); - Eigen::Matrix S - = deserializer.read_cholesky_factor_cov(3, 2); - EXPECT_FLOAT_EQ(theta[0], S(0, 0)); - EXPECT_FLOAT_EQ(theta[1], S(1, 0)); - EXPECT_FLOAT_EQ(theta[2], S(2, 0)); - - EXPECT_FLOAT_EQ(theta[3], S(0, 1)); - EXPECT_FLOAT_EQ(theta[4], S(1, 1)); - EXPECT_FLOAT_EQ(theta[5], S(2, 1)); -} - -TEST(deserializer_matrix, cholesky_factor_cov_exception) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - theta[0] = -6.3; - stan::io::deserializer deserializer(theta, theta_i); - EXPECT_THROW(deserializer.read_cholesky_factor_cov(2, 2), - std::domain_error); - EXPECT_THROW(deserializer.read_cholesky_factor_cov(0, 0), - std::domain_error); - - theta[0] = 1; - EXPECT_THROW(deserializer.read_cholesky_factor_cov(2, 3), - std::domain_error); -} TEST(deserializer_matrix, cholesky_factor_cov_constrain) { std::vector theta_i; std::vector theta; @@ -1413,53 +940,6 @@ TEST(deserializer_matrix, cholesky_factor_cov_constrain_jacobian_asymmetric) { EXPECT_EQ(1.9 + log(L(0, 0)) + log(L(1, 1)) + log(L(2, 2)), lp); } -TEST(deserializer_matrix, cholesky_factor_corr) { - std::vector theta_i; - std::vector theta(9); - // column major - theta[0] = 1; - theta[1] = 0; - theta[2] = 0; - - theta[3] = 0; - theta[4] = 1; - theta[5] = 0; - - theta[6] = 0; - theta[7] = 0; - theta[8] = 1; - stan::io::deserializer deserializer(theta, theta_i); - Eigen::Matrix S - = deserializer.read_cholesky_factor_corr(3); - EXPECT_FLOAT_EQ(theta[0], S(0, 0)); - EXPECT_FLOAT_EQ(theta[1], S(1, 0)); - EXPECT_FLOAT_EQ(theta[4], S(1, 1)); - EXPECT_FLOAT_EQ(theta[7], S(1, 2)); - EXPECT_FLOAT_EQ(theta[8], S(2, 2)); -} - -TEST(deserializer_matrix, cholesky_factor_corr_exception) { - std::vector theta_i; - std::vector theta(9); - Eigen::Matrix S; - - // non lower-triangular matrix (column major) - // the rest of these tests are with check_cholesky_factor_corr - theta[0] = 1; - theta[1] = 0; - theta[2] = 0; - - theta[3] = 0.5; - theta[4] = 1; - theta[5] = 0; - - theta[6] = 0; - theta[7] = 0; - theta[8] = 1; - stan::io::deserializer deserializer(theta, theta_i); - EXPECT_THROW(deserializer.read_cholesky_factor_corr(3), - std::domain_error); -} TEST(deserializer_matrix, cholesky_factor_corr_constrain) { std::vector theta_i; std::vector theta; @@ -1477,22 +957,6 @@ TEST(deserializer_matrix, cholesky_factor_corr_constrain) { EXPECT_EQ(5U, deserializer.available()); } -TEST(deserializer_matrix, offset_multiplier) { - std::vector theta_i; - std::vector theta; - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); - stan::io::deserializer deserializer(theta, theta_i); - Eigen::Matrix phi( - deserializer.read_offset_multiplier(0, 1, 2, 2)); - EXPECT_FLOAT_EQ(theta[0], phi(0, 0)); - EXPECT_FLOAT_EQ(theta[1], phi(1, 0)); - EXPECT_FLOAT_EQ(theta[2], phi(0, 1)); - EXPECT_FLOAT_EQ(theta[3], phi(1, 1)); -} - TEST(deserializer_matrix, offset_multiplier_constrain) { std::vector theta_i; std::vector theta; diff --git a/src/test/unit/io/deserializer_varmat_test.cpp b/src/test/unit/io/deserializer_varmat_test.cpp index 6f7024f2274..12ca0f02950 100644 --- a/src/test/unit/io/deserializer_varmat_test.cpp +++ b/src/test/unit/io/deserializer_varmat_test.cpp @@ -28,96 +28,8 @@ TEST(deserializer_var_vector, read) { EXPECT_FLOAT_EQ(11.0, z.val()); } -TEST(deserializer_var_vector, unit_vector) { - std::vector theta_i(0); - std::vector theta(4, sqrt(0.25)); - stan::io::deserializer deserializer(theta, theta_i); - var_vector_t y = deserializer.read_unit_vector(4); - EXPECT_EQ(4, y.size()); - EXPECT_FLOAT_EQ(sqrt(0.25), y.val()[0]); - EXPECT_FLOAT_EQ(sqrt(0.25), y.val()[1]); - EXPECT_FLOAT_EQ(sqrt(0.25), y.val()[2]); - EXPECT_FLOAT_EQ(sqrt(0.25), y.val()[3]); -} - -TEST(deserializer_var_vector, unit_vector_exception) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - theta[0] = 0.00; - theta[1] = -sqrt(0.29); - theta[2] = sqrt(0.70); - theta[3] = -sqrt(0.01); - theta[4] = sqrt(1.0); - theta[5] = sqrt(1.0); - EXPECT_NO_THROW(deserializer.read_unit_vector(4)); - EXPECT_THROW(deserializer.read_unit_vector(2), - std::domain_error); - EXPECT_THROW(deserializer.read_unit_vector(0), - std::invalid_argument); -} - -TEST(deserializer_var_vector, simplex) { - std::vector theta_i(0); - std::vector theta(4, 0.25); - stan::io::deserializer deserializer(theta, theta_i); - var_vector_t y = deserializer.read_simplex(4); - EXPECT_EQ(4, y.size()); - EXPECT_FLOAT_EQ(0.25, y.val()[0]); - EXPECT_FLOAT_EQ(0.25, y.val()[1]); - EXPECT_FLOAT_EQ(0.25, y.val()[2]); - EXPECT_FLOAT_EQ(0.25, y.val()[3]); -} -TEST(deserializer_var_vector, simplex_exception) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - theta[0] = 0.00; - theta[1] = 0.29; - theta[2] = 0.70; - theta[3] = 0.01; - theta[4] = 1.0; - theta[5] = 1.0; - EXPECT_NO_THROW(deserializer.read_simplex(4)); - EXPECT_THROW(deserializer.read_simplex(2), std::domain_error); - EXPECT_THROW(deserializer.read_simplex(0), - std::invalid_argument); -} +// need to add unit vector and simplex constrain tests -TEST(deserializer_var_vector, ordered) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - EXPECT_FLOAT_EQ( - 0.0, deserializer.read().val()); // throw away theta[0] - var_vector_t y = deserializer.read_ordered(5); - EXPECT_EQ(5, y.size()); - EXPECT_FLOAT_EQ(1.0, y.val()[0]); - EXPECT_FLOAT_EQ(2.0, y.val()[1]); - EXPECT_FLOAT_EQ(5.0, y.val()[4]); - EXPECT_FLOAT_EQ(6.0, deserializer.read().val()); -} -TEST(deserializer_var_vector, ordered_exception) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - EXPECT_FLOAT_EQ( - 0.0, deserializer.read().val()); // throw away theta[0] - var_vector_t y = deserializer.read_ordered(5); - EXPECT_EQ(5, y.size()); - EXPECT_FLOAT_EQ(1.0, y.val()[0]); - EXPECT_FLOAT_EQ(2.0, y.val()[1]); - EXPECT_FLOAT_EQ(5.0, y.val()[4]); - EXPECT_FLOAT_EQ(6.0, deserializer.read().val()); -} TEST(deserializer_var_vector, ordered_constrain) { std::vector theta_i; std::vector theta; @@ -159,22 +71,6 @@ TEST(deserializer_var_vector, ordered_constrain_jacobian) { EXPECT_FLOAT_EQ(expected_lp, lp.val()); } -TEST(deserializer_var_vector, positive_ordered) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - EXPECT_FLOAT_EQ( - 0.0, deserializer.read().val()); // throw away theta[0] - var_vector_t y = deserializer.read_positive_ordered(5); - EXPECT_EQ(5, y.size()); - EXPECT_FLOAT_EQ(1.0, y.val()[0]); - EXPECT_FLOAT_EQ(2.0, y.val()[1]); - EXPECT_FLOAT_EQ(5.0, y.val()[4]); - EXPECT_FLOAT_EQ(6.0, deserializer.read().val()); -} - TEST(deserializer_var_vector, positive_ordered_constrain) { std::vector theta_i; std::vector theta; @@ -219,21 +115,6 @@ TEST(deserializer_var_vector, positive_ordered_constrain_jacobian) { EXPECT_FLOAT_EQ(expected_lp, lp.val()); } -TEST(deserializer_vector, offset_multiplier) { - std::vector theta_i; - std::vector theta; - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); - stan::io::deserializer deserializer(theta, theta_i); - var_vector_t phi(deserializer.read_offset_multiplier(0, 1, 4)); - EXPECT_FLOAT_EQ(theta[0].val(), phi.val()[0]); - EXPECT_FLOAT_EQ(theta[1].val(), phi.val()[1]); - EXPECT_FLOAT_EQ(theta[2].val(), phi.val()[2]); - EXPECT_FLOAT_EQ(theta[3].val(), phi.val()[3]); -} - TEST(deserializer_vector, offset_multiplier_constrain) { std::vector theta_i; std::vector theta; @@ -295,31 +176,6 @@ TEST(deserializer_var_matrix, read) { EXPECT_FLOAT_EQ(13.0, a.val()); } -TEST(deserializer_var_matrix, matrix_lb) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - for (int i = 0; i < 7; ++i) { - stan::math::var x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x.val()); - } - stan::math::var lb = -1.5; - var_matrix_t y = deserializer.read_lb(lb, 3, 2); - EXPECT_EQ(3, y.rows()); - EXPECT_EQ(2, y.cols()); - EXPECT_FLOAT_EQ(7.0, y.val()(0, 0)); - EXPECT_FLOAT_EQ(8.0, y.val()(1, 0)); - EXPECT_FLOAT_EQ(9.0, y.val()(2, 0)); - EXPECT_FLOAT_EQ(10.0, y.val()(0, 1)); - EXPECT_FLOAT_EQ(11.0, y.val()(1, 1)); - EXPECT_FLOAT_EQ(12.0, y.val()(2, 1)); - - stan::math::var a = deserializer.read(); - EXPECT_FLOAT_EQ(13.0, a.val()); -} - TEST(deserializer_var_matrix, matrix_lb_constrain) { std::vector theta_i; std::vector theta; @@ -372,31 +228,6 @@ TEST(deserializer_var_matrix, matrix_lb_constrain_lp) { EXPECT_FLOAT_EQ(13.0, a.val()); } -TEST(deserializer_var_matrix, matrix_ub) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - for (int i = 0; i < 7; ++i) { - stan::math::var x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x.val()); - } - stan::math::var ub = 12.5; - var_matrix_t y = deserializer.read_ub(ub, 3, 2); - EXPECT_EQ(3, y.rows()); - EXPECT_EQ(2, y.cols()); - EXPECT_FLOAT_EQ(7.0, y.val()(0, 0)); - EXPECT_FLOAT_EQ(8.0, y.val()(1, 0)); - EXPECT_FLOAT_EQ(9.0, y.val()(2, 0)); - EXPECT_FLOAT_EQ(10.0, y.val()(0, 1)); - EXPECT_FLOAT_EQ(11.0, y.val()(1, 1)); - EXPECT_FLOAT_EQ(12.0, y.val()(2, 1)); - - stan::math::var a = deserializer.read(); - EXPECT_FLOAT_EQ(13.0, a.val()); -} - TEST(deserializer_var_matrix, matrix_ub_constrain) { std::vector theta_i; std::vector theta; @@ -449,32 +280,6 @@ TEST(deserializer_var_matrix, matrix_ub_constrain_lp) { EXPECT_FLOAT_EQ(13.0, a.val()); } -TEST(deserializer_var_matrix, matrix_lub) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - for (int i = 0; i < 7; ++i) { - stan::math::var x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x.val()); - } - stan::math::var lb = 6.9; - stan::math::var ub = 12.5; - var_matrix_t y = deserializer.read_lub(lb, ub, 3, 2); - EXPECT_EQ(3, y.rows()); - EXPECT_EQ(2, y.cols()); - EXPECT_FLOAT_EQ(7.0, y.val()(0, 0)); - EXPECT_FLOAT_EQ(8.0, y.val()(1, 0)); - EXPECT_FLOAT_EQ(9.0, y.val()(2, 0)); - EXPECT_FLOAT_EQ(10.0, y.val()(0, 1)); - EXPECT_FLOAT_EQ(11.0, y.val()(1, 1)); - EXPECT_FLOAT_EQ(12.0, y.val()(2, 1)); - - stan::math::var a = deserializer.read(); - EXPECT_FLOAT_EQ(13.0, a.val()); -} - TEST(deserializer_var_matrix, matrix_lub_constrain) { std::vector theta_i; std::vector theta; @@ -535,39 +340,6 @@ TEST(deserializer_var_matrix, matrix_lub_constrain_lp) { EXPECT_FLOAT_EQ(13.0, a.val()); } -TEST(deserializer_var_matrix, corr_matrix) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - theta[0] = 1.0000000000000000; - theta[1] = 0.1817621852191252; - theta[2] = 0.8620926037637362; - theta[3] = 0.1817621852191252; - theta[4] = 1.0000000000000000; - theta[5] = 0.2248293054822660; - theta[6] = 0.8620926037637362; - theta[7] = 0.2248293054822660; - theta[8] = 1.0000000000000001; // allow some tolerance - stan::io::deserializer deserializer(theta, theta_i); - var_matrix_t S = deserializer.read_corr(3); - EXPECT_FLOAT_EQ(theta[0].val(), S.val()(0, 0)); -} -TEST(deserializer_var_matrix, corr_matrix_exception) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - theta[0] = 1.5; - theta[1] = 1.0; - theta[2] = 2.0; - theta[3] = 0.0; - theta[4] = 1.0; - stan::io::deserializer deserializer(theta, theta_i); - EXPECT_THROW(deserializer.read_corr(1), std::domain_error); - EXPECT_THROW(deserializer.read_corr(2), std::domain_error); -} - TEST(deserializer_var_matrix, corr_matrix_constrain) { using Eigen::Dynamic; using Eigen::Matrix; @@ -597,6 +369,7 @@ TEST(deserializer_var_matrix, corr_matrix_constrain) { solver(R.val(), Eigen::EigenvaluesOnly); assert(solver.eigenvalues()[0] > 1E-10); } + TEST(deserializer_var_matrix, corr_matrix_constrain_jacobian) { std::vector theta_i; std::vector theta; @@ -626,42 +399,6 @@ TEST(deserializer_var_matrix, corr_matrix_constrain_jacobian) { // FIXME: test jacobian } -TEST(deserializer_var_matrix, cov_matrix) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - theta[0] = 6.3295234356180128; - theta[1] = 0.6351775806192667; - theta[2] = 3.8081029582054304; - theta[3] = 0.6351775806192667; - theta[4] = 1.9293554162496527; - theta[5] = 0.5483126868366485; - theta[6] = 3.8081029582054304; - theta[7] = 0.5483126868366485; - theta[8] = 3.0827514661973088; - stan::io::deserializer deserializer(theta, theta_i); - var_matrix_t S = deserializer.read_cov_matrix(3); - EXPECT_FLOAT_EQ(theta[0].val(), S.val()(0, 0)); - EXPECT_FLOAT_EQ(theta[1].val(), S.val()(1, 0)); - EXPECT_FLOAT_EQ(theta[7].val(), S.val()(2, 1)); - EXPECT_FLOAT_EQ(theta[8].val(), S.val()(2, 2)); -} -TEST(deserializer_var_matrix, cov_matrix_exception) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - theta[0] = 6.3; - theta[1] = 0.7; - theta[2] = 0.6; - theta[3] = 1.9; - stan::io::deserializer deserializer(theta, theta_i); - EXPECT_THROW(deserializer.read_cov_matrix(2), - std::domain_error); - EXPECT_THROW(deserializer.read_cov_matrix(0), - std::invalid_argument); -} TEST(deserializer_var_matrix, cov_matrix_constrain) { std::vector theta_i; std::vector theta; @@ -689,6 +426,7 @@ TEST(deserializer_var_matrix, cov_matrix_constrain) { assert(solver.eigenvalues()[0] > 1E-10); // check positive definite with smallest eigenvalue > 0 } + TEST(deserializer_var_matrix, cov_matrix_constrain_jacobian) { std::vector theta_i; std::vector theta; @@ -720,104 +458,6 @@ TEST(deserializer_var_matrix, cov_matrix_constrain_jacobian) { // FIXME: test Jacobian } -TEST(deserializer_var_matrix, cholesky_factor_cov) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - // column major - theta[0] = 1; - theta[1] = 2; - theta[2] = 3; - - theta[3] = 0; - theta[4] = 4; - theta[5] = 5; - - theta[6] = 0; - theta[7] = 0; - theta[8] = 6; - stan::io::deserializer deserializer(theta, theta_i); - var_matrix_t S = deserializer.read_cholesky_factor_cov(3, 3); - EXPECT_FLOAT_EQ(theta[0].val(), S.val()(0, 0)); - EXPECT_FLOAT_EQ(theta[1].val(), S.val()(1, 0)); - EXPECT_FLOAT_EQ(theta[7].val(), S.val()(1, 2)); - EXPECT_FLOAT_EQ(theta[8].val(), S.val()(2, 2)); -} -TEST(deserializer_var_matrix, cholesky_factor_cov_asymmetric) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - // column major - theta[0] = 1; - theta[1] = 2; - theta[2] = 3; - - theta[3] = 0; - theta[4] = 4; - theta[5] = 5; - - stan::io::deserializer deserializer(theta, theta_i); - var_matrix_t S = deserializer.read_cholesky_factor_cov(3, 2); - EXPECT_FLOAT_EQ(theta[0].val(), S.val()(0, 0)); - EXPECT_FLOAT_EQ(theta[1].val(), S.val()(1, 0)); - EXPECT_FLOAT_EQ(theta[2].val(), S.val()(2, 0)); - - EXPECT_FLOAT_EQ(theta[3].val(), S.val()(0, 1)); - EXPECT_FLOAT_EQ(theta[4].val(), S.val()(1, 1)); - EXPECT_FLOAT_EQ(theta[5].val(), S.val()(2, 1)); -} - -TEST(deserializer_var_matrix, cholesky_factor_cov_exception) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - theta[0] = -6.3; - stan::io::deserializer deserializer(theta, theta_i); - EXPECT_THROW(deserializer.read_cholesky_factor_cov(2, 2), - std::domain_error); - EXPECT_THROW(deserializer.read_cholesky_factor_cov(0, 0), - std::domain_error); - - theta[0] = 1; - EXPECT_THROW(deserializer.read_cholesky_factor_cov(2, 3), - std::domain_error); -} -TEST(deserializer_var_matrix, cholesky_factor_cov_constrain) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 8; ++i) - theta.push_back(-static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - stan::math::var lp = 0; - var_matrix_t L( - deserializer.read_cholesky_factor_cov(lp, 3U, 3U)); - EXPECT_NO_THROW(stan::math::check_cholesky_factor( - "test_cholesky_factor_constrain", "L", L.val())); - EXPECT_EQ(3, L.rows()); - EXPECT_EQ(3, L.cols()); - EXPECT_EQ(9, L.size()); - EXPECT_EQ(2U, deserializer.available()); -} - -TEST(deserializer_var_matrix, cholesky_factor_cov_constrain_asymmetric) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 8; ++i) - theta.push_back(-static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - stan::math::var lp = 0; - var_matrix_t L( - deserializer.read_cholesky_factor_cov(lp, 3U, 2U)); - EXPECT_NO_THROW(stan::math::check_cholesky_factor( - "test_cholesky_factor_constrain", "L", L.val())); - EXPECT_EQ(3, L.rows()); - EXPECT_EQ(2, L.cols()); - EXPECT_EQ(6, L.size()); - EXPECT_EQ(3U, deserializer.available()); -} TEST(deserializer_var_matrix, cholesky_factor_cov_constrain_jacobian) { std::vector theta_i; std::vector theta; @@ -856,52 +496,6 @@ TEST(deserializer_var_matrix, lp.val()); } -TEST(deserializer_var_matrix, cholesky_factor_corr) { - std::vector theta_i; - std::vector theta(9); - // column major - theta[0] = 1; - theta[1] = 0; - theta[2] = 0; - - theta[3] = 0; - theta[4] = 1; - theta[5] = 0; - - theta[6] = 0; - theta[7] = 0; - theta[8] = 1; - stan::io::deserializer deserializer(theta, theta_i); - var_matrix_t S = deserializer.read_cholesky_factor_corr(3); - EXPECT_FLOAT_EQ(theta[0].val(), S.val()(0, 0)); - EXPECT_FLOAT_EQ(theta[1].val(), S.val()(1, 0)); - EXPECT_FLOAT_EQ(theta[4].val(), S.val()(1, 1)); - EXPECT_FLOAT_EQ(theta[7].val(), S.val()(1, 2)); - EXPECT_FLOAT_EQ(theta[8].val(), S.val()(2, 2)); -} - -TEST(deserializer_var_matrix, cholesky_factor_corr_exception) { - std::vector theta_i; - std::vector theta(9); - var_matrix_t S; - - // non lower-triangular matrix (column major) - // the rest of these tests are with check_cholesky_factor_corr - theta[0] = 1; - theta[1] = 0; - theta[2] = 0; - - theta[3] = 0.5; - theta[4] = 1; - theta[5] = 0; - - theta[6] = 0; - theta[7] = 0; - theta[8] = 1; - stan::io::deserializer deserializer(theta, theta_i); - EXPECT_THROW(deserializer.read_cholesky_factor_corr(3), - std::domain_error); -} TEST(deserializer_var_matrix, cholesky_factor_corr_constrain) { std::vector theta_i; std::vector theta; @@ -918,22 +512,7 @@ TEST(deserializer_var_matrix, cholesky_factor_corr_constrain) { EXPECT_EQ(9, L.size()); EXPECT_EQ(5U, deserializer.available()); } - -TEST(deserializer_var_matrix, offset_multiplier) { - std::vector theta_i; - std::vector theta; - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); - stan::io::deserializer deserializer(theta, theta_i); - var_matrix_t phi( - deserializer.read_offset_multiplier(0, 1, 2, 2)); - EXPECT_FLOAT_EQ(theta[0].val(), phi.val()(0, 0)); - EXPECT_FLOAT_EQ(theta[1].val(), phi.val()(1, 0)); - EXPECT_FLOAT_EQ(theta[2].val(), phi.val()(0, 1)); - EXPECT_FLOAT_EQ(theta[3].val(), phi.val()(1, 1)); -} +// need lp version of ^ TEST(deserializer_var_matrix, offset_multiplier_constrain) { std::vector theta_i; From 42a9a6d71c90989ba7fb5e4615a328e3d6caa7c0 Mon Sep 17 00:00:00 2001 From: Stan Jenkins Date: Sun, 7 Mar 2021 02:20:52 +0000 Subject: [PATCH 17/29] [Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.04.1 (tags/RELEASE_600/final) --- src/stan/io/deserializer.hpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/stan/io/deserializer.hpp b/src/stan/io/deserializer.hpp index ef31a061dfc..03ad001e375 100644 --- a/src/stan/io/deserializer.hpp +++ b/src/stan/io/deserializer.hpp @@ -232,8 +232,7 @@ class deserializer { * @param rows The size of the rows of the matrix. * @param cols The size of the cols of the matrix. */ - template * = nullptr, + template * = nullptr, require_not_vt_complex* = nullptr> inline auto read(Eigen::Index rows, Eigen::Index cols) { if (rows == 0 || cols == 0) { @@ -249,8 +248,7 @@ class deserializer { * @param rows The size of the rows of the matrix. * @param cols The size of the cols of the matrix. */ - template * = nullptr, + template * = nullptr, require_vt_complex* = nullptr> inline auto read(Eigen::Index rows, Eigen::Index cols) { if (rows == 0 || cols == 0) { From c1820b2c74e5500bb81e42e7ff18ab5141b8ad7d Mon Sep 17 00:00:00 2001 From: Ben Date: Mon, 8 Mar 2021 08:24:38 -0500 Subject: [PATCH 18/29] Shorted offset multiplier, removed positive, prob, and corr scalar constrains --- src/stan/io/deserializer.hpp | 283 +----------------- .../unit/io/deserializer_stdvector_test.cpp | 78 ----- src/test/unit/io/deserializer_test.cpp | 73 ----- 3 files changed, 1 insertion(+), 433 deletions(-) diff --git a/src/stan/io/deserializer.hpp b/src/stan/io/deserializer.hpp index 03ad001e375..1595762889b 100644 --- a/src/stan/io/deserializer.hpp +++ b/src/stan/io/deserializer.hpp @@ -400,55 +400,6 @@ class deserializer { } } - /** - * Return the next object transformed to be positive, possibly - * incrementing the specified reference with the log absolute - * determinant of the Jacobian. - * - *

See stan::math::positive_constrain(T,T&). - * - * @tparam Ret The type to return. - * @tparam Jacobian Whether to increment the log of the absolute Jacobian - * determinant of the transform. - * @tparam LP Type of log probability. - * @tparam Sizes A parameter pack of integral types. - * @param lp Reference to log probability variable to increment. - * @param sizes Pack of integrals to use to construct the return's type. - */ - template * = nullptr> - inline auto read_pos(LP& lp, Sizes... sizes) { - if (Jacobian) { - return stan::math::positive_constrain(this->read(sizes...), lp); - } else { - return stan::math::positive_constrain(this->read(sizes...)); - } - } - - /** - * Specialization for `std::vector` that calls itself recursivly for - * each element. - * @tparam Ret The type to return. - * @tparam Jacobian Whether to increment the log of the absolute Jacobian - * determinant of the transform. - * @tparam LP Type of log probability. - * @tparam Sizes A parameter pack of integral types. - * @param vecsize Size of the return vector. - * @param lp Reference to log probability variable to increment. - * @param sizes Pack of integrals to use to construct the return's type. - */ - template * = nullptr> - inline auto read_pos(LP& lp, size_t vecsize, Sizes... sizes) { - std::decay_t ret; - ret.reserve(vecsize); - for (size_t i = 0; i < vecsize; ++i) { - ret.emplace_back( - this->read_pos, Jacobian>(lp, sizes...)); - } - return ret; - } - /** * Return the next object transformed to have the specified offset and * multiplier. @@ -471,8 +422,7 @@ class deserializer { * bounds. */ template * = nullptr> + typename LP, typename... Sizes> inline auto read_offset_multiplier(const Offset& offset, const Mult& multiplier, LP& lp, Sizes... sizes) { @@ -486,237 +436,6 @@ class deserializer { } } - /** - * Specialization of offset multiplier for `std::vector` with - * non-`std::vector` offset and multiplier. - * - *

See stan::math::offset_multiplier_constrain(T, double, - * double). - * - * @tparam Ret The type to return. - * @tparam Jacobian Whether to increment the log of the absolute Jacobian - * determinant of the transform. - * @tparam Offset Type of offset. - * @tparam Mult Type of multiplier. - * @tparam LP Type of log probability. - * @tparam Sizes A parameter pack of integral types. - * @param offset Offset. - * @param multiplier Multiplier. - * @param lp Reference to log probability variable to increment. - * @param vecsize The size of the return vector. - * @param sizes Pack of integrals to use to construct the return's type. - * bounds. - */ - template * = nullptr> - inline auto read_offset_multiplier(const Offset& offset, - const Mult& multiplier, LP& lp, - const size_t vecsize, Sizes... sizes) { - std::decay_t ret; - ret.reserve(vecsize); - for (size_t i = 0; i < vecsize; ++i) { - ret.emplace_back( - this->read_offset_multiplier, Jacobian>( - offset, multiplier, lp, sizes...)); - } - return ret; - } - - /** - * Specialization of offset multiplier for `std::vector` with `std::vector` - * offset and multiplier. - * - *

See stan::math::offset_multiplier_constrain(T, double, - * double). - * - * @tparam Ret The type to return. - * @tparam Jacobian Whether to increment the log of the absolute Jacobian - * determinant of the transform. - * @tparam Offset Type of offset. - * @tparam Mult Type of multiplier. - * @tparam LP Type of log probability. - * @tparam Sizes A parameter pack of integral types. - * @param offset Offset. - * @param multiplier Multiplier. - * @param lp Reference to log probability variable to increment. - * @param vecsize The size of the return vector. - * @param sizes Pack of integrals to use to construct the return's type. - * bounds. - */ - template * = nullptr> - inline auto read_offset_multiplier(const std::vector& offset, - const std::vector& multiplier, - LP& lp, const size_t vecsize, - Sizes... sizes) { - std::decay_t ret; - ret.reserve(vecsize); - for (size_t i = 0; i < vecsize; ++i) { - ret.emplace_back( - this->read_offset_multiplier, Jacobian>( - offset[i], multiplier[i], lp, sizes...)); - } - return ret; - } - - /** - * Specialization of offset multiplier for `std::vector` with `std::vector` - * offset and non-`std::vector` multiplier. - * - *

See stan::math::offset_multiplier_constrain(T, double, - * double). - * - * @tparam Ret The type to return. - * @tparam Jacobian Whether to increment the log of the absolute Jacobian - * determinant of the transform. - * @tparam Offset Type of offset. - * @tparam Mult Type of multiplier. - * @tparam LP Type of log probability. - * @tparam Sizes A parameter pack of integral types. - * @param offset Offset. - * @param multiplier Multiplier. - * @param lp Reference to log probability variable to increment. - * @param vecsize The size of the return vector. - * @param sizes Pack of integrals to use to construct the return's type. - * bounds. - */ - template * = nullptr> - inline auto read_offset_multiplier(const std::vector& offset, - const Mult& multiplier, LP& lp, - const size_t vecsize, Sizes... sizes) { - std::decay_t ret; - ret.reserve(vecsize); - for (size_t i = 0; i < vecsize; ++i) { - ret.emplace_back( - this->read_offset_multiplier, Jacobian>( - offset[i], multiplier, lp, sizes...)); - } - return ret; - } - - /** - * Specialization of offset multiplier for `std::vector` with - * non-`std::vector` offset and `std::vector` multiplier. - * - *

See stan::math::offset_multiplier_constrain(T, double, - * double). - * - * @tparam Ret The type to return. - * @tparam Jacobian Whether to increment the log of the absolute Jacobian - * determinant of the transform. - * @tparam Offset Type of offset. - * @tparam Mult Type of multiplier. - * @tparam LP Type of log probability. - * @tparam Sizes A parameter pack of integral types. - * @param offset Offset. - * @param multiplier Multiplier. - * @param lp Reference to log probability variable to increment. - * @param vecsize The size of the return vector. - * @param sizes Pack of integrals to use to construct the return's type. - * bounds. - */ - template * = nullptr> - inline auto read_offset_multiplier(const Offset& offset, - const std::vector& multiplier, - LP& lp, const size_t vecsize, - Sizes... sizes) { - std::decay_t ret; - ret.reserve(vecsize); - for (size_t i = 0; i < vecsize; ++i) { - ret.emplace_back( - this->read_offset_multiplier, Jacobian>( - offset, multiplier[i], lp, sizes...)); - } - return ret; - } - - /** - * Return the next object transformed to be a probability - * between 0 and 1, incrementing the specified reference with - * the log of the absolute Jacobian determinant. - * - *

See stan::math::prob_constrain(T). - * - * @tparam Ret The type to return. - * @tparam Jacobian Whether to increment the log of the absolute Jacobian - * determinant of the transform. - * @tparam LP Type of log probability. - * @tparam Sizes A parameter pack of integral types. - * @param lp Reference to log probability variable to increment. - * @param sizes Pack of integrals to use to construct the return's type. - * @return The next scalar transformed to a probability. - */ - template * = nullptr> - inline auto read_prob(LP& lp, Sizes... sizes) { - if (Jacobian) { - return stan::math::prob_constrain(this->read(sizes...), lp); - } else { - return stan::math::prob_constrain(this->read(sizes...)); - } - } - - /** - * Specialization of `read_prob` for returning an `std::vector`. - * - *

See stan::math::prob_constrain(T). - * - * @tparam Ret The type to return. - * @tparam Jacobian Whether to increment the log of the absolute Jacobian - * determinant of the transform. - * @tparam LP Type of log probability. - * @tparam Sizes A parameter pack of integral types. - * @param lp Reference to log probability variable to increment. - * @param sizes Pack of integrals to use to construct the return's type. - * @return The next scalar transformed to a probability. - */ - template * = nullptr> - inline auto read_prob(LP& lp, const size_t vecsize, Sizes... sizes) { - std::decay_t ret; - ret.reserve(vecsize); - for (size_t i = 0; i < vecsize; ++i) { - ret.emplace_back( - this->read_prob, Jacobian>(lp, sizes...)); - } - return ret; - } - - /** - * Return the next object transformed to be a (partial) - * correlation between -1 and 1, incrementing the specified - * reference with the log of the absolute Jacobian determinant. - * - *

See stan::math::corr_constrain(T,T&). - * - * @tparam Ret The type to return. - * @tparam Jacobian Whether to increment the log of the absolute Jacobian - * determinant of the transform. - * @tparam LP Type of log probability. - * @tparam Sizes A parameter pack of integral types. - * @param sizes Pack of integrals to use to construct the return's type. - * @param lp The reference to the variable holding the log - * probability to increment. - * @return The next scalar transformed to a correlation. - */ - template * = nullptr, - require_not_matrix_t* = nullptr> - inline auto read_corr(LP& lp, Sizes... sizes) { - using stan::math::corr_constrain; - if (Jacobian) { - return corr_constrain(this->read(sizes...), lp); - } else { - return corr_constrain(this->read(sizes...)); - } - } - /** * Return the next object transformed to be a (partial) * correlation between -1 and 1, incrementing the specified diff --git a/src/test/unit/io/deserializer_stdvector_test.cpp b/src/test/unit/io/deserializer_stdvector_test.cpp index 5b932b98740..2fb08c0a0ff 100644 --- a/src/test/unit/io/deserializer_stdvector_test.cpp +++ b/src/test/unit/io/deserializer_stdvector_test.cpp @@ -239,84 +239,6 @@ TEST(deserializer_stdvec_scalar, offset_multiplier_constrain_jacobian) { EXPECT_FLOAT_EQ(expected_lp, lp); } -// prob - -TEST(deserializer_stdvec_scalar, prob_constrain) { - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(0.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = 0; - auto ret = deserializer.read_prob, false>(lp, 4); - EXPECT_FLOAT_EQ(inv_logit_m2, ret[0]); - EXPECT_FLOAT_EQ(inv_logit_3, ret[1]); - EXPECT_FLOAT_EQ(inv_logit_m1, ret[2]); - EXPECT_FLOAT_EQ(inv_logit_0, ret[3]); -} - -TEST(deserializer_stdvec_scalar, prob_constrain_jacobian) { - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(0.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = -0.88; - auto ret = deserializer.read_prob, true>(lp, 4); - EXPECT_FLOAT_EQ(inv_logit_m2, ret[0]); - EXPECT_FLOAT_EQ(inv_logit_3, ret[1]); - EXPECT_FLOAT_EQ(inv_logit_m1, ret[2]); - EXPECT_FLOAT_EQ(inv_logit_0, ret[3]); - double expected_lp = -0.88 + log(inv_logit_m2 * (1.0 - inv_logit_m2)) - + log(inv_logit_3 * (1.0 - inv_logit_3)) - + log(inv_logit_m1 * (1.0 - inv_logit_m1)) - + log(inv_logit_0 * (1.0 - inv_logit_0)); - EXPECT_FLOAT_EQ(expected_lp, lp); -} - -// corr - -TEST(deserializer_stdvec_scalar, corr_constrain) { - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(0.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = 0; - auto ret = deserializer.read_corr, false>(lp, 4); - EXPECT_FLOAT_EQ(tanh(-2.0), ret[0]); - EXPECT_FLOAT_EQ(tanh(3.0), ret[1]); - EXPECT_FLOAT_EQ(tanh(-1.0), ret[2]); - EXPECT_FLOAT_EQ(tanh(0.0), ret[3]); -} -TEST(deserializer_stdvec_scalar, corr_constrain_jacobian) { - using std::tanh; - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(0.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = -10.0; - auto ret = deserializer.read_corr, true>(lp, 4); - EXPECT_FLOAT_EQ(tanh(-2.0), ret[0]); - EXPECT_FLOAT_EQ(tanh(3.0), ret[1]); - EXPECT_FLOAT_EQ(tanh(-1.0), ret[2]); - EXPECT_FLOAT_EQ(tanh(0.0), ret[3]); - double expected_lp = -10.0 + log(1.0 - tanh(-2.0) * tanh(-2.0)) - + log(1.0 - tanh(3.0) * tanh(3.0)) - + log(1.0 - tanh(-1.0) * tanh(-1.0)) - + log(1.0 - tanh(0.0) * tanh(0.0)); - EXPECT_FLOAT_EQ(expected_lp, lp); -} - // vectors TEST(deserializer_stdvec_vector, read) { diff --git a/src/test/unit/io/deserializer_test.cpp b/src/test/unit/io/deserializer_test.cpp index 1d6f5d5ace2..6e0ad7dabb9 100644 --- a/src/test/unit/io/deserializer_test.cpp +++ b/src/test/unit/io/deserializer_test.cpp @@ -287,79 +287,6 @@ TEST(deserializer_scalar, offset_multiplier_constrain_jacobian) { EXPECT_FLOAT_EQ(expected_lp, lp); } -// prob -TEST(deserializer_scalar, prob_constrain) { - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(0.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = 0; - EXPECT_FLOAT_EQ(inv_logit_m2, (deserializer.read_prob(lp))); - EXPECT_FLOAT_EQ(inv_logit_3, (deserializer.read_prob(lp))); - EXPECT_FLOAT_EQ(inv_logit_m1, (deserializer.read_prob(lp))); - EXPECT_FLOAT_EQ(inv_logit_0, (deserializer.read_prob(lp))); -} - -TEST(deserializer_scalar, prob_constrain_jacobian) { - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(0.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = -0.88; - EXPECT_FLOAT_EQ(inv_logit_m2, (deserializer.read_prob(lp))); - EXPECT_FLOAT_EQ(inv_logit_3, (deserializer.read_prob(lp))); - EXPECT_FLOAT_EQ(inv_logit_m1, (deserializer.read_prob(lp))); - EXPECT_FLOAT_EQ(inv_logit_0, (deserializer.read_prob(lp))); - double expected_lp = -0.88 + log(inv_logit_m2 * (1.0 - inv_logit_m2)) - + log(inv_logit_3 * (1.0 - inv_logit_3)) - + log(inv_logit_m1 * (1.0 - inv_logit_m1)) - + log(inv_logit_0 * (1.0 - inv_logit_0)); - EXPECT_FLOAT_EQ(expected_lp, lp); -} - -// corr -TEST(deserializer_scalar, corr_constrain) { - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(0.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = 0; - EXPECT_FLOAT_EQ(tanh(-2.0), (deserializer.read_corr(lp))); - EXPECT_FLOAT_EQ(tanh(3.0), (deserializer.read_corr(lp))); - EXPECT_FLOAT_EQ(tanh(-1.0), (deserializer.read_corr(lp))); - EXPECT_FLOAT_EQ(tanh(0.0), (deserializer.read_corr(lp))); -} - -TEST(deserializer_scalar, corr_constrain_jacobian) { - using std::tanh; - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(0.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = -10.0; - EXPECT_FLOAT_EQ(tanh(-2.0), (deserializer.read_corr(lp))); - EXPECT_FLOAT_EQ(tanh(3.0), (deserializer.read_corr(lp))); - EXPECT_FLOAT_EQ(tanh(-1.0), (deserializer.read_corr(lp))); - EXPECT_FLOAT_EQ(tanh(0.0), (deserializer.read_corr(lp))); - double expected_lp = -10.0 + log(1.0 - tanh(-2.0) * tanh(-2.0)) - + log(1.0 - tanh(3.0) * tanh(3.0)) - + log(1.0 - tanh(-1.0) * tanh(-1.0)) - + log(1.0 - tanh(0.0) * tanh(0.0)); - EXPECT_FLOAT_EQ(expected_lp, lp); -} - // vector TEST(deserializer_vector, read) { std::vector theta_i; From ad7437d3b96f3a00ef7b83b306d6521e4af5e4a9 Mon Sep 17 00:00:00 2001 From: Ben Date: Mon, 8 Mar 2021 13:54:37 -0500 Subject: [PATCH 19/29] Updated deserializer tests --- src/stan/io/deserializer.hpp | 122 +- .../unit/io/deserializer_stdvector_test.cpp | 1075 ++++---------- src/test/unit/io/deserializer_test.cpp | 1244 ++++++++--------- src/test/unit/io/deserializer_varmat_test.cpp | 761 +++++----- 4 files changed, 1295 insertions(+), 1907 deletions(-) diff --git a/src/stan/io/deserializer.hpp b/src/stan/io/deserializer.hpp index 1595762889b..0f3c3615153 100644 --- a/src/stan/io/deserializer.hpp +++ b/src/stan/io/deserializer.hpp @@ -436,65 +436,6 @@ class deserializer { } } - /** - * Return the next object transformed to be a (partial) - * correlation between -1 and 1, incrementing the specified - * reference with the log of the absolute Jacobian determinant. - * - *

See stan::math::corr_constrain(T,T&). - * - * @tparam Ret The type to return. - * @tparam Jacobian Whether to increment the log of the absolute Jacobian - * determinant of the transform. - * @tparam LP Type of log probability. - * @param k Dimensions of matrix return type. - * @param lp The reference to the variable holding the log - * probability to increment. - */ - template * = nullptr, - require_matrix_t* = nullptr> - inline auto read_corr(LP& lp, Eigen::Index k) { - using stan::math::corr_matrix_constrain; - if (Jacobian) { - return corr_matrix_constrain( - this->read>((k * (k - 1)) / 2), - k, lp); - } else { - return corr_matrix_constrain( - this->read>((k * (k - 1)) / 2), - k); - } - } - - /** - * Specialization of `read_corr` for `std::vector` return types. - * - *

See stan::math::corr_constrain(T,T&). - * - * @tparam Ret The type to return. - * @tparam Jacobian Whether to increment the log of the absolute Jacobian - * determinant of the transform. - * @tparam LP Type of log probability. - * @tparam Sizes A parameter pack of integral types. - * @param lp The reference to the variable holding the log - * @param vecsize The size of the return vector. - * @param sizes Pack of integrals to use to construct the return's type. - * probability to increment. - * @return The next scalar transformed to a correlation. - */ - template * = nullptr> - inline auto read_corr(LP& lp, const size_t vecsize, Sizes... sizes) { - std::decay_t ret; - ret.reserve(vecsize); - for (size_t i = 0; i < vecsize; ++i) { - ret.emplace_back( - this->read_corr, Jacobian>(lp, sizes...)); - } - return ret; - } - /** * Return the next unit_vector of the specified size (using one fewer * unconstrained scalars), incrementing the specified reference with the @@ -518,9 +459,9 @@ class deserializer { inline auto read_unit_vector(LP& lp, Sizes... sizes) { using stan::math::unit_vector_constrain; if (Jacobian) { - return unit_vector_constrain(this->read(sizes...), lp); + return math::eval(unit_vector_constrain(this->read(sizes...), lp)); } else { - return unit_vector_constrain(this->read(sizes...)); + return math::eval(unit_vector_constrain(this->read(sizes...))); } } @@ -926,6 +867,65 @@ class deserializer { } return ret; } + + /** + * Return the next object transformed to be a (partial) + * correlation between -1 and 1, incrementing the specified + * reference with the log of the absolute Jacobian determinant. + * + *

See stan::math::corr_constrain(T,T&). + * + * @tparam Ret The type to return. + * @tparam Jacobian Whether to increment the log of the absolute Jacobian + * determinant of the transform. + * @tparam LP Type of log probability. + * @param k Dimensions of matrix return type. + * @param lp The reference to the variable holding the log + * probability to increment. + */ + template * = nullptr, + require_matrix_t* = nullptr> + inline auto read_corr_matrix(LP& lp, Eigen::Index k) { + using stan::math::corr_matrix_constrain; + if (Jacobian) { + return corr_matrix_constrain( + this->read>((k * (k - 1)) / 2), + k, lp); + } else { + return corr_matrix_constrain( + this->read>((k * (k - 1)) / 2), + k); + } + } + + /** + * Specialization of `read_corr` for `std::vector` return types. + * + *

See stan::math::corr_constrain(T,T&). + * + * @tparam Ret The type to return. + * @tparam Jacobian Whether to increment the log of the absolute Jacobian + * determinant of the transform. + * @tparam LP Type of log probability. + * @tparam Sizes A parameter pack of integral types. + * @param lp The reference to the variable holding the log + * @param vecsize The size of the return vector. + * @param sizes Pack of integrals to use to construct the return's type. + * probability to increment. + * @return The next scalar transformed to a correlation. + */ + template * = nullptr> + inline auto read_corr_matrix(LP& lp, const size_t vecsize, Sizes... sizes) { + std::decay_t ret; + ret.reserve(vecsize); + for (size_t i = 0; i < vecsize; ++i) { + ret.emplace_back( + this->read_corr_matrix, Jacobian>(lp, sizes...)); + } + return ret; + } }; } // namespace io diff --git a/src/test/unit/io/deserializer_stdvector_test.cpp b/src/test/unit/io/deserializer_stdvector_test.cpp index 2fb08c0a0ff..4ad63df103f 100644 --- a/src/test/unit/io/deserializer_stdvector_test.cpp +++ b/src/test/unit/io/deserializer_stdvector_test.cpp @@ -1,920 +1,347 @@ #include +// expect_near_rel comes from lib/stan_math +#include #include -TEST(deserializer_rowvector, read) { +template +void test_std_vector_deserializer_read(Sizes... sizes) { std::vector theta_i; std::vector theta; for (size_t i = 0; i < 100U; ++i) theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - for (size_t i = 0; i < 7U; ++i) { - double x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - Eigen::Matrix y - = deserializer.read(4); - EXPECT_EQ(4, y.cols()); - EXPECT_EQ(1, y.rows()); - EXPECT_EQ(4, y.size()); - EXPECT_FLOAT_EQ(7.0, y[0]); - EXPECT_FLOAT_EQ(8.0, y[1]); - EXPECT_FLOAT_EQ(9.0, y[2]); - EXPECT_FLOAT_EQ(10.0, y[3]); - - double z = deserializer.read(); - EXPECT_FLOAT_EQ(11.0, z); -} -TEST(deserializer_stdvec, std_vector_vector) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100U; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - auto y = deserializer.read>(5, 4); - EXPECT_EQ(5, y.size()); - int sentinal = 0; - for (int i = 0; i < y.size(); ++i) { - EXPECT_EQ(4, y[i].rows()); - EXPECT_EQ(1, y[i].cols()); - for (int j = 0; j < 4; ++j) { - EXPECT_FLOAT_EQ(sentinal, y[i].coeff(j)); - sentinal++; - } - } -} + stan::io::deserializer deserializer1(theta, theta_i); + stan::io::deserializer deserializer2(theta, theta_i); -TEST(deserializer_stdvec, std_vector_std_vector_matrix) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 120U; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - auto y = deserializer.read>>(5, 4, 3, - 2); - EXPECT_EQ(5, y.size()); - int sentinal = 0; - for (int i = 0; i < y.size(); ++i) { - EXPECT_EQ(4, y[i].size()); - for (int j = 0; j < 4; ++j) { - EXPECT_EQ(3, y[i][j].rows()); - EXPECT_EQ(2, y[i][j].cols()); - for (int k = 0; k < 6; ++k) { - EXPECT_FLOAT_EQ(sentinal, y[i][j].coeff(k)); - sentinal++; - } - } + auto y = deserializer1.read>(4, sizes...); + for(size_t i = 0; i < 4; ++i) { + stan::test::expect_near_rel("test_std_vector_deserializer", y[i], deserializer2.read(sizes...)); } } -// scalar bounds -TEST(deserializer_stdvec_scalar, read) { - std::vector theta_i; - std::vector theta; - theta.push_back(1.0); - theta.push_back(2.0); - stan::io::deserializer deserializer(theta, theta_i); - auto x = deserializer.read>(2); - EXPECT_FLOAT_EQ(1.0, x[0]); - EXPECT_FLOAT_EQ(2.0, x[1]); - EXPECT_EQ(0U, deserializer.available()); +TEST(deserializer_array, read_arrays) { + test_std_vector_deserializer_read(); + test_std_vector_deserializer_read>(); + test_std_vector_deserializer_read>(3); + test_std_vector_deserializer_read(2); + test_std_vector_deserializer_read, Eigen::Dynamic, 1>>(2); + test_std_vector_deserializer_read>(3, 2); + test_std_vector_deserializer_read(2); + test_std_vector_deserializer_read, 1, Eigen::Dynamic>>(2); + test_std_vector_deserializer_read>(3, 2); + test_std_vector_deserializer_read(2, 2); + test_std_vector_deserializer_read, Eigen::Dynamic, Eigen::Dynamic>>(2, 2); + test_std_vector_deserializer_read>(2, 3, 2); } -TEST(deserializer_stdvec_scalar, read_lb_constrain) { - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(0.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = 0.0; - auto ret = deserializer.read_lb, false>( - std::vector{1.0, 5, -2, 15}, lp, 4); - EXPECT_FLOAT_EQ(1.0 + exp(-2.0), ret[0]); - EXPECT_FLOAT_EQ(5.0 + exp(3.0), ret[1]); - EXPECT_FLOAT_EQ(-2.0 + exp(-1.0), ret[2]); - EXPECT_FLOAT_EQ(15.0 + exp(0.0), ret[3]); -} -TEST(deserializer_stdvec_scalar, read_lb_constrain_jacobian) { - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(0.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = -1.5; - auto ret = deserializer.read_lb, true>( - std::vector{1.0, 5.0, -2.0, 15.0}, lp, 4); - EXPECT_FLOAT_EQ(1.0 + exp(-2.0), ret[0]); - EXPECT_FLOAT_EQ(5.0 + exp(3.0), ret[1]); - EXPECT_FLOAT_EQ(-2.0 + exp(-1.0), ret[2]); - EXPECT_FLOAT_EQ(15.0 + exp(0.0), ret[3]); - EXPECT_FLOAT_EQ(-1.5 - 2.0 + 3.0 - 1.0, lp); -} +// unit vector -// ub - -TEST(deserializer_stdvec_scalar, read_ub_constrain) { +TEST(deserializer_array, unit_vector) { std::vector theta_i; std::vector theta; - theta.push_back(-2.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(0.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = 0; - auto ret = deserializer.read_ub, false>( - std::vector{1.0, 5.0, -2, 15}, lp, 4); - EXPECT_FLOAT_EQ(1.0 - exp(-2.0), ret[0]); - EXPECT_FLOAT_EQ(5.0 - exp(3.0), ret[1]); - EXPECT_FLOAT_EQ(-2.0 - exp(-1.0), ret[2]); - EXPECT_FLOAT_EQ(15.0 - exp(0.0), ret[3]); -} -TEST(deserializer_stdvec_scalar, read_ub_constrain_jacobian) { - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(0.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = -12.9; - auto ret = deserializer.read_ub, false>( - std::vector{1.0, 5.0, -2, 15}, lp, 4); - EXPECT_FLOAT_EQ(1.0 - exp(-2.0), ret[0]); - EXPECT_FLOAT_EQ(5.0 - exp(3.0), ret[1]); - EXPECT_FLOAT_EQ(-2.0 - exp(-1.0), ret[2]); - EXPECT_FLOAT_EQ(15.0 - exp(0.0), ret[3]); - EXPECT_FLOAT_EQ(-12.9 - 2.0 + 3.0 - 1.0, lp); -} - -// lub - -const double inv_logit_m2 = 0.1192029; // stan::math::inv_logit(-2.0) -const double inv_logit_m1 = 0.2689414; // stan::math::inv_logit(-1.0) -const double inv_logit_0 = 0.5; // stan::math::inv_logit(0) -const double inv_logit_3 = 0.9525741; // stan::math::inv_logit(3.0) - -TEST(deserializer_stdvec_scalar, read_lub_constrain) { - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(0.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = 0; - std::vector lb{0.0, 3.0, -3.0, -15.0}; - std::vector ub{1.0, 5.0, 2.0, 15.0}; - auto ret = deserializer.read_lub, false>(lb, ub, lp, 4); - EXPECT_FLOAT_EQ(inv_logit_m2, ret[0]); - EXPECT_FLOAT_EQ(3.0 + 2.0 * inv_logit_3, ret[1]); - EXPECT_FLOAT_EQ(-3.0 + 5.0 * inv_logit_m1, ret[2]); - EXPECT_FLOAT_EQ(-15.0 + 30.0 * inv_logit_0, ret[3]); -} -TEST(deserializer_stdvec_scalar, read_lub_constrain_jacobian) { - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(0.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = -7.2; - std::vector lb{0.0, 3.0, -3.0, -15.0}; - std::vector ub{1.0, 5.0, 2.0, 15.0}; - auto ret = deserializer.read_lub, true>(lb, ub, lp, 4); - EXPECT_FLOAT_EQ(0.0 + 1.0 * inv_logit_m2, ret[0]); - EXPECT_FLOAT_EQ(3.0 + 2.0 * inv_logit_3, ret[1]); - EXPECT_FLOAT_EQ(-3.0 + 5.0 * inv_logit_m1, ret[2]); - EXPECT_FLOAT_EQ(-15.0 + 30.0 * inv_logit_0, ret[3]); - double expected_lp = -7.2 - + log((1.0 - 0.0) * inv_logit_m2 * (1 - inv_logit_m2)) - + log((5.0 - 3.0) * inv_logit_3 * (1 - inv_logit_3)) - + log((2.0 - -3.0) * inv_logit_m1 * (1 - inv_logit_m1)) - + log((15.0 - -15.0) * inv_logit_0 * (1 - inv_logit_0)); - EXPECT_FLOAT_EQ(expected_lp, lp); -} + for (size_t i = 0; i < 100U; ++i) + theta.push_back(static_cast(i)); -// offset multiplier + stan::io::deserializer deserializer1(theta, theta_i); + stan::io::deserializer deserializer2(theta, theta_i); + + // no jac + { + double lp_ref = 0.0; + double lp = 0.0; + auto y = deserializer1.read_unit_vector, false>(lp, 4, 3); + for(size_t i = 0; i < 4; ++i) { + stan::test::expect_near_rel("test_std_vector_deserializer", y[i], + deserializer2.read_unit_vector(lp_ref, 3)); + } + EXPECT_FLOAT_EQ(lp_ref, lp); + } -TEST(deserializer_stdvec_scalar, offset_multiplier_constrain) { - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(0.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = 0; - std::vector offset{0, 3, -3, -15}; - std::vector mult{1.0, 5.0, 2.0, 15}; - auto ret = deserializer.read_offset_multiplier, false>( - offset, mult, lp, 4); - EXPECT_FLOAT_EQ(-2.0, ret[0]); - EXPECT_FLOAT_EQ(3.0 + 5.0 * 3.0, ret[1]); - EXPECT_FLOAT_EQ(-3.0 + 2.0 * -1.0, ret[2]); - EXPECT_FLOAT_EQ(-15.0, ret[3]); -} -TEST(deserializer_stdvec_scalar, offset_multiplier_constrain_jacobian) { - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(0.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = -7.2; - std::vector offset{0, 3, -3, -15}; - std::vector mult{1.0, 5.0, 2.0, 15}; - auto ret = deserializer.read_offset_multiplier, true>( - offset, mult, lp, 4); - EXPECT_FLOAT_EQ(-2.0, ret[0]); - EXPECT_FLOAT_EQ(3.0 + 5.0 * 3.0, ret[1]); - EXPECT_FLOAT_EQ(-3.0 + 2.0 * -1.0, ret[2]); - EXPECT_FLOAT_EQ(-15.0, ret[3]); - double expected_lp = -7.2 + log(1.0) + log(5.0) + log(2.0) + log(15.0); - EXPECT_FLOAT_EQ(expected_lp, lp); + // jac + { + double lp_ref = 0.0; + double lp = 0.0; + auto y = deserializer1.read_unit_vector, true>(lp, 4, 3); + for(size_t i = 0; i < 4; ++i) { + stan::test::expect_near_rel("test_std_vector_deserializer", y[i], + deserializer2.read_unit_vector(lp_ref, 3)); + } + EXPECT_FLOAT_EQ(lp_ref, lp); + } } -// vectors +// simplex -TEST(deserializer_stdvec_vector, read) { +TEST(deserializer_array, simplex) { std::vector theta_i; std::vector theta; for (size_t i = 0; i < 100U; ++i) theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - for (size_t i = 0; i < 7U; ++i) { - double x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - auto y = deserializer.read>(4, 4); - EXPECT_EQ(4, y.size()); - double sentinal = 7; - for (int i = 0; i < 4; ++i) { - EXPECT_EQ(4, y[i].rows()); - EXPECT_EQ(1, y[i].cols()); - for (int j = 0; j < 4; ++j) { - EXPECT_FLOAT_EQ(sentinal, y[i][j]); - ++sentinal; + + stan::io::deserializer deserializer1(theta, theta_i); + stan::io::deserializer deserializer2(theta, theta_i); + + // no jac + { + double lp_ref = 0.0; + double lp = 0.0; + auto y = deserializer1.read_simplex, false>(lp, 4, 3); + for(size_t i = 0; i < 4; ++i) { + stan::test::expect_near_rel("test_std_vector_deserializer", y[i], + deserializer2.read_simplex(lp_ref, 3)); } + EXPECT_FLOAT_EQ(lp_ref, lp); } -} - -// Need to add unit vector and simplex constrain/lp tests -TEST(deserializer_stdvec_vector, ordered_constrain) { - std::vector theta_i; - std::vector theta; - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); - double v0 = 3.0; - double v1 = v0 + exp(-1.0); - double v2 = v1 + exp(-2.0); - double v3 = v2 + exp(0.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = 0; - auto phi( - deserializer.read_ordered, false>(lp, 2, 4)); - EXPECT_EQ(2, phi.size()); - for (int i = 0; i < 2; ++i) { - EXPECT_EQ(4, phi[i].rows()); - EXPECT_EQ(1, phi[i].cols()); - EXPECT_FLOAT_EQ(v0, phi[i][0]); - EXPECT_FLOAT_EQ(v1, phi[i][1]); - EXPECT_FLOAT_EQ(v2, phi[i][2]); - EXPECT_FLOAT_EQ(v3, phi[i][3]); + // jac + { + double lp_ref = 0.0; + double lp = 0.0; + auto y = deserializer1.read_simplex, true>(lp, 4, 3); + for(size_t i = 0; i < 4; ++i) { + stan::test::expect_near_rel("test_std_vector_deserializer", y[i], + deserializer2.read_simplex(lp_ref, 3)); + } + EXPECT_FLOAT_EQ(lp_ref, lp); } } -TEST(deserializer_stdvec_vector, ordered_constrain_jacobian) { - std::vector theta_i; - std::vector theta; - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); - double v0 = 3.0; - double v1 = v0 + exp(-1.0); - double v2 = v1 + exp(-2.0); - double v3 = v2 + exp(0.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = -101.1; - double expected_lp = lp - 1.0 - 2.0 + 0.0 - 1.0 - 2.0 + 0.0; - auto phi( - deserializer.read_ordered, true>(lp, 2, 4)); - EXPECT_FLOAT_EQ(v0, phi[0][0]); - EXPECT_FLOAT_EQ(v1, phi[0][1]); - EXPECT_FLOAT_EQ(v2, phi[0][2]); - EXPECT_FLOAT_EQ(v3, phi[0][3]); - EXPECT_FLOAT_EQ(v0, phi[1][0]); - EXPECT_FLOAT_EQ(v1, phi[1][1]); - EXPECT_FLOAT_EQ(v2, phi[1][2]); - EXPECT_FLOAT_EQ(v3, phi[1][3]); - EXPECT_FLOAT_EQ(expected_lp, lp); -} -TEST(deserializer_stdvec_vector, positive_ordered_constrain) { - std::vector theta_i; - std::vector theta; - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); - double v0 = exp(3.0); - double v1 = v0 + exp(-1.0); - double v2 = v1 + exp(-2.0); - double v3 = v2 + exp(0.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = 0; - auto phi( - deserializer.read_positive_ordered, false>( - lp, 2, 4)); - EXPECT_FLOAT_EQ(v0, phi[0][0]); - EXPECT_FLOAT_EQ(v1, phi[0][1]); - EXPECT_FLOAT_EQ(v2, phi[0][2]); - EXPECT_FLOAT_EQ(v3, phi[0][3]); - EXPECT_FLOAT_EQ(v0, phi[1][0]); - EXPECT_FLOAT_EQ(v1, phi[1][1]); - EXPECT_FLOAT_EQ(v2, phi[1][2]); - EXPECT_FLOAT_EQ(v3, phi[1][3]); -} +// ordered -TEST(deserializer_stdvec_vector, positive_ordered_constrain_jacobian) { +TEST(deserializer_array, ordered) { std::vector theta_i; std::vector theta; - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); - double v0 = exp(3.0); - double v1 = v0 + exp(-1.0); - double v2 = v1 + exp(-2.0); - double v3 = v2 + exp(0.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = -101.1; - double expected_lp = lp + 3.0 - 1.0 - 2.0 + 0.0 + 3.0 - 1.0 - 2.0 + 0.0; - auto phi( - deserializer.read_positive_ordered, true>( - lp, 2, 4)); - EXPECT_FLOAT_EQ(v0, phi[0][0]); - EXPECT_FLOAT_EQ(v1, phi[0][1]); - EXPECT_FLOAT_EQ(v2, phi[0][2]); - EXPECT_FLOAT_EQ(v3, phi[0][3]); - EXPECT_FLOAT_EQ(v0, phi[1][0]); - EXPECT_FLOAT_EQ(v1, phi[1][1]); - EXPECT_FLOAT_EQ(v2, phi[1][2]); - EXPECT_FLOAT_EQ(v3, phi[1][3]); - EXPECT_FLOAT_EQ(expected_lp, lp); -} + for (size_t i = 0; i < 100U; ++i) + theta.push_back(static_cast(i)); -TEST(deserializer_stdvec_vector, offset_multiplier_constrain) { - std::vector theta_i; - std::vector theta; - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = 0; - auto phi( - deserializer.read_offset_multiplier, false>( - 0, 1, lp, 2, 4)); - for (int i = 0; i < 2; ++i) { - EXPECT_FLOAT_EQ(theta[0], phi[i][0]); - EXPECT_FLOAT_EQ(theta[1], phi[i][1]); - EXPECT_FLOAT_EQ(theta[2], phi[i][2]); - EXPECT_FLOAT_EQ(theta[3], phi[i][3]); + stan::io::deserializer deserializer1(theta, theta_i); + stan::io::deserializer deserializer2(theta, theta_i); + + // no jac + { + double lp_ref = 0.0; + double lp = 0.0; + auto y = deserializer1.read_ordered, false>(lp, 4, 3); + for(size_t i = 0; i < 4; ++i) { + stan::test::expect_near_rel("test_std_vector_deserializer", y[i], + deserializer2.read_ordered(lp_ref, 3)); + } + EXPECT_FLOAT_EQ(lp_ref, lp); } -} -TEST(deserializer_stdvec_vector, offset_multiplier_constrain_lp) { - std::vector theta_i; - std::vector theta; - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = 0; - auto phi( - deserializer.read_offset_multiplier, true>( - 0, 2, lp, 2, 4)); - for (int i = 0; i < 2; ++i) { - EXPECT_FLOAT_EQ(theta[0] * 2, phi[i][0]); - EXPECT_FLOAT_EQ(theta[1] * 2, phi[i][1]); - EXPECT_FLOAT_EQ(theta[2] * 2, phi[i][2]); - EXPECT_FLOAT_EQ(theta[3] * 2, phi[i][3]); + // jac + { + double lp_ref = 0.0; + double lp = 0.0; + auto y = deserializer1.read_ordered, true>(lp, 4, 3); + for(size_t i = 0; i < 4; ++i) { + stan::test::expect_near_rel("test_std_vector_deserializer", y[i], + deserializer2.read_ordered(lp_ref, 3)); + } + EXPECT_FLOAT_EQ(lp_ref, lp); } - EXPECT_FLOAT_EQ(lp, std::log(2) * 8); } -// matrix +// positive ordered -TEST(deserializer_stdvec_matrix, read) { +TEST(deserializer_array, positive_ordered) { std::vector theta_i; std::vector theta; - for (size_t i = 0; i < 100.0; ++i) + for (size_t i = 0; i < 100U; ++i) theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - for (int i = 0; i < 7; ++i) { - double x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - using eig_mat = Eigen::Matrix; - auto y = deserializer.read>(2, 3, 2); - EXPECT_EQ(2, y.size()); - double sentinal = 7; - for (int i = 0; i < 2; ++i) { - EXPECT_EQ(3, y[i].rows()); - EXPECT_EQ(2, y[i].cols()); - for (int j = 0; j < y[i].size(); ++j) { - EXPECT_FLOAT_EQ(sentinal, y[i](j)); - ++sentinal; + + stan::io::deserializer deserializer1(theta, theta_i); + stan::io::deserializer deserializer2(theta, theta_i); + + // no jac + { + double lp_ref = 0.0; + double lp = 0.0; + auto y = deserializer1.read_positive_ordered, false>(lp, 4, 3); + for(size_t i = 0; i < 4; ++i) { + stan::test::expect_near_rel("test_std_vector_deserializer", y[i], + deserializer2.read_positive_ordered(lp_ref, 3)); } + EXPECT_FLOAT_EQ(lp_ref, lp); } -} -TEST(deserializer_stdvec_matrix, matrix_lb_constrain) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - for (int i = 0; i < 7; ++i) { - double x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - double lb = -1.5; - double lp = 0; - auto y = deserializer.read_lb, false>(lb, lp, 2, - 3, 2); - EXPECT_EQ(2, y.size()); - double sentinal = 7; - for (int i = 0; i < 2; ++i) { - EXPECT_EQ(3, y[i].rows()); - EXPECT_EQ(2, y[i].cols()); - for (int j = 0; j < y[i].size(); ++j) { - EXPECT_FLOAT_EQ(stan::math::lb_constrain(sentinal, lb), y[i](j)); - ++sentinal; + // jac + { + double lp_ref = 0.0; + double lp = 0.0; + auto y = deserializer1.read_positive_ordered, true>(lp, 4, 3); + for(size_t i = 0; i < 4; ++i) { + stan::test::expect_near_rel("test_std_vector_deserializer", y[i], + deserializer2.read_positive_ordered(lp_ref, 3)); } + EXPECT_FLOAT_EQ(lp_ref, lp); } } -TEST(deserializer_stdvec_matrix, matrix_lb_constrain_lp) { +// chol_cov + +TEST(deserializer_array, chol_cov) { std::vector theta_i; std::vector theta; - for (size_t i = 0; i < 100.0; ++i) + for (size_t i = 0; i < 200U; ++i) theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - for (int i = 0; i < 7; ++i) { - double x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - double lb = -1.5; - double lp = -5.0; - auto y = deserializer.read_lb, true>(lb, lp, 2, - 3, 2); - EXPECT_EQ(2, y.size()); - double sentinal = 7; - for (int i = 0; i < 2; ++i) { - EXPECT_EQ(3, y[i].rows()); - EXPECT_EQ(2, y[i].cols()); - for (int j = 0; j < y[i].size(); ++j) { - EXPECT_FLOAT_EQ(stan::math::lb_constrain(sentinal, lb, lp), y[i](j)); - ++sentinal; + + stan::io::deserializer deserializer1(theta, theta_i); + stan::io::deserializer deserializer2(theta, theta_i); + + // no jac, square + { + double lp_ref = 0.0; + double lp = 0.0; + auto y = deserializer1.read_cholesky_factor_cov, false>(lp, 4, 3, 3); + for(size_t i = 0; i < 4; ++i) { + stan::test::expect_near_rel("test_std_vector_deserializer", y[i], + deserializer2.read_cholesky_factor_cov(lp_ref, 3, 3)); } + EXPECT_FLOAT_EQ(lp_ref, lp); } -} -TEST(deserializer_stdvec_matrix, matrix_ub_constrain) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - for (int i = 0; i < 7; ++i) { - double x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - double ub = 14.1; - double lp = 0; - auto y = deserializer.read_ub, false>(ub, lp, 2, - 3, 2); - EXPECT_EQ(2, y.size()); - double sentinal = 7; - for (int i = 0; i < 2; ++i) { - EXPECT_EQ(3, y[i].rows()); - EXPECT_EQ(2, y[i].cols()); - for (int j = 0; j < y[i].size(); ++j) { - EXPECT_FLOAT_EQ(stan::math::ub_constrain(sentinal, ub), y[i](j)); - ++sentinal; + // jac, square + { + double lp_ref = 0.0; + double lp = 0.0; + auto y = deserializer1.read_cholesky_factor_cov, true>(lp, 4, 3, 3); + for(size_t i = 0; i < 4; ++i) { + stan::test::expect_near_rel("test_std_vector_deserializer", y[i], + deserializer2.read_cholesky_factor_cov(lp_ref, 3, 3)); } + EXPECT_FLOAT_EQ(lp_ref, lp); } -} -TEST(deserializer_stdvec_matrix, matrix_ub_constrain_lp) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - for (int i = 0; i < 7; ++i) { - double x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - double ub = 12.1; - double lp = -5.0; - auto y = deserializer.read_ub, true>(ub, lp, 2, - 3, 2); - EXPECT_EQ(2, y.size()); - double sentinal = 7; - for (int i = 0; i < 2; ++i) { - EXPECT_EQ(3, y[i].rows()); - EXPECT_EQ(2, y[i].cols()); - for (int j = 0; j < y[i].size(); ++j) { - EXPECT_FLOAT_EQ(stan::math::ub_constrain(sentinal, ub, lp), y[i](j)); - ++sentinal; + // no jac, non-square + { + double lp_ref = 0.0; + double lp = 0.0; + auto y = deserializer1.read_cholesky_factor_cov, false>(lp, 4, 3, 2); + for(size_t i = 0; i < 4; ++i) { + stan::test::expect_near_rel("test_std_vector_deserializer", y[i], + deserializer2.read_cholesky_factor_cov(lp_ref, 3, 2)); } + EXPECT_FLOAT_EQ(lp_ref, lp); } -} -TEST(deserializer_stdvec_matrix, matrix_lub_constrain) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - for (int i = 0; i < 7; ++i) { - double x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - double lb = 3.5; - double ub = 14.1; - double lp = 0; - auto y = deserializer.read_lub, false>( - lb, ub, lp, 2, 3, 2); - EXPECT_EQ(2, y.size()); - double sentinal = 7; - for (int i = 0; i < 2; ++i) { - EXPECT_EQ(3, y[i].rows()); - EXPECT_EQ(2, y[i].cols()); - for (int j = 0; j < y[i].size(); ++j) { - EXPECT_FLOAT_EQ(stan::math::lub_constrain(sentinal, lb, ub), y[i](j)); - ++sentinal; + // jac, non-square + { + double lp_ref = 0.0; + double lp = 0.0; + auto y = deserializer1.read_cholesky_factor_cov, true>(lp, 4, 3, 2); + for(size_t i = 0; i < 4; ++i) { + stan::test::expect_near_rel("test_std_vector_deserializer", y[i], + deserializer2.read_cholesky_factor_cov(lp_ref, 3, 2)); } + EXPECT_FLOAT_EQ(lp_ref, lp); } } -TEST(deserializer_stdvec_matrix, matrix_lub_constrain_lp) { +// chol_corr + +TEST(deserializer_array, chol_corr) { std::vector theta_i; std::vector theta; - for (size_t i = 0; i < 100.0; ++i) + for (size_t i = 0; i < 100U; ++i) theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - for (int i = 0; i < 7; ++i) { - double x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - double lb = 4.1; - double ub = 12.1; - double lp = -5.0; - auto y = deserializer.read_lub, true>(lb, ub, lp, - 2, 3, 2); - EXPECT_EQ(2, y.size()); - double sentinal = 7; - for (int i = 0; i < 2; ++i) { - EXPECT_EQ(3, y[i].rows()); - EXPECT_EQ(2, y[i].cols()); - for (int j = 0; j < y[i].size(); ++j) { - EXPECT_FLOAT_EQ(stan::math::lub_constrain(sentinal, lb, ub, lp), y[i](j)); - ++sentinal; - } - } -} -TEST(deserializer_stdvec_matrix, corr_matrix_constrain) { - using Eigen::Dynamic; - using Eigen::Matrix; - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(-1.0); - theta.push_back(0.0); - theta.push_back(0.5); - theta.push_back(1.0); - theta.push_back(2.0); - theta.push_back(1.0); - theta.push_back(-2.0); - theta.push_back(-1.0); - theta.push_back(0.0); - theta.push_back(0.5); - theta.push_back(1.0); - theta.push_back(2.0); - theta.push_back(1.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = 0; - auto R( - deserializer.read_corr, false>(lp, 2, 3U)); - EXPECT_EQ(2, R.size()); - for (int k = 0; k < 2; k++) { - EXPECT_EQ(3, R[k].rows()); - EXPECT_EQ(3, R[k].cols()); - for (size_t i = 0; i < 3U; ++i) { - EXPECT_FLOAT_EQ(1.0, R[k](i, i)); - for (size_t j = i + 1; j < 3U; ++j) - EXPECT_FLOAT_EQ(R[k](i, j), R[k](j, i)); + stan::io::deserializer deserializer1(theta, theta_i); + stan::io::deserializer deserializer2(theta, theta_i); + + // no jac + { + double lp_ref = 0.0; + double lp = 0.0; + auto y = deserializer1.read_cholesky_factor_corr, false>(lp, 4, 3); + for(size_t i = 0; i < 4; ++i) { + stan::test::expect_near_rel("test_std_vector_deserializer", y[i], + deserializer2.read_cholesky_factor_corr(lp_ref, 3)); } - Eigen::SelfAdjointEigenSolver< - Eigen::Matrix> - solver(R[k], Eigen::EigenvaluesOnly); - assert(solver.eigenvalues()[0] > 1E-10); + EXPECT_FLOAT_EQ(lp_ref, lp); } -} -TEST(deserializer_stdvec_matrix, corr_matrix_constrain_jacobian) { - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(-1.0); - theta.push_back(0.0); - theta.push_back(0.5); - theta.push_back(1.0); - theta.push_back(2.0); - theta.push_back(1.0); - theta.push_back(-2.0); - theta.push_back(-1.0); - theta.push_back(0.0); - theta.push_back(0.5); - theta.push_back(1.0); - theta.push_back(2.0); - theta.push_back(1.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = -9.2; - auto R(deserializer.read_corr, true>(lp, 2, 3U)); - EXPECT_EQ(2, R.size()); - for (int k = 0; k < 2; k++) { - EXPECT_EQ(3, R[k].rows()); - EXPECT_EQ(3, R[k].cols()); - for (size_t i = 0; i < 3U; ++i) { - EXPECT_FLOAT_EQ(1.0, R[k](i, i)); - for (size_t j = i + 1; j < 3U; ++j) - EXPECT_FLOAT_EQ(R[k](i, j), R[k](j, i)); + // jac + { + double lp_ref = 0.0; + double lp = 0.0; + auto y = deserializer1.read_cholesky_factor_corr, true>(lp, 4, 3); + for(size_t i = 0; i < 4; ++i) { + stan::test::expect_near_rel("test_std_vector_deserializer", y[i], + deserializer2.read_cholesky_factor_corr(lp_ref, 3)); } - Eigen::SelfAdjointEigenSolver< - Eigen::Matrix> - solver(R[k], Eigen::EigenvaluesOnly); - assert(solver.eigenvalues()[0] > 1E-10); + EXPECT_FLOAT_EQ(lp_ref, lp); } } -TEST(deserializer_stdvec_matrix, cov_matrix_constrain) { +// cov_matrix + +TEST(deserializer_array, cov_matrix) { std::vector theta_i; std::vector theta; - theta.push_back(-2.0); - theta.push_back(-1.0); - theta.push_back(0.0); - theta.push_back(0.5); - theta.push_back(1.0); - theta.push_back(2.0); - theta.push_back(1.0); - theta.push_back(-2.0); - theta.push_back(-1.0); - theta.push_back(0.0); - theta.push_back(0.5); - theta.push_back(1.0); - theta.push_back(2.0); - theta.push_back(1.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = 0; - auto S(deserializer.read_cov_matrix, false>( - lp, 2, 3U)); - EXPECT_EQ(2, S.size()); - for (int k = 0; k < 2; ++k) { - EXPECT_EQ(3, S[k].rows()); - EXPECT_EQ(3, S[k].cols()); - for (size_t i = 0; i < 3U; ++i) { - for (size_t j = i + 1; j < 3U; ++j) { - EXPECT_FLOAT_EQ(S[k](i, j), S[k](j, i)); - } + for (size_t i = 0; i < 100U; ++i) + theta.push_back(static_cast(i)); + + stan::io::deserializer deserializer1(theta, theta_i); + stan::io::deserializer deserializer2(theta, theta_i); + + // no jac + { + double lp_ref = 0.0; + double lp = 0.0; + auto y = deserializer1.read_cov_matrix, false>(lp, 4, 3); + for(size_t i = 0; i < 4; ++i) { + stan::test::expect_near_rel("test_std_vector_deserializer", y[i], + deserializer2.read_cov_matrix(lp_ref, 3)); } - Eigen::SelfAdjointEigenSolver< - Eigen::Matrix> - solver(S[k], Eigen::EigenvaluesOnly); - assert(solver.eigenvalues()[0] - > 1E-10); // check positive definite with smallest eigenvalue > 0 + EXPECT_FLOAT_EQ(lp_ref, lp); } -} -TEST(deserializer_stdvec_matrix, cov_matrix_constrain_jacobian) { - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(-1.0); - theta.push_back(0.0); - theta.push_back(0.5); - theta.push_back(1.0); - theta.push_back(2.0); - theta.push_back(1.0); - theta.push_back(-2.0); - theta.push_back(-1.0); - theta.push_back(0.0); - theta.push_back(0.5); - theta.push_back(1.0); - theta.push_back(2.0); - theta.push_back(1.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = -3.1; - - auto S(deserializer.read_cov_matrix, true>(lp, 2, - 3U)); - - EXPECT_EQ(2, S.size()); - for (int k = 0; k < 2; ++k) { - EXPECT_EQ(3, S[k].rows()); - EXPECT_EQ(3, S[k].cols()); - for (size_t i = 0; i < 3U; ++i) { - for (size_t j = i + 1; j < 3U; ++j) { - EXPECT_FLOAT_EQ(S[k](i, j), S[k](j, i)); - } + // jac + { + double lp_ref = 0.0; + double lp = 0.0; + auto y = deserializer1.read_cov_matrix, true>(lp, 4, 3); + for(size_t i = 0; i < 4; ++i) { + stan::test::expect_near_rel("test_std_vector_deserializer", y[i], + deserializer2.read_cov_matrix(lp_ref, 3)); } - Eigen::SelfAdjointEigenSolver< - Eigen::Matrix> - solver(S[k], Eigen::EigenvaluesOnly); - assert(solver.eigenvalues()[0] - > 1E-10); // check positive definite with smallest eigenvalue > 0 + EXPECT_FLOAT_EQ(lp_ref, lp); } } -TEST(deserializer_stdvec_matrix, cholesky_factor_cov_constrain) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 16; ++i) - theta.push_back(-static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - double lp = 0; - auto L(deserializer - .read_cholesky_factor_cov, false>( - lp, 2U, 3U, 3U)); - EXPECT_NO_THROW(stan::math::check_cholesky_factor( - "test_cholesky_factor_constrain", "L", L[0])); - EXPECT_EQ(2, L.size()); - EXPECT_EQ(3, L[0].rows()); - EXPECT_EQ(3, L[0].cols()); - EXPECT_EQ(9, L[0].size()); -} - -TEST(deserializer_stdvec_matrix, cholesky_factor_cov_constrain_asymmetric) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 16; ++i) - theta.push_back(-static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - double lp = 0; - auto L(deserializer - .read_cholesky_factor_cov, false>( - lp, 2U, 3U, 2U)); - EXPECT_NO_THROW(stan::math::check_cholesky_factor( - "test_cholesky_factor_constrain", "L", L[0])); - EXPECT_EQ(2, L.size()); - EXPECT_EQ(3, L[0].rows()); - EXPECT_EQ(2, L[0].cols()); - EXPECT_EQ(6, L[0].size()); -} -TEST(deserializer_stdvec_matrix, cholesky_factor_cov_constrain_jacobian) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 16; ++i) - theta.push_back(-static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - double lp = 1.9; - auto L( - deserializer.read_cholesky_factor_cov, true>( - lp, 2U, 3U, 3U)); - EXPECT_NO_THROW(stan::math::check_cholesky_factor( - "test_cholesky_factor_constrain", "L", L[0])); - EXPECT_EQ(2, L.size()); - EXPECT_EQ(3, L[0].rows()); - EXPECT_EQ(3, L[0].cols()); - EXPECT_EQ(9, L[0].size()); - EXPECT_EQ(1.9 + log(L[0](0, 0)) + log(L[0](1, 1)) + log(L[0](2, 2)) - + +log(L[1](0, 0)) + log(L[1](1, 1)) + log(L[1](2, 2)), - lp); -} -TEST(deserializer_stdvec_matrix, - cholesky_factor_cov_constrain_jacobian_asymmetric) { - std::vector theta_i; - std::vector theta; - for (int i = 0; i < 24; ++i) - theta.push_back(-static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - double lp = 1.9; - auto L( - deserializer.read_cholesky_factor_cov, true>( - lp, 2U, 4U, 3U)); - EXPECT_NO_THROW(stan::math::check_cholesky_factor( - "test_cholesky_factor_constrain", "L", L[0])); - EXPECT_EQ(2, L.size()); - EXPECT_EQ(4, L[0].rows()); - EXPECT_EQ(3, L[0].cols()); - EXPECT_EQ(12, L[0].size()); - EXPECT_EQ(1.9 + log(L[0](0, 0)) + log(L[0](1, 1)) + log(L[0](2, 2)) - + +log(L[1](0, 0)) + log(L[1](1, 1)) + log(L[1](2, 2)), - lp); -} +// corr_matrix -TEST(deserializer_stdvec_matrix, cholesky_factor_corr_constrain) { +TEST(deserializer_array, corr_matrix) { std::vector theta_i; std::vector theta; - for (int i = 0; i < 16; ++i) - theta.push_back(-static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - double lp = 0; - auto L(deserializer - .read_cholesky_factor_corr, false>( - lp, 2U, 3U)); - EXPECT_NO_THROW(stan::math::check_cholesky_factor_corr( - "test_cholesky_factor_corr_constrain", "L", L[0])); - EXPECT_EQ(3, L[0].rows()); - EXPECT_EQ(3, L[0].cols()); - EXPECT_EQ(9, L[0].size()); -} - -// Need to add cholesky factor corr constrain lp test + for (size_t i = 0; i < 100U; ++i) + theta.push_back(static_cast(i)); -TEST(deserializer_stdvec_matrix, offset_multiplier_constrain) { - std::vector theta_i; - std::vector theta; - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = 0; - auto phi( - deserializer.read_offset_multiplier, false>( - 0, 1, lp, 2, 2, 2)); - for (int i = 0; i < 2; ++i) { - EXPECT_FLOAT_EQ(theta[0], phi[i](0, 0)); - EXPECT_FLOAT_EQ(theta[1], phi[i](1, 0)); - EXPECT_FLOAT_EQ(theta[2], phi[i](0, 1)); - EXPECT_FLOAT_EQ(theta[3], phi[i](1, 1)); + stan::io::deserializer deserializer1(theta, theta_i); + stan::io::deserializer deserializer2(theta, theta_i); + + // no jac + { + double lp_ref = 0.0; + double lp = 0.0; + auto y = deserializer1.read_corr_matrix, false>(lp, 4, 3); + for(size_t i = 0; i < 4; ++i) { + stan::test::expect_near_rel("test_std_vector_deserializer", y[i], + deserializer2.read_corr_matrix(lp_ref, 3)); + } + EXPECT_FLOAT_EQ(lp_ref, lp); } -} -TEST(deserializer_stdvec_matrix, offset_multiplier_constrain_lp) { - std::vector theta_i; - std::vector theta; - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = 0; - auto phi( - deserializer.read_offset_multiplier, true>( - 0, 2, lp, 2, 2, 2)); - for (int i = 0; i < 2; ++i) { - EXPECT_FLOAT_EQ(theta[0] * 2, phi[i](0, 0)); - EXPECT_FLOAT_EQ(theta[1] * 2, phi[i](1, 0)); - EXPECT_FLOAT_EQ(theta[2] * 2, phi[i](0, 1)); - EXPECT_FLOAT_EQ(theta[3] * 2, phi[i](1, 1)); + // jac + { + double lp_ref = 0.0; + double lp = 0.0; + auto y = deserializer1.read_corr_matrix, true>(lp, 4, 3); + for(size_t i = 0; i < 4; ++i) { + stan::test::expect_near_rel("test_std_vector_deserializer", y[i], + deserializer2.read_corr_matrix(lp_ref, 3)); + } + EXPECT_FLOAT_EQ(lp_ref, lp); } - EXPECT_FLOAT_EQ(lp, std::log(2) * 8); } diff --git a/src/test/unit/io/deserializer_test.cpp b/src/test/unit/io/deserializer_test.cpp index 6e0ad7dabb9..ff5ba9dc68b 100644 --- a/src/test/unit/io/deserializer_test.cpp +++ b/src/test/unit/io/deserializer_test.cpp @@ -1,7 +1,39 @@ #include +// expect_near_rel comes from lib/stan_math +#include #include -TEST(deserializer, eigen_input) { +TEST(deserializer_scalar, read) { + std::vector theta_i; + std::vector theta; + theta.push_back(1.0); + theta.push_back(2.0); + stan::io::deserializer deserializer(theta, theta_i); + double x = deserializer.read(); + EXPECT_FLOAT_EQ(1.0, x); + double y = deserializer.read(); + EXPECT_FLOAT_EQ(2.0, y); + EXPECT_EQ(0U, deserializer.available()); +} + +TEST(deserializer_scalar, complex_read) { + std::vector theta_i; + std::vector theta; + theta.push_back(1.0); + theta.push_back(2.0); + theta.push_back(3.0); + theta.push_back(4.0); + stan::io::deserializer deserializer(theta, theta_i); + std::complex x = deserializer.read>(); + EXPECT_FLOAT_EQ(1.0, x.real()); + EXPECT_FLOAT_EQ(2.0, x.imag()); + std::complex y = deserializer.read>(); + EXPECT_FLOAT_EQ(3.0, y.real()); + EXPECT_FLOAT_EQ(4.0, y.imag()); + EXPECT_EQ(0U, deserializer.available()); +} + +TEST(deserializer, read_int) { Eigen::Matrix theta_i(1); Eigen::VectorXd theta(2); theta[0] = 1.0; @@ -17,49 +49,62 @@ TEST(deserializer, eigen_input) { EXPECT_EQ(0U, deserializer.available()); } -TEST(deserializer, zeroSizeVecs) { +// vector + +TEST(deserializer_vector, read) { std::vector theta_i; std::vector theta; - theta.push_back(1.0); + for (size_t i = 0; i < 100U; ++i) + theta.push_back(static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); + for (size_t i = 0; i < 7U; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + Eigen::Matrix y + = deserializer.read(4); + EXPECT_EQ(4, y.rows()); + EXPECT_EQ(1, y.cols()); + EXPECT_EQ(4, y.size()); + EXPECT_FLOAT_EQ(7.0, y[0]); + EXPECT_FLOAT_EQ(8.0, y[1]); + EXPECT_FLOAT_EQ(9.0, y[2]); + EXPECT_FLOAT_EQ(10.0, y[3]); - EXPECT_FLOAT_EQ(1.0, deserializer.read()); // finish available - - EXPECT_EQ(0, deserializer.read>(0).size()); - EXPECT_EQ(0, deserializer.read(0).size()); - EXPECT_EQ(0, deserializer.read(0).size()); - EXPECT_EQ(0, deserializer.read(0, 3).size()); - EXPECT_EQ(0, deserializer.read(3, 0).size()); - EXPECT_EQ(0, deserializer - .read>>(0, 0, 0, 0) - .size()); + double z = deserializer.read(); + EXPECT_FLOAT_EQ(11.0, z); } -TEST(deserializer, eos_exception) { - std::vector theta; - theta.push_back(1.0); - theta.push_back(2.0); +TEST(deserializer_vector, complex_read) { std::vector theta_i; - theta_i.push_back(1); + std::vector theta; + for (size_t i = 0; i < 100U; ++i) + theta.push_back(static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); + for (size_t i = 0; i < 7U; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + using complex_vec = Eigen::Matrix, Eigen::Dynamic, 1>; + complex_vec y = deserializer.read(4); + EXPECT_EQ(4, y.rows()); + EXPECT_EQ(1, y.cols()); + EXPECT_EQ(4, y.size()); + double sentinal = 7; + for (int i = 0; i < y.size(); ++i) { + EXPECT_FLOAT_EQ(sentinal, y[i].real()); + ++sentinal; + EXPECT_FLOAT_EQ(sentinal, y[i].imag()); + ++sentinal; + } - EXPECT_EQ(2U, deserializer.available()); - EXPECT_EQ(1U, deserializer.available_i()); - - EXPECT_NO_THROW(deserializer.read()); - EXPECT_NO_THROW(deserializer.read()); - EXPECT_THROW(deserializer.read(), std::runtime_error); - - // should go back to working - EXPECT_NO_THROW(deserializer.read()); - EXPECT_THROW(deserializer.read(), std::runtime_error); - - // should keep throwing - EXPECT_THROW(deserializer.read(), std::runtime_error); - EXPECT_THROW(deserializer.read(), std::runtime_error); + double z = deserializer.read(); + EXPECT_FLOAT_EQ(15.0, z); } -TEST(deserializer_rowvector, read) { +// row vector + +TEST(deserializer_row_vector, read) { std::vector theta_i; std::vector theta; for (size_t i = 0; i < 100U; ++i) @@ -83,108 +128,286 @@ TEST(deserializer_rowvector, read) { EXPECT_FLOAT_EQ(11.0, z); } -// scalar bounds -TEST(deserializer_scalar, read) { +TEST(deserializer_row_vector, complex_read) { std::vector theta_i; std::vector theta; - theta.push_back(1.0); - theta.push_back(2.0); + for (size_t i = 0; i < 100U; ++i) + theta.push_back(static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); - double x = deserializer.read(); - EXPECT_FLOAT_EQ(1.0, x); - double y = deserializer.read(); - EXPECT_FLOAT_EQ(2.0, y); - EXPECT_EQ(0U, deserializer.available()); -} + for (size_t i = 0; i < 7U; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + using complex_row_vec = Eigen::Matrix, 1, Eigen::Dynamic>; + complex_row_vec y = deserializer.read(4); + EXPECT_EQ(1, y.rows()); + EXPECT_EQ(4, y.cols()); + EXPECT_EQ(4, y.size()); + double sentinal = 7; + for (int i = 0; i < y.size(); ++i) { + EXPECT_FLOAT_EQ(sentinal, y[i].real()); + ++sentinal; + EXPECT_FLOAT_EQ(sentinal, y[i].imag()); + ++sentinal; + } -TEST(deserializer_scalar, complex_read) { - std::vector theta_i; - std::vector theta; - theta.push_back(1.0); - theta.push_back(2.0); - theta.push_back(3.0); - theta.push_back(4.0); - stan::io::deserializer deserializer(theta, theta_i); - std::complex x = deserializer.read>(); - EXPECT_FLOAT_EQ(1.0, x.real()); - EXPECT_FLOAT_EQ(2.0, x.imag()); - std::complex y = deserializer.read>(); - EXPECT_FLOAT_EQ(3.0, y.real()); - EXPECT_FLOAT_EQ(4.0, y.imag()); - EXPECT_EQ(0U, deserializer.available()); + double z = deserializer.read(); + EXPECT_FLOAT_EQ(15.0, z); } -TEST(deserializer_scalar, read_lb_constrain) { +// matrix + +TEST(deserializer_matrix, read) { std::vector theta_i; std::vector theta; - theta.push_back(-2.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(0.0); + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); - double lp = 0.0; - EXPECT_FLOAT_EQ(1.0 + exp(-2.0), - (deserializer.read_lb(1.0, lp))); - EXPECT_FLOAT_EQ(5.0 + exp(3.0), - (deserializer.read_lb(5.0, lp))); - EXPECT_FLOAT_EQ(-2.0 + exp(-1.0), - (deserializer.read_lb(-2.0, lp))); - EXPECT_FLOAT_EQ(15.0 + exp(0.0), - (deserializer.read_lb(15.0, lp))); + for (int i = 0; i < 7; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + using eig_mat = Eigen::Matrix; + eig_mat y = deserializer.read(3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(7.0, y(0, 0)); + EXPECT_FLOAT_EQ(8.0, y(1, 0)); + EXPECT_FLOAT_EQ(9.0, y(2, 0)); + EXPECT_FLOAT_EQ(10.0, y(0, 1)); + EXPECT_FLOAT_EQ(11.0, y(1, 1)); + EXPECT_FLOAT_EQ(12.0, y(2, 1)); + + double a = deserializer.read(); + EXPECT_FLOAT_EQ(13.0, a); } -TEST(deserializer_scalar, read_lb_constrain_jacobian) { +TEST(deserializer_matrix, complex_read) { std::vector theta_i; std::vector theta; - theta.push_back(-2.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(0.0); + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); - double lp = -1.5; - EXPECT_FLOAT_EQ(1.0 + exp(-2.0), - (deserializer.read_lb(1.0, lp))); - EXPECT_FLOAT_EQ(5.0 + exp(3.0), - (deserializer.read_lb(5.0, lp))); - EXPECT_FLOAT_EQ(-2.0 + exp(-1.0), - (deserializer.read_lb(-2.0, lp))); - EXPECT_FLOAT_EQ(15.0 + exp(0.0), - (deserializer.read_lb(15.0, lp))); - EXPECT_FLOAT_EQ(-1.5 - 2.0 + 3.0 - 1.0, lp); + for (int i = 0; i < 7; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + using eig_mat + = Eigen::Matrix, Eigen::Dynamic, Eigen::Dynamic>; + eig_mat y = deserializer.read(3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + double sentinal = 7; + for (int i = 0; i < y.size(); ++i) { + EXPECT_FLOAT_EQ(sentinal, y(i).real()); + sentinal++; + EXPECT_FLOAT_EQ(sentinal, y(i).imag()); + sentinal++; + } } -// ub +// array -TEST(deserializer_scalar, read_ub_constrain) { +TEST(deserializer_array, read) { std::vector theta_i; std::vector theta; - theta.push_back(-2.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(0.0); + for (size_t i = 0; i < 100U; ++i) + theta.push_back(static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); - double lp = 0; - EXPECT_FLOAT_EQ(1.0 - exp(-2.0), - (deserializer.read_ub(1.0, lp))); - EXPECT_FLOAT_EQ(5.0 - exp(3.0), - (deserializer.read_ub(5.0, lp))); - EXPECT_FLOAT_EQ(-2.0 - exp(-1.0), - (deserializer.read_ub(-2.0, lp))); - EXPECT_FLOAT_EQ(15.0 - exp(0.0), - (deserializer.read_ub(15.0, lp))); + for (size_t i = 0; i < 7U; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + std::vector y + = deserializer.read>(4); + EXPECT_EQ(4, y.size()); + EXPECT_FLOAT_EQ(7.0, y[0]); + EXPECT_FLOAT_EQ(8.0, y[1]); + EXPECT_FLOAT_EQ(9.0, y[2]); + EXPECT_FLOAT_EQ(10.0, y[3]); + + double z = deserializer.read(); + EXPECT_FLOAT_EQ(11.0, z); } -TEST(deserializer_scalar, read_ub_constrain_jacobian) { + +TEST(deserializer_array, complex_read) { std::vector theta_i; std::vector theta; - theta.push_back(-2.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(0.0); + for (size_t i = 0; i < 100U; ++i) + theta.push_back(static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); - double lp = -12.9; - EXPECT_FLOAT_EQ(1.0 - exp(-2.0), - (deserializer.read_ub(1.0, lp))); - EXPECT_FLOAT_EQ(5.0 - exp(3.0), + for (size_t i = 0; i < 7U; ++i) { + double x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x); + } + using complex_array = std::vector>; + complex_array y = deserializer.read(4); + EXPECT_EQ(4, y.size()); + double sentinal = 7; + for (int i = 0; i < y.size(); ++i) { + EXPECT_FLOAT_EQ(sentinal, y[i].real()); + ++sentinal; + EXPECT_FLOAT_EQ(sentinal, y[i].imag()); + ++sentinal; + } + + double z = deserializer.read(); + EXPECT_FLOAT_EQ(15.0, z); +} + +TEST(deserializer_array, read_vector) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100U; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + std::vector y + = deserializer.read>(4, 2); + EXPECT_EQ(4, y.size()); + EXPECT_FLOAT_EQ(0.0, y[0](0)); + EXPECT_FLOAT_EQ(1.0, y[0](1)); + EXPECT_FLOAT_EQ(2.0, y[1](0)); + EXPECT_FLOAT_EQ(3.0, y[1](1)); + EXPECT_FLOAT_EQ(4.0, y[2](0)); + EXPECT_FLOAT_EQ(5.0, y[2](1)); + EXPECT_FLOAT_EQ(6.0, y[3](0)); + EXPECT_FLOAT_EQ(7.0, y[3](1)); + + double z = deserializer.read(); + EXPECT_FLOAT_EQ(8.0, z); +} + +// size zero + +TEST(deserializer, zeroSizeVecs) { + std::vector theta_i; + std::vector theta; + theta.push_back(1.0); + stan::io::deserializer deserializer(theta, theta_i); + + EXPECT_FLOAT_EQ(1.0, deserializer.read()); // finish available + + EXPECT_EQ(0, deserializer.read>(0).size()); + EXPECT_EQ(0, deserializer.read(0).size()); + EXPECT_EQ(0, deserializer.read(0).size()); + EXPECT_EQ(0, deserializer.read(0, 3).size()); + EXPECT_EQ(0, deserializer.read(3, 0).size()); + EXPECT_EQ(0, deserializer + .read>>(0, 0, 0, 0) + .size()); +} + +// out of memory + +/*TEST(deserializer, eos_exception) { + std::vector theta; + theta.push_back(1.0); + theta.push_back(2.0); + std::vector theta_i; + theta_i.push_back(1); + stan::io::deserializer deserializer(theta, theta_i); + + EXPECT_EQ(2U, deserializer.available()); + EXPECT_EQ(1U, deserializer.available_i()); + + EXPECT_NO_THROW(deserializer.read()); + EXPECT_NO_THROW(deserializer.read()); + EXPECT_THROW(deserializer.read(), std::runtime_error); + + // should go back to working + EXPECT_NO_THROW(deserializer.read()); + EXPECT_THROW(deserializer.read(), std::runtime_error); + + // should keep throwing + EXPECT_THROW(deserializer.read(), std::runtime_error); + EXPECT_THROW(deserializer.read(), std::runtime_error); + + EXPECT_THROW(deserializer.read>(), std::runtime_error); + EXPECT_THROW(deserializer.read>(3), std::runtime_error); + EXPECT_THROW(deserializer.read(2), std::runtime_error); + EXPECT_THROW((deserializer.read, Eigen::Dynamic, 1>>(2)), std::runtime_error); + EXPECT_THROW(deserializer.read>(3, 2), std::runtime_error); + EXPECT_THROW(deserializer.read(2), std::runtime_error); + EXPECT_THROW((deserializer.read, 1, Eigen::Dynamic>>(2)), std::runtime_error); + EXPECT_THROW(deserializer.read>(3, 2), std::runtime_error); + EXPECT_THROW(deserializer.read(2, 2), std::runtime_error); + EXPECT_THROW((deserializer.read, Eigen::Dynamic, Eigen::Dynamic>>(2, 2)), std::runtime_error); + EXPECT_THROW(deserializer.read>(2, 3, 2), std::runtime_error); + }*/ + +// lb + +TEST(deserializer_scalar, read_lb_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0.0; + EXPECT_FLOAT_EQ(1.0 + exp(-2.0), + (deserializer.read_lb(1.0, lp))); + EXPECT_FLOAT_EQ(5.0 + exp(3.0), + (deserializer.read_lb(5.0, lp))); + EXPECT_FLOAT_EQ(-2.0 + exp(-1.0), + (deserializer.read_lb(-2.0, lp))); + EXPECT_FLOAT_EQ(15.0 + exp(0.0), + (deserializer.read_lb(15.0, lp))); +} + +TEST(deserializer_scalar, read_lb_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = -1.5; + EXPECT_FLOAT_EQ(1.0 + exp(-2.0), + (deserializer.read_lb(1.0, lp))); + EXPECT_FLOAT_EQ(5.0 + exp(3.0), + (deserializer.read_lb(5.0, lp))); + EXPECT_FLOAT_EQ(-2.0 + exp(-1.0), + (deserializer.read_lb(-2.0, lp))); + EXPECT_FLOAT_EQ(15.0 + exp(0.0), + (deserializer.read_lb(15.0, lp))); + EXPECT_FLOAT_EQ(-1.5 - 2.0 + 3.0 - 1.0, lp); +} + +// ub + +TEST(deserializer_scalar, read_ub_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = 0; + EXPECT_FLOAT_EQ(1.0 - exp(-2.0), + (deserializer.read_ub(1.0, lp))); + EXPECT_FLOAT_EQ(5.0 - exp(3.0), + (deserializer.read_ub(5.0, lp))); + EXPECT_FLOAT_EQ(-2.0 - exp(-1.0), + (deserializer.read_ub(-2.0, lp))); + EXPECT_FLOAT_EQ(15.0 - exp(0.0), + (deserializer.read_ub(15.0, lp))); +} +TEST(deserializer_scalar, read_ub_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = -12.9; + EXPECT_FLOAT_EQ(1.0 - exp(-2.0), + (deserializer.read_ub(1.0, lp))); + EXPECT_FLOAT_EQ(5.0 - exp(3.0), (deserializer.read_ub(5.0, lp))); EXPECT_FLOAT_EQ(-2.0 - exp(-1.0), (deserializer.read_ub(-2.0, lp))); @@ -263,540 +486,197 @@ TEST(deserializer_scalar, offset_multiplier_constrain) { (deserializer.read_offset_multiplier(-3.0, 2.0, lp))); EXPECT_FLOAT_EQ(-15.0, (deserializer.read_offset_multiplier( -15.0, 15.0, lp))); -} -TEST(deserializer_scalar, offset_multiplier_constrain_jacobian) { - std::vector theta_i; - std::vector theta; - theta.push_back(-2.0); - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(0.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = -7.2; - EXPECT_FLOAT_EQ( - -2.0, (deserializer.read_offset_multiplier(0.0, 1.0, lp))); - EXPECT_FLOAT_EQ( - 3.0 + 5.0 * 3.0, - (deserializer.read_offset_multiplier(3.0, 5.0, lp))); - EXPECT_FLOAT_EQ( - -3.0 + 2.0 * -1.0, - (deserializer.read_offset_multiplier(-3.0, 2.0, lp))); - EXPECT_FLOAT_EQ(-15.0, (deserializer.read_offset_multiplier( - -15.0, 15.0, lp))); - double expected_lp = -7.2 + log(1.0) + log(5.0) + log(2.0) + log(15.0); - EXPECT_FLOAT_EQ(expected_lp, lp); -} - -// vector -TEST(deserializer_vector, read) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100U; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - for (size_t i = 0; i < 7U; ++i) { - double x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - Eigen::Matrix y - = deserializer.read(4); - EXPECT_EQ(4, y.rows()); - EXPECT_EQ(1, y.cols()); - EXPECT_EQ(4, y.size()); - EXPECT_FLOAT_EQ(7.0, y[0]); - EXPECT_FLOAT_EQ(8.0, y[1]); - EXPECT_FLOAT_EQ(9.0, y[2]); - EXPECT_FLOAT_EQ(10.0, y[3]); - - double z = deserializer.read(); - EXPECT_FLOAT_EQ(11.0, z); -} - -TEST(deserializer_vector, complex_read) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100U; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - for (size_t i = 0; i < 7U; ++i) { - double x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - using complex_vec = Eigen::Matrix, Eigen::Dynamic, 1>; - complex_vec y = deserializer.read(4); - EXPECT_EQ(4, y.rows()); - EXPECT_EQ(1, y.cols()); - EXPECT_EQ(4, y.size()); - double sentinal = 7; - for (int i = 0; i < y.size(); ++i) { - EXPECT_FLOAT_EQ(sentinal, y[i].real()); - ++sentinal; - EXPECT_FLOAT_EQ(sentinal, y[i].imag()); - ++sentinal; - } - - double z = deserializer.read(); - EXPECT_FLOAT_EQ(15.0, z); -} - -// need to add unit vector, simplex tests before merge - -TEST(deserializer_vector, ordered_constrain) { - std::vector theta_i; - std::vector theta; - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); - double v0 = 3.0; - double v1 = v0 + exp(-1.0); - double v2 = v1 + exp(-2.0); - double v3 = v2 + exp(0.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = 0; - Eigen::Matrix phi( - deserializer.read_ordered(lp, 4)); - EXPECT_FLOAT_EQ(v0, phi[0]); - EXPECT_FLOAT_EQ(v1, phi[1]); - EXPECT_FLOAT_EQ(v2, phi[2]); - EXPECT_FLOAT_EQ(v3, phi[3]); -} -TEST(deserializer_vector, ordered_constrain_jacobian) { - std::vector theta_i; - std::vector theta; - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); - double v0 = 3.0; - double v1 = v0 + exp(-1.0); - double v2 = v1 + exp(-2.0); - double v3 = v2 + exp(0.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = -101.1; - double expected_lp = lp - 1.0 - 2.0 + 0.0; - Eigen::Matrix phi( - deserializer.read_ordered(lp, 4)); - EXPECT_FLOAT_EQ(v0, phi[0]); - EXPECT_FLOAT_EQ(v1, phi[1]); - EXPECT_FLOAT_EQ(v2, phi[2]); - EXPECT_FLOAT_EQ(v3, phi[3]); - EXPECT_FLOAT_EQ(expected_lp, lp); -} - -TEST(deserializer_vector, positive_ordered_constrain) { - std::vector theta_i; - std::vector theta; - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); - double v0 = exp(3.0); - double v1 = v0 + exp(-1.0); - double v2 = v1 + exp(-2.0); - double v3 = v2 + exp(0.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = 0; - Eigen::Matrix phi( - deserializer.read_positive_ordered(lp, 4)); - EXPECT_FLOAT_EQ(v0, phi[0]); - EXPECT_FLOAT_EQ(v1, phi[1]); - EXPECT_FLOAT_EQ(v2, phi[2]); - EXPECT_FLOAT_EQ(v3, phi[3]); -} - -TEST(deserializer_vector, positive_ordered_constrain_jacobian) { - std::vector theta_i; - std::vector theta; - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); - double v0 = exp(3.0); - double v1 = v0 + exp(-1.0); - double v2 = v1 + exp(-2.0); - double v3 = v2 + exp(0.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = -101.1; - double expected_lp = lp + 3.0 - 1.0 - 2.0 + 0.0; - Eigen::Matrix phi( - deserializer.read_positive_ordered(lp, 4)); - EXPECT_FLOAT_EQ(v0, phi[0]); - EXPECT_FLOAT_EQ(v1, phi[1]); - EXPECT_FLOAT_EQ(v2, phi[2]); - EXPECT_FLOAT_EQ(v3, phi[3]); - EXPECT_FLOAT_EQ(expected_lp, lp); -} - -TEST(deserializer_vector, offset_multiplier_constrain) { - std::vector theta_i; - std::vector theta; - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = 0; - Eigen::Matrix phi( - deserializer.read_offset_multiplier(0.0, 1.0, lp, - 4)); - EXPECT_FLOAT_EQ(theta[0], phi[0]); - EXPECT_FLOAT_EQ(theta[1], phi[1]); - EXPECT_FLOAT_EQ(theta[2], phi[2]); - EXPECT_FLOAT_EQ(theta[3], phi[3]); -} - -TEST(deserializer_vector, offset_multiplier_constrain_lp) { - std::vector theta_i; - std::vector theta; - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); - stan::io::deserializer deserializer(theta, theta_i); - double lp = 0; - Eigen::Matrix phi( - deserializer.read_offset_multiplier(0, 2, lp, 4)); - EXPECT_FLOAT_EQ(theta[0] * 2, phi[0]); - EXPECT_FLOAT_EQ(theta[1] * 2, phi[1]); - EXPECT_FLOAT_EQ(theta[2] * 2, phi[2]); - EXPECT_FLOAT_EQ(theta[3] * 2, phi[3]); - EXPECT_FLOAT_EQ(lp, std::log(2) * 4); -} - -// matrix - -TEST(deserializer_matrix, read) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - for (int i = 0; i < 7; ++i) { - double x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - using eig_mat = Eigen::Matrix; - eig_mat y = deserializer.read(3, 2); - EXPECT_EQ(3, y.rows()); - EXPECT_EQ(2, y.cols()); - EXPECT_FLOAT_EQ(7.0, y(0, 0)); - EXPECT_FLOAT_EQ(8.0, y(1, 0)); - EXPECT_FLOAT_EQ(9.0, y(2, 0)); - EXPECT_FLOAT_EQ(10.0, y(0, 1)); - EXPECT_FLOAT_EQ(11.0, y(1, 1)); - EXPECT_FLOAT_EQ(12.0, y(2, 1)); - - double a = deserializer.read(); - EXPECT_FLOAT_EQ(13.0, a); -} - -TEST(deserializer_matrix, complex_read) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - for (int i = 0; i < 7; ++i) { - double x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - using eig_mat - = Eigen::Matrix, Eigen::Dynamic, Eigen::Dynamic>; - eig_mat y = deserializer.read(3, 2); - EXPECT_EQ(3, y.rows()); - EXPECT_EQ(2, y.cols()); - double sentinal = 7; - for (int i = 0; i < y.size(); ++i) { - EXPECT_FLOAT_EQ(sentinal, y(i).real()); - sentinal++; - EXPECT_FLOAT_EQ(sentinal, y(i).imag()); - sentinal++; - } -} - -TEST(deserializer_matrix, matrix_lb_constrain) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - for (int i = 0; i < 7; ++i) { - double x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - double lb = -1.5; - double lp = 0; - Eigen::Matrix y - = deserializer.read_lb(lb, lp, 3, 2); - EXPECT_EQ(3, y.rows()); - EXPECT_EQ(2, y.cols()); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(7.0, lb), y(0, 0)); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(8.0, lb), y(1, 0)); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(9.0, lb), y(2, 0)); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(10.0, lb), y(0, 1)); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(11.0, lb), y(1, 1)); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(12.0, lb), y(2, 1)); - - double a = deserializer.read(); - EXPECT_FLOAT_EQ(13.0, a); -} - -TEST(deserializer_matrix, matrix_lb_constrain_lp) { - std::vector theta_i; - std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); - stan::io::deserializer deserializer(theta, theta_i); - for (int i = 0; i < 7; ++i) { - double x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - double lb = -1.5; - double lp = -5.0; - Eigen::Matrix y - = deserializer.read_lb(lb, lp, 3, 2); - EXPECT_EQ(3, y.rows()); - EXPECT_EQ(2, y.cols()); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(7.0, lb, lp), y(0, 0)); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(8.0, lb, lp), y(1, 0)); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(9.0, lb, lp), y(2, 0)); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(10.0, lb, lp), y(0, 1)); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(11.0, lb, lp), y(1, 1)); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(12.0, lb, lp), y(2, 1)); +} - double a = deserializer.read(); - EXPECT_FLOAT_EQ(13.0, a); +TEST(deserializer_scalar, offset_multiplier_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + double lp = -7.2; + EXPECT_FLOAT_EQ( + -2.0, (deserializer.read_offset_multiplier(0.0, 1.0, lp))); + EXPECT_FLOAT_EQ( + 3.0 + 5.0 * 3.0, + (deserializer.read_offset_multiplier(3.0, 5.0, lp))); + EXPECT_FLOAT_EQ( + -3.0 + 2.0 * -1.0, + (deserializer.read_offset_multiplier(-3.0, 2.0, lp))); + EXPECT_FLOAT_EQ(-15.0, (deserializer.read_offset_multiplier( + -15.0, 15.0, lp))); + double expected_lp = -7.2 + log(1.0) + log(5.0) + log(2.0) + log(15.0); + EXPECT_FLOAT_EQ(expected_lp, lp); } -TEST(deserializer_matrix, matrix_ub_constrain) { +// unit vector + +TEST(deserializer_vector, unit_vector_constrain) { std::vector theta_i; std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); - for (int i = 0; i < 7; ++i) { - double x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - double ub = 14.1; double lp = 0; - Eigen::Matrix y - = deserializer.read_ub(ub, lp, 3, 2); - EXPECT_EQ(3, y.rows()); - EXPECT_EQ(2, y.cols()); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(7.0, ub), y(0, 0)); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(8.0, ub), y(1, 0)); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(9.0, ub), y(2, 0)); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(10.0, ub), y(0, 1)); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(11.0, ub), y(1, 1)); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(12.0, ub), y(2, 1)); - - double a = deserializer.read(); - EXPECT_FLOAT_EQ(13.0, a); + Eigen::VectorXd reference = stan::math::unit_vector_constrain(stan::math::to_vector(theta)); + Eigen::VectorXd phi(deserializer.read_unit_vector(lp, 4)); + for(size_t i = 0; i < phi.size(); ++i) { + EXPECT_FLOAT_EQ(reference(i), phi[i]); + } } -TEST(deserializer_matrix, matrix_ub_constrain_lp) { +TEST(deserializer_vector, unit_vector_jacobian) { std::vector theta_i; std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); - for (int i = 0; i < 7; ++i) { - double x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x); + double lp = 0.0; + double lp_ref = 0.0; + Eigen::VectorXd reference = stan::math::unit_vector_constrain(stan::math::to_vector(theta), lp_ref); + Eigen::VectorXd phi(deserializer.read_unit_vector(lp, 4)); + for(size_t i = 0; i < phi.size(); ++i) { + EXPECT_FLOAT_EQ(reference(i), phi[i]); } - double ub = 12.1; - double lp = -5.0; - Eigen::Matrix y - = deserializer.read_ub(ub, lp, 3, 2); - EXPECT_EQ(3, y.rows()); - EXPECT_EQ(2, y.cols()); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(7.0, ub, lp), y(0, 0)); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(8.0, ub, lp), y(1, 0)); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(9.0, ub, lp), y(2, 0)); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(10.0, ub, lp), y(0, 1)); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(11.0, ub, lp), y(1, 1)); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(12.0, ub, lp), y(2, 1)); - - double a = deserializer.read(); - EXPECT_FLOAT_EQ(13.0, a); + EXPECT_FLOAT_EQ(lp_ref, lp); } -TEST(deserializer_matrix, matrix_lub_constrain) { +// simplex + +TEST(deserializer_vector, simplex_constrain) { std::vector theta_i; std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); - for (int i = 0; i < 7; ++i) { - double x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x); - } - double lb = 3.5; - double ub = 14.1; double lp = 0; - Eigen::Matrix y - = deserializer.read_lub(lb, ub, lp, 3, 2); - EXPECT_EQ(3, y.rows()); - EXPECT_EQ(2, y.cols()); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(7.0, lb, ub), y(0, 0)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(8.0, lb, ub), y(1, 0)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(9.0, lb, ub), y(2, 0)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(10.0, lb, ub), y(0, 1)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(11.0, lb, ub), y(1, 1)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(12.0, lb, ub), y(2, 1)); - - double a = deserializer.read(); - EXPECT_FLOAT_EQ(13.0, a); + Eigen::VectorXd reference = stan::math::simplex_constrain(stan::math::to_vector(theta)); + Eigen::VectorXd phi(deserializer.read_simplex(lp, 4)); + for(size_t i = 0; i < phi.size(); ++i) { + EXPECT_FLOAT_EQ(reference(i), phi[i]); + } } -TEST(deserializer_matrix, matrix_lub_constrain_lp) { +TEST(deserializer_vector, simplex_jacobian) { std::vector theta_i; std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); - for (int i = 0; i < 7; ++i) { - double x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x); + double lp = 0.0; + double lp_ref = 0.0; + Eigen::VectorXd reference = stan::math::simplex_constrain(stan::math::to_vector(theta), lp_ref); + Eigen::VectorXd phi(deserializer.read_simplex(lp, 4)); + for(size_t i = 0; i < phi.size(); ++i) { + EXPECT_FLOAT_EQ(reference(i), phi[i]); } - double lb = 4.1; - double ub = 12.1; - double lp = -5.0; - Eigen::Matrix y - = deserializer.read_lub(lb, ub, lp, 3, 2); - EXPECT_EQ(3, y.rows()); - EXPECT_EQ(2, y.cols()); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(7.0, lb, ub, lp), y(0, 0)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(8.0, lb, ub, lp), y(1, 0)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(9.0, lb, ub, lp), y(2, 0)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(10.0, lb, ub, lp), y(0, 1)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(11.0, lb, ub, lp), y(1, 1)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(12.0, lb, ub, lp), y(2, 1)); - - double a = deserializer.read(); - EXPECT_FLOAT_EQ(13.0, a); + EXPECT_FLOAT_EQ(lp_ref, lp); } -TEST(deserializer_matrix, corr_matrix_constrain) { - using Eigen::Dynamic; - using Eigen::Matrix; +// ordered + +TEST(deserializer_vector, ordered_constrain) { std::vector theta_i; std::vector theta; - theta.push_back(-2.0); + theta.push_back(3.0); theta.push_back(-1.0); + theta.push_back(-2.0); theta.push_back(0.0); - theta.push_back(0.5); - theta.push_back(1.0); - theta.push_back(2.0); - theta.push_back(1.0); + double v0 = 3.0; + double v1 = v0 + exp(-1.0); + double v2 = v1 + exp(-2.0); + double v3 = v2 + exp(0.0); stan::io::deserializer deserializer(theta, theta_i); double lp = 0; - Matrix R( - deserializer.read_corr(lp, 3U)); - EXPECT_EQ(3, R.rows()); - EXPECT_EQ(3, R.cols()); - EXPECT_EQ(9, R.size()); - EXPECT_EQ(4U, deserializer.available()); - for (size_t i = 0; i < 3U; ++i) { - EXPECT_FLOAT_EQ(1.0, R(i, i)); - for (size_t j = i + 1; j < 3U; ++j) - EXPECT_FLOAT_EQ(R(i, j), R(j, i)); - } - Eigen::SelfAdjointEigenSolver< - Eigen::Matrix> - solver(R, Eigen::EigenvaluesOnly); - assert(solver.eigenvalues()[0] > 1E-10); + Eigen::Matrix phi( + deserializer.read_ordered(lp, 4)); + EXPECT_FLOAT_EQ(v0, phi[0]); + EXPECT_FLOAT_EQ(v1, phi[1]); + EXPECT_FLOAT_EQ(v2, phi[2]); + EXPECT_FLOAT_EQ(v3, phi[3]); } -TEST(deserializer_matrix, corr_matrix_constrain_jacobian) { + +TEST(deserializer_vector, ordered_constrain_jacobian) { std::vector theta_i; std::vector theta; - theta.push_back(-2.0); + theta.push_back(3.0); theta.push_back(-1.0); + theta.push_back(-2.0); theta.push_back(0.0); - theta.push_back(0.5); - theta.push_back(1.0); - theta.push_back(2.0); - theta.push_back(1.0); + double v0 = 3.0; + double v1 = v0 + exp(-1.0); + double v2 = v1 + exp(-2.0); + double v3 = v2 + exp(0.0); stan::io::deserializer deserializer(theta, theta_i); - double lp = -9.2; - Eigen::Matrix R( - deserializer.read_corr(lp, 3U)); - EXPECT_EQ(3, R.rows()); - EXPECT_EQ(3, R.cols()); - EXPECT_EQ(9, R.size()); - EXPECT_EQ(4U, deserializer.available()); - for (size_t i = 0; i < 3U; ++i) { - EXPECT_FLOAT_EQ(1.0, R(i, i)); - for (size_t j = i + 1; j < 3U; ++j) - EXPECT_FLOAT_EQ(R(i, j), R(j, i)); - } - Eigen::SelfAdjointEigenSolver< - Eigen::Matrix> - solver(R, Eigen::EigenvaluesOnly); - assert(solver.eigenvalues()[0] > 1E-10); - // FIXME: test jacobian + double lp = -101.1; + double expected_lp = lp - 1.0 - 2.0 + 0.0; + Eigen::Matrix phi( + deserializer.read_ordered(lp, 4)); + EXPECT_FLOAT_EQ(v0, phi[0]); + EXPECT_FLOAT_EQ(v1, phi[1]); + EXPECT_FLOAT_EQ(v2, phi[2]); + EXPECT_FLOAT_EQ(v3, phi[3]); + EXPECT_FLOAT_EQ(expected_lp, lp); } -TEST(deserializer_matrix, cov_matrix_constrain) { +// positive ordered + +TEST(deserializer_vector, positive_ordered_constrain) { std::vector theta_i; std::vector theta; - theta.push_back(-2.0); + theta.push_back(3.0); theta.push_back(-1.0); + theta.push_back(-2.0); theta.push_back(0.0); - theta.push_back(0.5); - theta.push_back(1.0); - theta.push_back(2.0); - theta.push_back(1.0); + double v0 = exp(3.0); + double v1 = v0 + exp(-1.0); + double v2 = v1 + exp(-2.0); + double v3 = v2 + exp(0.0); stan::io::deserializer deserializer(theta, theta_i); double lp = 0; - Eigen::Matrix S( - deserializer.read_cov_matrix(lp, 3U)); - EXPECT_EQ(3, S.rows()); - EXPECT_EQ(3, S.cols()); - EXPECT_EQ(9, S.size()); - EXPECT_EQ(1U, deserializer.available()); - for (size_t i = 0; i < 3U; ++i) - for (size_t j = i + 1; j < 3U; ++j) - EXPECT_FLOAT_EQ(S(i, j), S(j, i)); - Eigen::SelfAdjointEigenSolver< - Eigen::Matrix> - solver(S, Eigen::EigenvaluesOnly); - assert(solver.eigenvalues()[0] - > 1E-10); // check positive definite with smallest eigenvalue > 0 -} -TEST(deserializer_matrix, cov_matrix_constrain_jacobian) { + Eigen::Matrix phi( + deserializer.read_positive_ordered(lp, 4)); + EXPECT_FLOAT_EQ(v0, phi[0]); + EXPECT_FLOAT_EQ(v1, phi[1]); + EXPECT_FLOAT_EQ(v2, phi[2]); + EXPECT_FLOAT_EQ(v3, phi[3]); +} + +TEST(deserializer_vector, positive_ordered_constrain_jacobian) { std::vector theta_i; std::vector theta; - theta.push_back(-2.0); + theta.push_back(3.0); theta.push_back(-1.0); + theta.push_back(-2.0); theta.push_back(0.0); - theta.push_back(0.5); - theta.push_back(1.0); - theta.push_back(2.0); - theta.push_back(1.0); + double v0 = exp(3.0); + double v1 = v0 + exp(-1.0); + double v2 = v1 + exp(-2.0); + double v3 = v2 + exp(0.0); stan::io::deserializer deserializer(theta, theta_i); - double lp = -3.1; - - Eigen::Matrix S( - deserializer.read_cov_matrix(lp, 3U)); - - EXPECT_EQ(3, S.rows()); - EXPECT_EQ(3, S.cols()); - EXPECT_EQ(9, S.size()); - EXPECT_EQ(1U, deserializer.available()); - for (size_t i = 0; i < 3U; ++i) - for (size_t j = i + 1; j < 3U; ++j) - EXPECT_FLOAT_EQ(S(i, j), S(j, i)); - Eigen::SelfAdjointEigenSolver< - Eigen::Matrix> - solver(S, Eigen::EigenvaluesOnly); - assert(solver.eigenvalues()[0] - > 1E-10); // check positive definite with smallest eigenvalue > 0 - // FIXME: test Jacobian + double lp = -101.1; + double expected_lp = lp + 3.0 - 1.0 - 2.0 + 0.0; + Eigen::Matrix phi( + deserializer.read_positive_ordered(lp, 4)); + EXPECT_FLOAT_EQ(v0, phi[0]); + EXPECT_FLOAT_EQ(v1, phi[1]); + EXPECT_FLOAT_EQ(v2, phi[2]); + EXPECT_FLOAT_EQ(v3, phi[3]); + EXPECT_FLOAT_EQ(expected_lp, lp); } +// chol cov + TEST(deserializer_matrix, cholesky_factor_cov_constrain) { std::vector theta_i; std::vector theta; @@ -804,119 +684,179 @@ TEST(deserializer_matrix, cholesky_factor_cov_constrain) { theta.push_back(-static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); double lp = 0; - Eigen::Matrix L( - deserializer.read_cholesky_factor_cov(lp, 3U, - 3U)); - EXPECT_NO_THROW(stan::math::check_cholesky_factor( - "test_cholesky_factor_constrain", "L", L)); + Eigen::MatrixXd reference = + stan::math::cholesky_factor_constrain(stan::math::to_vector(theta).segment(0, 6), 3, 3); + Eigen::MatrixXd L(deserializer.read_cholesky_factor_cov(lp, 3U, 3U)); + EXPECT_EQ(3, L.rows()); + EXPECT_EQ(3, L.cols()); + EXPECT_EQ(9, L.size()); + stan::test::expect_near_rel("deserializer tests", reference, L); + EXPECT_EQ(2U, deserializer.available()); +} + +TEST(deserializer_matrix, cholesky_factor_cov_jacobian) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 8; ++i) + theta.push_back(-static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + double lp_ref = 0.0; + double lp = 0.0; + Eigen::MatrixXd reference = + stan::math::cholesky_factor_constrain(stan::math::to_vector(theta).segment(0, 6), 3, 3, lp_ref); + Eigen::MatrixXd L(deserializer.read_cholesky_factor_cov(lp, 3U, 3U)); EXPECT_EQ(3, L.rows()); EXPECT_EQ(3, L.cols()); EXPECT_EQ(9, L.size()); + stan::test::expect_near_rel("deserializer tests", reference, L); EXPECT_EQ(2U, deserializer.available()); + EXPECT_FLOAT_EQ(lp_ref, lp); } -TEST(deserializer_matrix, cholesky_factor_cov_constrain_asymmetric) { +TEST(deserializer_matrix, cholesky_factor_cov_constrain_non_square) { std::vector theta_i; std::vector theta; for (int i = 0; i < 8; ++i) theta.push_back(-static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); double lp = 0; - Eigen::Matrix L( - deserializer.read_cholesky_factor_cov(lp, 3U, - 2U)); - EXPECT_NO_THROW(stan::math::check_cholesky_factor( - "test_cholesky_factor_constrain", "L", L)); + Eigen::MatrixXd reference = + stan::math::cholesky_factor_constrain(stan::math::to_vector(theta).segment(0, 5), 3, 2); + Eigen::MatrixXd L(deserializer.read_cholesky_factor_cov(lp, 3U, 2U)); EXPECT_EQ(3, L.rows()); EXPECT_EQ(2, L.cols()); EXPECT_EQ(6, L.size()); + stan::test::expect_near_rel("deserializer tests", reference, L); EXPECT_EQ(3U, deserializer.available()); } -TEST(deserializer_matrix, cholesky_factor_cov_constrain_jacobian) { + +TEST(deserializer_matrix, cholesky_factor_cov_jacobian_non_square) { std::vector theta_i; std::vector theta; for (int i = 0; i < 8; ++i) theta.push_back(-static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); - double lp = 1.9; - Eigen::Matrix L( - deserializer.read_cholesky_factor_cov(lp, 3U, 3U)); - EXPECT_NO_THROW(stan::math::check_cholesky_factor( - "test_cholesky_factor_constrain", "L", L)); + double lp_ref = 0.0; + double lp = 0.0; + Eigen::MatrixXd reference = + stan::math::cholesky_factor_constrain(stan::math::to_vector(theta).segment(0, 5), 3, 2, lp_ref); + Eigen::MatrixXd L(deserializer.read_cholesky_factor_cov(lp, 3U, 2U)); EXPECT_EQ(3, L.rows()); - EXPECT_EQ(3, L.cols()); - EXPECT_EQ(9, L.size()); - EXPECT_EQ(2U, deserializer.available()); - EXPECT_EQ(1.9 + log(L(0, 0)) + log(L(1, 1)) + log(L(2, 2)), lp); + EXPECT_EQ(2, L.cols()); + EXPECT_EQ(6, L.size()); + stan::test::expect_near_rel("deserializer tests", reference, L); + EXPECT_EQ(3U, deserializer.available()); + EXPECT_FLOAT_EQ(lp_ref, lp); } -TEST(deserializer_matrix, cholesky_factor_cov_constrain_jacobian_asymmetric) { + +// chol corr + +TEST(deserializer_matrix, cholesky_factor_corr_constrain) { std::vector theta_i; std::vector theta; - for (int i = 0; i < 12; ++i) + for (int i = 0; i < 8; ++i) theta.push_back(-static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); - double lp = 1.9; - Eigen::Matrix L( - deserializer.read_cholesky_factor_cov(lp, 4U, 3U)); - EXPECT_NO_THROW(stan::math::check_cholesky_factor( - "test_cholesky_factor_constrain", "L", L)); - EXPECT_EQ(4, L.rows()); + double lp = 0; + Eigen::MatrixXd reference = stan::math::cholesky_corr_constrain(stan::math::to_vector(theta).segment(0, 3), 3); + Eigen::MatrixXd L(deserializer.read_cholesky_factor_corr(lp, 3U)); + EXPECT_NO_THROW(stan::math::check_cholesky_factor_corr( + "test_cholesky_factor_corr_constrain", "L", L)); + EXPECT_EQ(3, L.rows()); EXPECT_EQ(3, L.cols()); - EXPECT_EQ(12, L.size()); - EXPECT_EQ(3U, deserializer.available()); - EXPECT_EQ(1.9 + log(L(0, 0)) + log(L(1, 1)) + log(L(2, 2)), lp); + EXPECT_EQ(9, L.size()); + stan::test::expect_near_rel("deserializer tests", reference, L); + EXPECT_EQ(5U, deserializer.available()); } -TEST(deserializer_matrix, cholesky_factor_corr_constrain) { +TEST(deserializer_matrix, cholesky_factor_corr_jacobian) { std::vector theta_i; std::vector theta; for (int i = 0; i < 8; ++i) theta.push_back(-static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); - double lp = 0; - Eigen::Matrix L( - deserializer.read_cholesky_factor_corr(lp, 3U)); + double lp_ref = 0.0; + double lp = 0.0; + Eigen::MatrixXd reference = stan::math::cholesky_corr_constrain(stan::math::to_vector(theta).segment(0, 3), 3, lp_ref); + Eigen::MatrixXd L(deserializer.read_cholesky_factor_corr(lp, 3U)); EXPECT_NO_THROW(stan::math::check_cholesky_factor_corr( "test_cholesky_factor_corr_constrain", "L", L)); EXPECT_EQ(3, L.rows()); EXPECT_EQ(3, L.cols()); EXPECT_EQ(9, L.size()); + stan::test::expect_near_rel("deserializer tests", reference, L); EXPECT_EQ(5U, deserializer.available()); + EXPECT_FLOAT_EQ(lp_ref, lp); } -TEST(deserializer_matrix, offset_multiplier_constrain) { +// cov + +TEST(deserializer_matrix, cov_matrix_constrain) { std::vector theta_i; std::vector theta; - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); + for (int i = 0; i < 8; ++i) + theta.push_back(-static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); double lp = 0; - Eigen::Matrix phi( - deserializer.read_offset_multiplier(0, 1, lp, 2, - 2)); - EXPECT_FLOAT_EQ(theta[0], phi(0, 0)); - EXPECT_FLOAT_EQ(theta[1], phi(1, 0)); - EXPECT_FLOAT_EQ(theta[2], phi(0, 1)); - EXPECT_FLOAT_EQ(theta[3], phi(1, 1)); + Eigen::MatrixXd reference = stan::math::cov_matrix_constrain(stan::math::to_vector(theta).segment(0, 6), 3); + Eigen::MatrixXd L(deserializer.read_cov_matrix(lp, 3U)); + EXPECT_EQ(3, L.rows()); + EXPECT_EQ(3, L.cols()); + EXPECT_EQ(9, L.size()); + stan::test::expect_near_rel("deserializer tests", reference, L); + EXPECT_EQ(2U, deserializer.available()); } -TEST(deserializer_matrix, offset_multiplier_constrain_lp) { +TEST(deserializer_matrix, cov_matrix_jacobian) { std::vector theta_i; std::vector theta; - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); + for (int i = 0; i < 8; ++i) + theta.push_back(-static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + double lp_ref = 0.0; + double lp = 0.0; + Eigen::MatrixXd reference = stan::math::cov_matrix_constrain(stan::math::to_vector(theta).segment(0, 6), 3, lp_ref); + Eigen::MatrixXd L(deserializer.read_cov_matrix(lp, 3U)); + EXPECT_EQ(3, L.rows()); + EXPECT_EQ(3, L.cols()); + EXPECT_EQ(9, L.size()); + stan::test::expect_near_rel("deserializer tests", reference, L); + EXPECT_EQ(2U, deserializer.available()); + EXPECT_FLOAT_EQ(lp_ref, lp); +} + +// corr + +TEST(deserializer_matrix, corr_matrix_constrain) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 8; ++i) + theta.push_back(-static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); double lp = 0; - Eigen::Matrix phi( - deserializer.read_offset_multiplier(0, 2, lp, 2, - 2)); - EXPECT_FLOAT_EQ(theta[0] * 2, phi(0, 0)); - EXPECT_FLOAT_EQ(theta[1] * 2, phi(1, 0)); - EXPECT_FLOAT_EQ(theta[2] * 2, phi(0, 1)); - EXPECT_FLOAT_EQ(theta[3] * 2, phi(1, 1)); - EXPECT_FLOAT_EQ(lp, std::log(2) * 4); + Eigen::MatrixXd reference = stan::math::corr_matrix_constrain(stan::math::to_vector(theta).segment(0, 3), 3); + Eigen::MatrixXd L(deserializer.read_corr_matrix(lp, 3U)); + EXPECT_EQ(3, L.rows()); + EXPECT_EQ(3, L.cols()); + EXPECT_EQ(9, L.size()); + stan::test::expect_near_rel("deserializer tests", reference, L); + EXPECT_EQ(5U, deserializer.available()); +} + +TEST(deserializer_matrix, corr_matrix_jacobian) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 8; ++i) + theta.push_back(-static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + double lp_ref = 0.0; + double lp = 0.0; + Eigen::MatrixXd reference = stan::math::corr_matrix_constrain(stan::math::to_vector(theta).segment(0, 3), 3, lp_ref); + Eigen::MatrixXd L(deserializer.read_corr_matrix(lp, 3U)); + EXPECT_EQ(3, L.rows()); + EXPECT_EQ(3, L.cols()); + EXPECT_EQ(9, L.size()); + stan::test::expect_near_rel("deserializer tests", reference, L); + EXPECT_EQ(5U, deserializer.available()); + EXPECT_FLOAT_EQ(lp_ref, lp); } diff --git a/src/test/unit/io/deserializer_varmat_test.cpp b/src/test/unit/io/deserializer_varmat_test.cpp index 12ca0f02950..4a5717a7566 100644 --- a/src/test/unit/io/deserializer_varmat_test.cpp +++ b/src/test/unit/io/deserializer_varmat_test.cpp @@ -1,10 +1,31 @@ #include +// expect_near_rel comes from lib/stan_math +#include +#include #include using var_matrix_t = stan::math::var_value; using var_vector_t = stan::math::var_value; +using var_row_vector_t = stan::math::var_value; + +TEST(deserializer_var_vector, varmat_reads_as_doubles) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100U; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + Eigen::VectorXd y = deserializer.read(4); + EXPECT_EQ(4, y.rows()); + EXPECT_EQ(1, y.cols()); + EXPECT_EQ(4, y.size()); + EXPECT_FLOAT_EQ(0.0, y[0]); + EXPECT_FLOAT_EQ(1.0, y[1]); + EXPECT_FLOAT_EQ(2.0, y[2]); + EXPECT_FLOAT_EQ(3.0, y[3]); +} // vectors + TEST(deserializer_var_vector, read) { std::vector theta_i; std::vector theta; @@ -28,474 +49,409 @@ TEST(deserializer_var_vector, read) { EXPECT_FLOAT_EQ(11.0, z.val()); } -// need to add unit vector and simplex constrain tests +// row vector -TEST(deserializer_var_vector, ordered_constrain) { +TEST(deserializer_var_row_vector, read) { std::vector theta_i; std::vector theta; - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); - double v0 = 3.0; - double v1 = v0 + exp(-1.0); - double v2 = v1 + exp(-2.0); - double v3 = v2 + exp(0.0); + for (size_t i = 0; i < 100U; ++i) + theta.push_back(static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); - stan::math::var lp = 0; - var_vector_t phi(deserializer.read_ordered(lp, 4)); - EXPECT_FLOAT_EQ(v0, phi.val()[0]); - EXPECT_FLOAT_EQ(v1, phi.val()[1]); - EXPECT_FLOAT_EQ(v2, phi.val()[2]); - EXPECT_FLOAT_EQ(v3, phi.val()[3]); + for (size_t i = 0; i < 7U; ++i) { + stan::math::var x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x.val()); + } + var_row_vector_t y = deserializer.read(4); + EXPECT_EQ(1, y.rows()); + EXPECT_EQ(4, y.cols()); + EXPECT_EQ(4, y.size()); + EXPECT_FLOAT_EQ(7.0, y.val()[0]); + EXPECT_FLOAT_EQ(8.0, y.val()[1]); + EXPECT_FLOAT_EQ(9.0, y.val()[2]); + EXPECT_FLOAT_EQ(10.0, y.val()[3]); + + stan::math::var z = deserializer.read(); + EXPECT_FLOAT_EQ(11.0, z.val()); } -TEST(deserializer_var_vector, ordered_constrain_jacobian) { + +// matrix + +TEST(deserializer_var_matrix, read) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (int i = 0; i < 7; ++i) { + stan::math::var x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x.val()); + } + var_matrix_t y = deserializer.read(3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(7.0, y.val()(0, 0)); + EXPECT_FLOAT_EQ(8.0, y.val()(1, 0)); + EXPECT_FLOAT_EQ(9.0, y.val()(2, 0)); + EXPECT_FLOAT_EQ(10.0, y.val()(0, 1)); + EXPECT_FLOAT_EQ(11.0, y.val()(1, 1)); + EXPECT_FLOAT_EQ(12.0, y.val()(2, 1)); + + stan::math::var a = deserializer.read(); + EXPECT_FLOAT_EQ(13.0, a.val()); +} + +// lb + +TEST(deserializer, read_lb_constrain) { std::vector theta_i; std::vector theta; - theta.push_back(3.0); - theta.push_back(-1.0); theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(1.0); theta.push_back(0.0); - double v0 = 3.0; - double v1 = v0 + exp(-1.0); - double v2 = v1 + exp(-2.0); - double v3 = v2 + exp(0.0); stan::io::deserializer deserializer(theta, theta_i); - stan::math::var lp = -101.1; - double expected_lp = lp.val() - 1.0 - 2.0 + 0.0; - var_vector_t phi(deserializer.read_ordered(lp, 4)); - EXPECT_FLOAT_EQ(v0, phi.val()[0]); - EXPECT_FLOAT_EQ(v1, phi.val()[1]); - EXPECT_FLOAT_EQ(v2, phi.val()[2]); - EXPECT_FLOAT_EQ(v3, phi.val()[3]); - EXPECT_FLOAT_EQ(expected_lp, lp.val()); + stan::math::var lp = 0.0; + auto reference = stan::math::lb_constrain(stan::math::to_vector(theta), 1.5); + auto y = deserializer.read_lb(1.5, lp, theta.size()); + EXPECT_TRUE((std::is_same::value)); + stan::test::expect_near_rel("deserializer tests", reference.val(), y.val()); } -TEST(deserializer_var_vector, positive_ordered_constrain) { +TEST(deserializer, read_lb_constrain_jacobian) { std::vector theta_i; std::vector theta; - theta.push_back(3.0); - theta.push_back(-1.0); theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(1.0); theta.push_back(0.0); - double v0 = exp(3.0); - double v1 = v0 + exp(-1.0); - double v2 = v1 + exp(-2.0); - double v3 = v2 + exp(0.0); stan::io::deserializer deserializer(theta, theta_i); - stan::math::var lp = 0; - var_vector_t phi( - deserializer.read_positive_ordered(lp, 4)); - EXPECT_FLOAT_EQ(v0, phi.val()[0]); - EXPECT_FLOAT_EQ(v1, phi.val()[1]); - EXPECT_FLOAT_EQ(v2, phi.val()[2]); - EXPECT_FLOAT_EQ(v3, phi.val()[3]); + stan::math::var lp_ref = 0.0; + stan::math::var lp = 0.0; + auto reference = stan::math::lb_constrain(stan::math::to_vector(theta), 1.5, lp_ref); + auto y = deserializer.read_lb(1.5, lp, theta.size()); + EXPECT_TRUE((std::is_same::value)); + stan::test::expect_near_rel("deserializer tests", reference.val(), y.val()); + EXPECT_FLOAT_EQ(lp_ref.val(), lp.val()); } -TEST(deserializer_var_vector, positive_ordered_constrain_jacobian) { +// ub + +TEST(deserializer, read_ub_constrain) { std::vector theta_i; std::vector theta; - theta.push_back(3.0); - theta.push_back(-1.0); theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(1.0); theta.push_back(0.0); - double v0 = exp(3.0); - double v1 = v0 + exp(-1.0); - double v2 = v1 + exp(-2.0); - double v3 = v2 + exp(0.0); stan::io::deserializer deserializer(theta, theta_i); - stan::math::var lp = -101.1; - double expected_lp = lp.val() + 3.0 - 1.0 - 2.0 + 0.0; - var_vector_t phi( - deserializer.read_positive_ordered(lp, 4)); - EXPECT_FLOAT_EQ(v0, phi.val()[0]); - EXPECT_FLOAT_EQ(v1, phi.val()[1]); - EXPECT_FLOAT_EQ(v2, phi.val()[2]); - EXPECT_FLOAT_EQ(v3, phi.val()[3]); - EXPECT_FLOAT_EQ(expected_lp, lp.val()); + stan::math::var lp = 0.0; + auto reference = stan::math::ub_constrain(stan::math::to_vector(theta), 1.5); + auto y = deserializer.read_ub(1.5, lp, theta.size()); + EXPECT_TRUE((std::is_same::value)); + stan::test::expect_near_rel("deserializer tests", reference.val(), y.val()); } -TEST(deserializer_vector, offset_multiplier_constrain) { +TEST(deserializer, read_ub_constrain_jacobian) { std::vector theta_i; std::vector theta; - theta.push_back(3.0); - theta.push_back(-1.0); theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(1.0); theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); - stan::math::var lp = 0; - var_vector_t phi( - deserializer.read_offset_multiplier(0, 1, lp, 4)); - EXPECT_FLOAT_EQ(theta[0].val(), phi.val()[0]); - EXPECT_FLOAT_EQ(theta[1].val(), phi.val()[1]); - EXPECT_FLOAT_EQ(theta[2].val(), phi.val()[2]); - EXPECT_FLOAT_EQ(theta[3].val(), phi.val()[3]); + stan::math::var lp_ref = 0.0; + stan::math::var lp = 0.0; + auto reference = stan::math::ub_constrain(stan::math::to_vector(theta), 1.5, lp_ref); + auto y = deserializer.read_ub(1.5, lp, theta.size()); + EXPECT_TRUE((std::is_same::value)); + stan::test::expect_near_rel("deserializer tests", reference.val(), y.val()); + EXPECT_FLOAT_EQ(lp_ref.val(), lp.val()); } -TEST(deserializer_vector, offset_multiplier_constrain_lp) { +// lub + +TEST(deserializer, read_lub_constrain) { std::vector theta_i; std::vector theta; + theta.push_back(-2.0); theta.push_back(3.0); theta.push_back(-1.0); - theta.push_back(-2.0); theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); - stan::math::var lp = 0; - var_vector_t phi( - deserializer.read_offset_multiplier(0, 2, lp, 4)); - EXPECT_FLOAT_EQ(theta[0].val() * 2, phi.val()[0]); - EXPECT_FLOAT_EQ(theta[1].val() * 2, phi.val()[1]); - EXPECT_FLOAT_EQ(theta[2].val() * 2, phi.val()[2]); - EXPECT_FLOAT_EQ(theta[3].val() * 2, phi.val()[3]); - EXPECT_FLOAT_EQ(lp.val(), std::log(2) * 4); + stan::math::var lp = 0.0; + auto reference = stan::math::lub_constrain(stan::math::to_vector(theta), 1.0, 2.0); + auto y = deserializer.read_lub(1.0, 2.0, lp, theta.size()); + EXPECT_TRUE((std::is_same::value)); + stan::test::expect_near_rel("deserializer tests", reference.val(), y.val()); } -// matrix - -TEST(deserializer_var_matrix, read) { +TEST(deserializer, read_lub_constrain_jacobian) { std::vector theta_i; std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); - for (int i = 0; i < 7; ++i) { - stan::math::var x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x.val()); - } - var_matrix_t y = deserializer.read(3, 2); - EXPECT_EQ(3, y.rows()); - EXPECT_EQ(2, y.cols()); - EXPECT_FLOAT_EQ(7.0, y.val()(0, 0)); - EXPECT_FLOAT_EQ(8.0, y.val()(1, 0)); - EXPECT_FLOAT_EQ(9.0, y.val()(2, 0)); - EXPECT_FLOAT_EQ(10.0, y.val()(0, 1)); - EXPECT_FLOAT_EQ(11.0, y.val()(1, 1)); - EXPECT_FLOAT_EQ(12.0, y.val()(2, 1)); - - stan::math::var a = deserializer.read(); - EXPECT_FLOAT_EQ(13.0, a.val()); + stan::math::var lp_ref = 0.0; + stan::math::var lp = 0.0; + auto reference = stan::math::lub_constrain(stan::math::to_vector(theta), 1.0, 2.0, lp_ref); + auto y = deserializer.read_lub(1.0, 2.0, lp, theta.size()); + EXPECT_TRUE((std::is_same::value)); + stan::test::expect_near_rel("deserializer tests", reference.val(), y.val()); + EXPECT_FLOAT_EQ(lp_ref.val(), lp.val()); } -TEST(deserializer_var_matrix, matrix_lb_constrain) { +// offset multiplier + +TEST(deserializer, read_offset_multiplier_constrain) { std::vector theta_i; std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); - for (int i = 0; i < 7; ++i) { - stan::math::var x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x.val()); - } - stan::math::var lb = -1.5; - stan::math::var lp = 0; - var_matrix_t y = deserializer.read_lb(lb, lp, 3, 2); - EXPECT_EQ(3, y.rows()); - EXPECT_EQ(2, y.cols()); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(7.0, lb).val(), y.val()(0, 0)); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(8.0, lb).val(), y.val()(1, 0)); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(9.0, lb).val(), y.val()(2, 0)); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(10.0, lb).val(), y.val()(0, 1)); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(11.0, lb).val(), y.val()(1, 1)); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(12.0, lb).val(), y.val()(2, 1)); - - stan::math::var a = deserializer.read(); - EXPECT_FLOAT_EQ(13.0, a.val()); + stan::math::var lp = 0.0; + auto reference = stan::math::offset_multiplier_constrain(stan::math::to_vector(theta), 1.0, 2.0); + auto y = deserializer.read_offset_multiplier(1.0, 2.0, lp, theta.size()); + EXPECT_TRUE((std::is_same::value)); + stan::test::expect_near_rel("deserializer tests", reference.val(), y.val()); } -TEST(deserializer_var_matrix, matrix_lb_constrain_lp) { +TEST(deserializer, read_offset_multiplier_jacobian) { std::vector theta_i; std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); - for (int i = 0; i < 7; ++i) { - stan::math::var x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x.val()); - } - stan::math::var lb = -1.5; - stan::math::var lp = -5.0; - var_matrix_t y = deserializer.read_lb(lb, lp, 3, 2); - EXPECT_EQ(3, y.rows()); - EXPECT_EQ(2, y.cols()); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(7.0, lb, lp).val(), y.val()(0, 0)); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(8.0, lb, lp).val(), y.val()(1, 0)); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(9.0, lb, lp).val(), y.val()(2, 0)); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(10.0, lb, lp).val(), y.val()(0, 1)); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(11.0, lb, lp).val(), y.val()(1, 1)); - EXPECT_FLOAT_EQ(stan::math::lb_constrain(12.0, lb, lp).val(), y.val()(2, 1)); - - stan::math::var a = deserializer.read(); - EXPECT_FLOAT_EQ(13.0, a.val()); + stan::math::var lp_ref = 0.0; + stan::math::var lp = 0.0; + auto reference = stan::math::offset_multiplier_constrain(stan::math::to_vector(theta), 1.0, 2.0, lp_ref); + auto y = deserializer.read_offset_multiplier(1.0, 2.0, lp, theta.size()); + EXPECT_TRUE((std::is_same::value)); + stan::test::expect_near_rel("deserializer tests", reference.val(), y.val()); + EXPECT_FLOAT_EQ(lp_ref.val(), lp.val()); } -TEST(deserializer_var_matrix, matrix_ub_constrain) { +// unit vector + +TEST(deserializer, read_unit_vector_constrain) { std::vector theta_i; std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); - for (int i = 0; i < 7; ++i) { - stan::math::var x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x.val()); - } - stan::math::var ub = 14.1; - stan::math::var lp = 0; - var_matrix_t y = deserializer.read_ub(ub, lp, 3, 2); - EXPECT_EQ(3, y.rows()); - EXPECT_EQ(2, y.cols()); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(7.0, ub).val(), y.val()(0, 0)); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(8.0, ub).val(), y.val()(1, 0)); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(9.0, ub).val(), y.val()(2, 0)); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(10.0, ub).val(), y.val()(0, 1)); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(11.0, ub).val(), y.val()(1, 1)); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(12.0, ub).val(), y.val()(2, 1)); - - stan::math::var a = deserializer.read(); - EXPECT_FLOAT_EQ(13.0, a.val()); + stan::math::var lp = 0.0; + auto reference = stan::math::unit_vector_constrain(stan::math::to_vector(theta)); + auto y = deserializer.read_unit_vector(lp, theta.size()); + EXPECT_TRUE((std::is_same::value)); + stan::test::expect_near_rel("deserializer tests", reference.val(), y.val()); } -TEST(deserializer_var_matrix, matrix_ub_constrain_lp) { +TEST(deserializer, read_unit_vector_jacobian) { std::vector theta_i; std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); - for (int i = 0; i < 7; ++i) { - stan::math::var x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x.val()); - } - stan::math::var ub = 12.1; - stan::math::var lp = -5.0; - var_matrix_t y = deserializer.read_ub(ub, lp, 3, 2); - EXPECT_EQ(3, y.rows()); - EXPECT_EQ(2, y.cols()); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(7.0, ub, lp).val(), y.val()(0, 0)); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(8.0, ub, lp).val(), y.val()(1, 0)); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(9.0, ub, lp).val(), y.val()(2, 0)); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(10.0, ub, lp).val(), y.val()(0, 1)); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(11.0, ub, lp).val(), y.val()(1, 1)); - EXPECT_FLOAT_EQ(stan::math::ub_constrain(12.0, ub, lp).val(), y.val()(2, 1)); - - stan::math::var a = deserializer.read(); - EXPECT_FLOAT_EQ(13.0, a.val()); + stan::math::var lp_ref = 0.0; + stan::math::var lp = 0.0; + auto reference = stan::math::unit_vector_constrain(stan::math::to_vector(theta), lp_ref); + auto y = deserializer.read_unit_vector(lp, theta.size()); + EXPECT_TRUE((std::is_same::value)); + stan::test::expect_near_rel("deserializer tests", reference.val(), y.val()); + EXPECT_FLOAT_EQ(lp_ref.val(), lp.val()); } -TEST(deserializer_var_matrix, matrix_lub_constrain) { +// simplex + +TEST(deserializer, read_simplex_constrain) { std::vector theta_i; std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); - for (int i = 0; i < 7; ++i) { - stan::math::var x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x.val()); - } - stan::math::var lb = 3.5; - stan::math::var ub = 14.1; - stan::math::var lp = 0; - var_matrix_t y = deserializer.read_lub(lb, ub, lp, 3, 2); - EXPECT_EQ(3, y.rows()); - EXPECT_EQ(2, y.cols()); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(7.0, lb, ub).val(), y.val()(0, 0)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(8.0, lb, ub).val(), y.val()(1, 0)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(9.0, lb, ub).val(), y.val()(2, 0)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(10.0, lb, ub).val(), y.val()(0, 1)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(11.0, lb, ub).val(), y.val()(1, 1)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(12.0, lb, ub).val(), y.val()(2, 1)); - - stan::math::var a = deserializer.read(); - EXPECT_FLOAT_EQ(13.0, a.val()); + stan::math::var lp = 0.0; + auto reference = stan::math::simplex_constrain(stan::math::to_vector(theta)); + auto y = deserializer.read_simplex(lp, theta.size()); + EXPECT_TRUE((std::is_same::value)); + stan::test::expect_near_rel("deserializer tests", reference.val(), y.val()); } -TEST(deserializer_var_matrix, matrix_lub_constrain_lp) { +TEST(deserializer, read_simplex_jacobian) { std::vector theta_i; std::vector theta; - for (size_t i = 0; i < 100.0; ++i) - theta.push_back(static_cast(i)); + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); - for (int i = 0; i < 7; ++i) { - stan::math::var x = deserializer.read(); - EXPECT_FLOAT_EQ(static_cast(i), x.val()); - } - stan::math::var lb = 4.1; - stan::math::var ub = 12.1; - stan::math::var lp = -5.0; - var_matrix_t y = deserializer.read_lub(lb, ub, lp, 3, 2); - EXPECT_EQ(3, y.rows()); - EXPECT_EQ(2, y.cols()); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(7.0, lb, ub, lp).val(), - y.val()(0, 0)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(8.0, lb, ub, lp).val(), - y.val()(1, 0)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(9.0, lb, ub, lp).val(), - y.val()(2, 0)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(10.0, lb, ub, lp).val(), - y.val()(0, 1)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(11.0, lb, ub, lp).val(), - y.val()(1, 1)); - EXPECT_FLOAT_EQ(stan::math::lub_constrain(12.0, lb, ub, lp).val(), - y.val()(2, 1)); - - stan::math::var a = deserializer.read(); - EXPECT_FLOAT_EQ(13.0, a.val()); + stan::math::var lp_ref = 0.0; + stan::math::var lp = 0.0; + auto reference = stan::math::simplex_constrain(stan::math::to_vector(theta), lp_ref); + auto y = deserializer.read_simplex(lp, theta.size()); + EXPECT_TRUE((std::is_same::value)); + stan::test::expect_near_rel("deserializer tests", reference.val(), y.val()); + EXPECT_FLOAT_EQ(lp_ref.val(), lp.val()); } -TEST(deserializer_var_matrix, corr_matrix_constrain) { - using Eigen::Dynamic; - using Eigen::Matrix; +// ordered + +TEST(deserializer, read_ordered_constrain) { std::vector theta_i; std::vector theta; theta.push_back(-2.0); + theta.push_back(3.0); theta.push_back(-1.0); theta.push_back(0.0); - theta.push_back(0.5); - theta.push_back(1.0); - theta.push_back(2.0); - theta.push_back(1.0); stan::io::deserializer deserializer(theta, theta_i); - stan::math::var lp = 0; - var_matrix_t R(deserializer.read_corr(lp, 3U)); - EXPECT_EQ(3, R.rows()); - EXPECT_EQ(3, R.cols()); - EXPECT_EQ(9, R.size()); - EXPECT_EQ(4U, deserializer.available()); - for (size_t i = 0; i < 3U; ++i) { - EXPECT_FLOAT_EQ(1.0, R.val()(i, i)); - for (size_t j = i + 1; j < 3U; ++j) - EXPECT_FLOAT_EQ(R.val()(i, j), R.val()(j, i)); - } - Eigen::SelfAdjointEigenSolver< - Eigen::Matrix> - solver(R.val(), Eigen::EigenvaluesOnly); - assert(solver.eigenvalues()[0] > 1E-10); + stan::math::var lp = 0.0; + auto reference = stan::math::ordered_constrain(stan::math::to_vector(theta)); + auto y = deserializer.read_ordered(lp, theta.size()); + EXPECT_TRUE((std::is_same::value)); + stan::test::expect_near_rel("deserializer tests", reference.val(), y.val()); } -TEST(deserializer_var_matrix, corr_matrix_constrain_jacobian) { +TEST(deserializer, read_ordered_jacobian) { std::vector theta_i; std::vector theta; theta.push_back(-2.0); + theta.push_back(3.0); theta.push_back(-1.0); theta.push_back(0.0); - theta.push_back(0.5); - theta.push_back(1.0); - theta.push_back(2.0); - theta.push_back(1.0); stan::io::deserializer deserializer(theta, theta_i); - stan::math::var lp = -9.2; - var_matrix_t R(deserializer.read_corr(lp, 3U)); - EXPECT_EQ(3, R.rows()); - EXPECT_EQ(3, R.cols()); - EXPECT_EQ(9, R.size()); - EXPECT_EQ(4U, deserializer.available()); - for (size_t i = 0; i < 3U; ++i) { - EXPECT_FLOAT_EQ(1.0, R.val()(i, i)); - for (size_t j = i + 1; j < 3U; ++j) - EXPECT_FLOAT_EQ(R.val()(i, j), R.val()(j, i)); - } - Eigen::SelfAdjointEigenSolver< - Eigen::Matrix> - solver(R.val(), Eigen::EigenvaluesOnly); - assert(solver.eigenvalues()[0] > 1E-10); - // FIXME: test jacobian + stan::math::var lp_ref = 0.0; + stan::math::var lp = 0.0; + auto reference = stan::math::ordered_constrain(stan::math::to_vector(theta), lp_ref); + auto y = deserializer.read_ordered(lp, theta.size()); + EXPECT_TRUE((std::is_same::value)); + stan::test::expect_near_rel("deserializer tests", reference.val(), y.val()); + EXPECT_FLOAT_EQ(lp_ref.val(), lp.val()); } -TEST(deserializer_var_matrix, cov_matrix_constrain) { +// positive ordered + +TEST(deserializer, read_positive_ordered_constrain) { std::vector theta_i; std::vector theta; theta.push_back(-2.0); + theta.push_back(3.0); theta.push_back(-1.0); theta.push_back(0.0); - theta.push_back(0.5); - theta.push_back(1.0); - theta.push_back(2.0); - theta.push_back(1.0); stan::io::deserializer deserializer(theta, theta_i); - stan::math::var lp = 0; - var_matrix_t S(deserializer.read_cov_matrix(lp, 3U)); - EXPECT_EQ(3, S.rows()); - EXPECT_EQ(3, S.cols()); - EXPECT_EQ(9, S.size()); - EXPECT_EQ(1U, deserializer.available()); - for (size_t i = 0; i < 3U; ++i) { - for (size_t j = i + 1; j < 3U; ++j) { - EXPECT_FLOAT_EQ(S.val()(i, j), S.val()(j, i)); - } - } - using eig_m = Eigen::Matrix; - Eigen::SelfAdjointEigenSolver solver(S.val(), Eigen::EigenvaluesOnly); - assert(solver.eigenvalues()[0] - > 1E-10); // check positive definite with smallest eigenvalue > 0 + stan::math::var lp = 0.0; + auto reference = stan::math::positive_ordered_constrain(stan::math::to_vector(theta)); + auto y = deserializer.read_positive_ordered(lp, theta.size()); + EXPECT_TRUE((std::is_same::value)); + stan::test::expect_near_rel("deserializer tests", reference.val(), y.val()); } -TEST(deserializer_var_matrix, cov_matrix_constrain_jacobian) { +TEST(deserializer, read_positive_ordered_jacobian) { std::vector theta_i; std::vector theta; theta.push_back(-2.0); + theta.push_back(3.0); theta.push_back(-1.0); theta.push_back(0.0); - theta.push_back(0.5); - theta.push_back(1.0); - theta.push_back(2.0); - theta.push_back(1.0); stan::io::deserializer deserializer(theta, theta_i); - stan::math::var lp = -3.1; - - var_matrix_t S(deserializer.read_cov_matrix(lp, 3U)); - - EXPECT_EQ(3, S.rows()); - EXPECT_EQ(3, S.cols()); - EXPECT_EQ(9, S.size()); - EXPECT_EQ(1U, deserializer.available()); - for (size_t i = 0; i < 3U; ++i) { - for (size_t j = i + 1; j < 3U; ++j) { - EXPECT_FLOAT_EQ(S.val()(i, j), S.val()(j, i)); - } - } - using eig_m = Eigen::Matrix; - Eigen::SelfAdjointEigenSolver solver(S.val(), Eigen::EigenvaluesOnly); - assert(solver.eigenvalues()[0] - > 1E-10); // check positive definite with smallest eigenvalue > 0 - // FIXME: test Jacobian + stan::math::var lp_ref = 0.0; + stan::math::var lp = 0.0; + auto reference = stan::math::positive_ordered_constrain(stan::math::to_vector(theta), lp_ref); + auto y = deserializer.read_positive_ordered(lp, theta.size()); + EXPECT_TRUE((std::is_same::value)); + stan::test::expect_near_rel("deserializer tests", reference.val(), y.val()); + EXPECT_FLOAT_EQ(lp_ref.val(), lp.val()); } -TEST(deserializer_var_matrix, cholesky_factor_cov_constrain_jacobian) { +// chol cov + +TEST(deserializer_var_matrix, cholesky_factor_cov_constrain) { std::vector theta_i; std::vector theta; for (int i = 0; i < 8; ++i) theta.push_back(-static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); - stan::math::var lp = 1.9; - var_matrix_t L( - deserializer.read_cholesky_factor_cov(lp, 3U, 3U)); - EXPECT_NO_THROW(stan::math::check_cholesky_factor( - "test_cholesky_factor_constrain", "L", L.val())); + stan::math::var lp = 0; + auto reference = + stan::math::cholesky_factor_constrain(stan::math::to_vector(theta).segment(0, 6), 3, 3); + auto L = deserializer.read_cholesky_factor_cov(lp, 3U, 3U); + EXPECT_TRUE((std::is_same::value)); EXPECT_EQ(3, L.rows()); EXPECT_EQ(3, L.cols()); EXPECT_EQ(9, L.size()); + stan::test::expect_near_rel("deserializer tests", reference.val(), L.val()); EXPECT_EQ(2U, deserializer.available()); - EXPECT_EQ(1.9 + log(L.val()(0, 0)) + log(L.val()(1, 1)) + log(L.val()(2, 2)), - lp.val()); } -TEST(deserializer_var_matrix, - cholesky_factor_cov_constrain_jacobian_asymmetric) { + +TEST(deserializer_var_matrix, cholesky_factor_cov_jacobian) { std::vector theta_i; std::vector theta; - for (int i = 0; i < 12; ++i) + for (int i = 0; i < 8; ++i) theta.push_back(-static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); - stan::math::var lp = 1.9; - var_matrix_t L( - deserializer.read_cholesky_factor_cov(lp, 4U, 3U)); - EXPECT_NO_THROW(stan::math::check_cholesky_factor( - "test_cholesky_factor_constrain", "L", L.val())); - EXPECT_EQ(4, L.rows()); + stan::math::var lp_ref = 0.0; + stan::math::var lp = 0.0; + auto reference = + stan::math::cholesky_factor_constrain(stan::math::to_vector(theta).segment(0, 6), 3, 3, lp_ref); + auto L = deserializer.read_cholesky_factor_cov(lp, 3U, 3U); + EXPECT_TRUE((std::is_same::value)); + EXPECT_EQ(3, L.rows()); EXPECT_EQ(3, L.cols()); - EXPECT_EQ(12, L.size()); + EXPECT_EQ(9, L.size()); + stan::test::expect_near_rel("deserializer tests", reference.val(), L.val()); + EXPECT_EQ(2U, deserializer.available()); + EXPECT_FLOAT_EQ(lp_ref.val(), lp.val()); +} + +TEST(deserializer_var_matrix, cholesky_factor_cov_constrain_non_square) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 8; ++i) + theta.push_back(-static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp = 0; + auto reference = + stan::math::cholesky_factor_constrain(stan::math::to_vector(theta).segment(0, 5), 3, 2); + auto L = deserializer.read_cholesky_factor_cov(lp, 3U, 2U); + EXPECT_TRUE((std::is_same::value)); + EXPECT_EQ(3, L.rows()); + EXPECT_EQ(2, L.cols()); + EXPECT_EQ(6, L.size()); + stan::test::expect_near_rel("deserializer tests", reference.val(), L.val()); EXPECT_EQ(3U, deserializer.available()); - EXPECT_EQ(1.9 + log(L.val()(0, 0)) + log(L.val()(1, 1)) + log(L.val()(2, 2)), - lp.val()); } +TEST(deserializer_var_matrix, cholesky_factor_cov_jacobian_non_square) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 8; ++i) + theta.push_back(-static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp_ref = 0.0; + stan::math::var lp = 0.0; + auto reference = + stan::math::cholesky_factor_constrain(stan::math::to_vector(theta).segment(0, 5), 3, 2, lp_ref); + auto L = deserializer.read_cholesky_factor_cov(lp, 3U, 2U); + EXPECT_TRUE((std::is_same::value)); + EXPECT_EQ(3, L.rows()); + EXPECT_EQ(2, L.cols()); + EXPECT_EQ(6, L.size()); + stan::test::expect_near_rel("deserializer tests", reference.val(), L.val()); + EXPECT_EQ(3U, deserializer.available()); + EXPECT_FLOAT_EQ(lp_ref.val(), lp.val()); +} + +// chol corr + TEST(deserializer_var_matrix, cholesky_factor_corr_constrain) { std::vector theta_i; std::vector theta; @@ -503,48 +459,113 @@ TEST(deserializer_var_matrix, cholesky_factor_corr_constrain) { theta.push_back(-static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp = 0; - var_matrix_t L( - deserializer.read_cholesky_factor_corr(lp, 3U)); - EXPECT_NO_THROW(stan::math::check_cholesky_factor_corr( - "test_cholesky_factor_corr_constrain", "L", L.val())); + auto reference = + stan::math::cholesky_corr_constrain(stan::math::to_vector(theta).segment(0, 3), 3); + auto L = deserializer.read_cholesky_factor_corr(lp, 3U); + EXPECT_TRUE((std::is_same::value)); EXPECT_EQ(3, L.rows()); EXPECT_EQ(3, L.cols()); EXPECT_EQ(9, L.size()); + stan::test::expect_near_rel("deserializer tests", reference.val(), L.val()); EXPECT_EQ(5U, deserializer.available()); } -// need lp version of ^ -TEST(deserializer_var_matrix, offset_multiplier_constrain) { +TEST(deserializer_var_matrix, cholesky_factor_corr_jacobian) { std::vector theta_i; std::vector theta; - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); + for (int i = 0; i < 8; ++i) + theta.push_back(-static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp_ref = 0.0; + stan::math::var lp = 0.0; + auto reference = + stan::math::cholesky_corr_constrain(stan::math::to_vector(theta).segment(0, 3), 3, lp_ref); + auto L = deserializer.read_cholesky_factor_corr(lp, 3U); + EXPECT_TRUE((std::is_same::value)); + EXPECT_EQ(3, L.rows()); + EXPECT_EQ(3, L.cols()); + EXPECT_EQ(9, L.size()); + stan::test::expect_near_rel("deserializer tests", reference.val(), L.val()); + EXPECT_EQ(5U, deserializer.available()); + EXPECT_FLOAT_EQ(lp_ref.val(), lp.val()); +} + +// cov + +TEST(deserializer_var_matrix, cov_matrix_constrain) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 8; ++i) + theta.push_back(-static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp = 0; - var_matrix_t phi( - deserializer.read_offset_multiplier(0, 1, lp, 2, 2)); - EXPECT_FLOAT_EQ(theta[0].val(), phi.val()(0, 0)); - EXPECT_FLOAT_EQ(theta[1].val(), phi.val()(1, 0)); - EXPECT_FLOAT_EQ(theta[2].val(), phi.val()(0, 1)); - EXPECT_FLOAT_EQ(theta[3].val(), phi.val()(1, 1)); + auto reference = + stan::math::cov_matrix_constrain(stan::math::to_vector(theta).segment(0, 6), 3); + auto L = deserializer.read_cov_matrix(lp, 3U); + EXPECT_TRUE((std::is_same::value)); + EXPECT_EQ(3, L.rows()); + EXPECT_EQ(3, L.cols()); + EXPECT_EQ(9, L.size()); + stan::test::expect_near_rel("deserializer tests", reference.val(), L.val()); + EXPECT_EQ(2U, deserializer.available()); } -TEST(deserializer_var_matrix, offset_multiplier_constrain_lp) { +TEST(deserializer_var_matrix, cov_matrix_jacobian) { std::vector theta_i; std::vector theta; - theta.push_back(3.0); - theta.push_back(-1.0); - theta.push_back(-2.0); - theta.push_back(0.0); + for (int i = 0; i < 8; ++i) + theta.push_back(-static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp_ref = 0.0; + stan::math::var lp = 0.0; + auto reference = + stan::math::cov_matrix_constrain(stan::math::to_vector(theta).segment(0, 6), 3, lp_ref); + auto L = deserializer.read_cov_matrix(lp, 3U); + EXPECT_TRUE((std::is_same::value)); + EXPECT_EQ(3, L.rows()); + EXPECT_EQ(3, L.cols()); + EXPECT_EQ(9, L.size()); + stan::test::expect_near_rel("deserializer tests", reference.val(), L.val()); + EXPECT_EQ(2U, deserializer.available()); + EXPECT_FLOAT_EQ(lp_ref.val(), lp.val()); +} + +// corr + +TEST(deserializer_var_matrix, corr_matrix_constrain) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 8; ++i) + theta.push_back(-static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp = 0; - var_matrix_t phi( - deserializer.read_offset_multiplier(0, 2, lp, 2, 2)); - EXPECT_FLOAT_EQ(theta[0].val() * 2, phi.val()(0, 0)); - EXPECT_FLOAT_EQ(theta[1].val() * 2, phi.val()(1, 0)); - EXPECT_FLOAT_EQ(theta[2].val() * 2, phi.val()(0, 1)); - EXPECT_FLOAT_EQ(theta[3].val() * 2, phi.val()(1, 1)); - EXPECT_FLOAT_EQ(lp.val(), std::log(2) * 4); + auto reference = + stan::math::corr_matrix_constrain(stan::math::to_vector(theta).segment(0, 3), 3); + auto L = deserializer.read_corr_matrix(lp, 3U); + EXPECT_TRUE((std::is_same::value)); + EXPECT_EQ(3, L.rows()); + EXPECT_EQ(3, L.cols()); + EXPECT_EQ(9, L.size()); + stan::test::expect_near_rel("deserializer tests", reference.val(), L.val()); + EXPECT_EQ(5U, deserializer.available()); +} + +TEST(deserializer_var_matrix, corr_matrix_jacobian) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 8; ++i) + theta.push_back(-static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp_ref = 0.0; + stan::math::var lp = 0.0; + auto reference = + stan::math::corr_matrix_constrain(stan::math::to_vector(theta).segment(0, 3), 3, lp_ref); + auto L = deserializer.read_corr_matrix(lp, 3U); + EXPECT_TRUE((std::is_same::value)); + EXPECT_EQ(3, L.rows()); + EXPECT_EQ(3, L.cols()); + EXPECT_EQ(9, L.size()); + stan::test::expect_near_rel("deserializer tests", reference.val(), L.val()); + EXPECT_EQ(5U, deserializer.available()); + EXPECT_FLOAT_EQ(lp_ref.val(), lp.val()); } From 606dce4bcd0c32134adba07a0d613b958f5de867 Mon Sep 17 00:00:00 2001 From: Stan Jenkins Date: Mon, 8 Mar 2021 18:55:18 +0000 Subject: [PATCH 20/29] [Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.04.1 (tags/RELEASE_600/final) --- .../unit/io/deserializer_stdvector_test.cpp | 216 +++++++++++------- src/test/unit/io/deserializer_test.cpp | 122 ++++++---- src/test/unit/io/deserializer_varmat_test.cpp | 106 +++++---- 3 files changed, 278 insertions(+), 166 deletions(-) diff --git a/src/test/unit/io/deserializer_stdvector_test.cpp b/src/test/unit/io/deserializer_stdvector_test.cpp index 4ad63df103f..75b0a70899e 100644 --- a/src/test/unit/io/deserializer_stdvector_test.cpp +++ b/src/test/unit/io/deserializer_stdvector_test.cpp @@ -3,7 +3,7 @@ #include #include -template +template void test_std_vector_deserializer_read(Sizes... sizes) { std::vector theta_i; std::vector theta; @@ -14,8 +14,9 @@ void test_std_vector_deserializer_read(Sizes... sizes) { stan::io::deserializer deserializer2(theta, theta_i); auto y = deserializer1.read>(4, sizes...); - for(size_t i = 0; i < 4; ++i) { - stan::test::expect_near_rel("test_std_vector_deserializer", y[i], deserializer2.read(sizes...)); + for (size_t i = 0; i < 4; ++i) { + stan::test::expect_near_rel("test_std_vector_deserializer", y[i], + deserializer2.read(sizes...)); } } @@ -24,13 +25,17 @@ TEST(deserializer_array, read_arrays) { test_std_vector_deserializer_read>(); test_std_vector_deserializer_read>(3); test_std_vector_deserializer_read(2); - test_std_vector_deserializer_read, Eigen::Dynamic, 1>>(2); + test_std_vector_deserializer_read< + Eigen::Matrix, Eigen::Dynamic, 1>>(2); test_std_vector_deserializer_read>(3, 2); test_std_vector_deserializer_read(2); - test_std_vector_deserializer_read, 1, Eigen::Dynamic>>(2); + test_std_vector_deserializer_read< + Eigen::Matrix, 1, Eigen::Dynamic>>(2); test_std_vector_deserializer_read>(3, 2); test_std_vector_deserializer_read(2, 2); - test_std_vector_deserializer_read, Eigen::Dynamic, Eigen::Dynamic>>(2, 2); + test_std_vector_deserializer_read< + Eigen::Matrix, Eigen::Dynamic, Eigen::Dynamic>>(2, + 2); test_std_vector_deserializer_read>(2, 3, 2); } @@ -49,10 +54,13 @@ TEST(deserializer_array, unit_vector) { { double lp_ref = 0.0; double lp = 0.0; - auto y = deserializer1.read_unit_vector, false>(lp, 4, 3); - for(size_t i = 0; i < 4; ++i) { - stan::test::expect_near_rel("test_std_vector_deserializer", y[i], - deserializer2.read_unit_vector(lp_ref, 3)); + auto y + = deserializer1.read_unit_vector, false>( + lp, 4, 3); + for (size_t i = 0; i < 4; ++i) { + stan::test::expect_near_rel( + "test_std_vector_deserializer", y[i], + deserializer2.read_unit_vector(lp_ref, 3)); } EXPECT_FLOAT_EQ(lp_ref, lp); } @@ -61,10 +69,12 @@ TEST(deserializer_array, unit_vector) { { double lp_ref = 0.0; double lp = 0.0; - auto y = deserializer1.read_unit_vector, true>(lp, 4, 3); - for(size_t i = 0; i < 4; ++i) { - stan::test::expect_near_rel("test_std_vector_deserializer", y[i], - deserializer2.read_unit_vector(lp_ref, 3)); + auto y = deserializer1.read_unit_vector, true>( + lp, 4, 3); + for (size_t i = 0; i < 4; ++i) { + stan::test::expect_near_rel( + "test_std_vector_deserializer", y[i], + deserializer2.read_unit_vector(lp_ref, 3)); } EXPECT_FLOAT_EQ(lp_ref, lp); } @@ -85,10 +95,12 @@ TEST(deserializer_array, simplex) { { double lp_ref = 0.0; double lp = 0.0; - auto y = deserializer1.read_simplex, false>(lp, 4, 3); - for(size_t i = 0; i < 4; ++i) { - stan::test::expect_near_rel("test_std_vector_deserializer", y[i], - deserializer2.read_simplex(lp_ref, 3)); + auto y = deserializer1.read_simplex, false>( + lp, 4, 3); + for (size_t i = 0; i < 4; ++i) { + stan::test::expect_near_rel( + "test_std_vector_deserializer", y[i], + deserializer2.read_simplex(lp_ref, 3)); } EXPECT_FLOAT_EQ(lp_ref, lp); } @@ -97,10 +109,12 @@ TEST(deserializer_array, simplex) { { double lp_ref = 0.0; double lp = 0.0; - auto y = deserializer1.read_simplex, true>(lp, 4, 3); - for(size_t i = 0; i < 4; ++i) { - stan::test::expect_near_rel("test_std_vector_deserializer", y[i], - deserializer2.read_simplex(lp_ref, 3)); + auto y = deserializer1.read_simplex, true>( + lp, 4, 3); + for (size_t i = 0; i < 4; ++i) { + stan::test::expect_near_rel( + "test_std_vector_deserializer", y[i], + deserializer2.read_simplex(lp_ref, 3)); } EXPECT_FLOAT_EQ(lp_ref, lp); } @@ -121,10 +135,12 @@ TEST(deserializer_array, ordered) { { double lp_ref = 0.0; double lp = 0.0; - auto y = deserializer1.read_ordered, false>(lp, 4, 3); - for(size_t i = 0; i < 4; ++i) { - stan::test::expect_near_rel("test_std_vector_deserializer", y[i], - deserializer2.read_ordered(lp_ref, 3)); + auto y = deserializer1.read_ordered, false>( + lp, 4, 3); + for (size_t i = 0; i < 4; ++i) { + stan::test::expect_near_rel( + "test_std_vector_deserializer", y[i], + deserializer2.read_ordered(lp_ref, 3)); } EXPECT_FLOAT_EQ(lp_ref, lp); } @@ -133,10 +149,12 @@ TEST(deserializer_array, ordered) { { double lp_ref = 0.0; double lp = 0.0; - auto y = deserializer1.read_ordered, true>(lp, 4, 3); - for(size_t i = 0; i < 4; ++i) { - stan::test::expect_near_rel("test_std_vector_deserializer", y[i], - deserializer2.read_ordered(lp_ref, 3)); + auto y = deserializer1.read_ordered, true>( + lp, 4, 3); + for (size_t i = 0; i < 4; ++i) { + stan::test::expect_near_rel( + "test_std_vector_deserializer", y[i], + deserializer2.read_ordered(lp_ref, 3)); } EXPECT_FLOAT_EQ(lp_ref, lp); } @@ -157,10 +175,14 @@ TEST(deserializer_array, positive_ordered) { { double lp_ref = 0.0; double lp = 0.0; - auto y = deserializer1.read_positive_ordered, false>(lp, 4, 3); - for(size_t i = 0; i < 4; ++i) { - stan::test::expect_near_rel("test_std_vector_deserializer", y[i], - deserializer2.read_positive_ordered(lp_ref, 3)); + auto y = deserializer1 + .read_positive_ordered, false>( + lp, 4, 3); + for (size_t i = 0; i < 4; ++i) { + stan::test::expect_near_rel( + "test_std_vector_deserializer", y[i], + deserializer2.read_positive_ordered(lp_ref, + 3)); } EXPECT_FLOAT_EQ(lp_ref, lp); } @@ -169,10 +191,14 @@ TEST(deserializer_array, positive_ordered) { { double lp_ref = 0.0; double lp = 0.0; - auto y = deserializer1.read_positive_ordered, true>(lp, 4, 3); - for(size_t i = 0; i < 4; ++i) { - stan::test::expect_near_rel("test_std_vector_deserializer", y[i], - deserializer2.read_positive_ordered(lp_ref, 3)); + auto y = deserializer1 + .read_positive_ordered, true>( + lp, 4, 3); + for (size_t i = 0; i < 4; ++i) { + stan::test::expect_near_rel( + "test_std_vector_deserializer", y[i], + deserializer2.read_positive_ordered(lp_ref, + 3)); } EXPECT_FLOAT_EQ(lp_ref, lp); } @@ -193,10 +219,14 @@ TEST(deserializer_array, chol_cov) { { double lp_ref = 0.0; double lp = 0.0; - auto y = deserializer1.read_cholesky_factor_cov, false>(lp, 4, 3, 3); - for(size_t i = 0; i < 4; ++i) { - stan::test::expect_near_rel("test_std_vector_deserializer", y[i], - deserializer2.read_cholesky_factor_cov(lp_ref, 3, 3)); + auto y = deserializer1 + .read_cholesky_factor_cov, false>( + lp, 4, 3, 3); + for (size_t i = 0; i < 4; ++i) { + stan::test::expect_near_rel( + "test_std_vector_deserializer", y[i], + deserializer2.read_cholesky_factor_cov(lp_ref, + 3, 3)); } EXPECT_FLOAT_EQ(lp_ref, lp); } @@ -205,10 +235,14 @@ TEST(deserializer_array, chol_cov) { { double lp_ref = 0.0; double lp = 0.0; - auto y = deserializer1.read_cholesky_factor_cov, true>(lp, 4, 3, 3); - for(size_t i = 0; i < 4; ++i) { - stan::test::expect_near_rel("test_std_vector_deserializer", y[i], - deserializer2.read_cholesky_factor_cov(lp_ref, 3, 3)); + auto y = deserializer1 + .read_cholesky_factor_cov, true>( + lp, 4, 3, 3); + for (size_t i = 0; i < 4; ++i) { + stan::test::expect_near_rel( + "test_std_vector_deserializer", y[i], + deserializer2.read_cholesky_factor_cov(lp_ref, + 3, 3)); } EXPECT_FLOAT_EQ(lp_ref, lp); } @@ -217,10 +251,14 @@ TEST(deserializer_array, chol_cov) { { double lp_ref = 0.0; double lp = 0.0; - auto y = deserializer1.read_cholesky_factor_cov, false>(lp, 4, 3, 2); - for(size_t i = 0; i < 4; ++i) { - stan::test::expect_near_rel("test_std_vector_deserializer", y[i], - deserializer2.read_cholesky_factor_cov(lp_ref, 3, 2)); + auto y = deserializer1 + .read_cholesky_factor_cov, false>( + lp, 4, 3, 2); + for (size_t i = 0; i < 4; ++i) { + stan::test::expect_near_rel( + "test_std_vector_deserializer", y[i], + deserializer2.read_cholesky_factor_cov(lp_ref, + 3, 2)); } EXPECT_FLOAT_EQ(lp_ref, lp); } @@ -229,10 +267,14 @@ TEST(deserializer_array, chol_cov) { { double lp_ref = 0.0; double lp = 0.0; - auto y = deserializer1.read_cholesky_factor_cov, true>(lp, 4, 3, 2); - for(size_t i = 0; i < 4; ++i) { - stan::test::expect_near_rel("test_std_vector_deserializer", y[i], - deserializer2.read_cholesky_factor_cov(lp_ref, 3, 2)); + auto y = deserializer1 + .read_cholesky_factor_cov, true>( + lp, 4, 3, 2); + for (size_t i = 0; i < 4; ++i) { + stan::test::expect_near_rel( + "test_std_vector_deserializer", y[i], + deserializer2.read_cholesky_factor_cov(lp_ref, + 3, 2)); } EXPECT_FLOAT_EQ(lp_ref, lp); } @@ -253,10 +295,15 @@ TEST(deserializer_array, chol_corr) { { double lp_ref = 0.0; double lp = 0.0; - auto y = deserializer1.read_cholesky_factor_corr, false>(lp, 4, 3); - for(size_t i = 0; i < 4; ++i) { - stan::test::expect_near_rel("test_std_vector_deserializer", y[i], - deserializer2.read_cholesky_factor_corr(lp_ref, 3)); + auto y + = deserializer1 + .read_cholesky_factor_corr, false>( + lp, 4, 3); + for (size_t i = 0; i < 4; ++i) { + stan::test::expect_near_rel( + "test_std_vector_deserializer", y[i], + deserializer2.read_cholesky_factor_corr( + lp_ref, 3)); } EXPECT_FLOAT_EQ(lp_ref, lp); } @@ -265,10 +312,14 @@ TEST(deserializer_array, chol_corr) { { double lp_ref = 0.0; double lp = 0.0; - auto y = deserializer1.read_cholesky_factor_corr, true>(lp, 4, 3); - for(size_t i = 0; i < 4; ++i) { - stan::test::expect_near_rel("test_std_vector_deserializer", y[i], - deserializer2.read_cholesky_factor_corr(lp_ref, 3)); + auto y = deserializer1 + .read_cholesky_factor_corr, true>( + lp, 4, 3); + for (size_t i = 0; i < 4; ++i) { + stan::test::expect_near_rel( + "test_std_vector_deserializer", y[i], + deserializer2.read_cholesky_factor_corr(lp_ref, + 3)); } EXPECT_FLOAT_EQ(lp_ref, lp); } @@ -289,10 +340,12 @@ TEST(deserializer_array, cov_matrix) { { double lp_ref = 0.0; double lp = 0.0; - auto y = deserializer1.read_cov_matrix, false>(lp, 4, 3); - for(size_t i = 0; i < 4; ++i) { - stan::test::expect_near_rel("test_std_vector_deserializer", y[i], - deserializer2.read_cov_matrix(lp_ref, 3)); + auto y = deserializer1.read_cov_matrix, false>( + lp, 4, 3); + for (size_t i = 0; i < 4; ++i) { + stan::test::expect_near_rel( + "test_std_vector_deserializer", y[i], + deserializer2.read_cov_matrix(lp_ref, 3)); } EXPECT_FLOAT_EQ(lp_ref, lp); } @@ -301,10 +354,12 @@ TEST(deserializer_array, cov_matrix) { { double lp_ref = 0.0; double lp = 0.0; - auto y = deserializer1.read_cov_matrix, true>(lp, 4, 3); - for(size_t i = 0; i < 4; ++i) { - stan::test::expect_near_rel("test_std_vector_deserializer", y[i], - deserializer2.read_cov_matrix(lp_ref, 3)); + auto y = deserializer1.read_cov_matrix, true>( + lp, 4, 3); + for (size_t i = 0; i < 4; ++i) { + stan::test::expect_near_rel( + "test_std_vector_deserializer", y[i], + deserializer2.read_cov_matrix(lp_ref, 3)); } EXPECT_FLOAT_EQ(lp_ref, lp); } @@ -325,10 +380,13 @@ TEST(deserializer_array, corr_matrix) { { double lp_ref = 0.0; double lp = 0.0; - auto y = deserializer1.read_corr_matrix, false>(lp, 4, 3); - for(size_t i = 0; i < 4; ++i) { - stan::test::expect_near_rel("test_std_vector_deserializer", y[i], - deserializer2.read_corr_matrix(lp_ref, 3)); + auto y + = deserializer1.read_corr_matrix, false>( + lp, 4, 3); + for (size_t i = 0; i < 4; ++i) { + stan::test::expect_near_rel( + "test_std_vector_deserializer", y[i], + deserializer2.read_corr_matrix(lp_ref, 3)); } EXPECT_FLOAT_EQ(lp_ref, lp); } @@ -337,10 +395,12 @@ TEST(deserializer_array, corr_matrix) { { double lp_ref = 0.0; double lp = 0.0; - auto y = deserializer1.read_corr_matrix, true>(lp, 4, 3); - for(size_t i = 0; i < 4; ++i) { - stan::test::expect_near_rel("test_std_vector_deserializer", y[i], - deserializer2.read_corr_matrix(lp_ref, 3)); + auto y = deserializer1.read_corr_matrix, true>( + lp, 4, 3); + for (size_t i = 0; i < 4; ++i) { + stan::test::expect_near_rel( + "test_std_vector_deserializer", y[i], + deserializer2.read_corr_matrix(lp_ref, 3)); } EXPECT_FLOAT_EQ(lp_ref, lp); } diff --git a/src/test/unit/io/deserializer_test.cpp b/src/test/unit/io/deserializer_test.cpp index ff5ba9dc68b..56d08cf8474 100644 --- a/src/test/unit/io/deserializer_test.cpp +++ b/src/test/unit/io/deserializer_test.cpp @@ -138,7 +138,8 @@ TEST(deserializer_row_vector, complex_read) { double x = deserializer.read(); EXPECT_FLOAT_EQ(static_cast(i), x); } - using complex_row_vec = Eigen::Matrix, 1, Eigen::Dynamic>; + using complex_row_vec + = Eigen::Matrix, 1, Eigen::Dynamic>; complex_row_vec y = deserializer.read(4); EXPECT_EQ(1, y.rows()); EXPECT_EQ(4, y.cols()); @@ -218,8 +219,7 @@ TEST(deserializer_array, read) { double x = deserializer.read(); EXPECT_FLOAT_EQ(static_cast(i), x); } - std::vector y - = deserializer.read>(4); + std::vector y = deserializer.read>(4); EXPECT_EQ(4, y.size()); EXPECT_FLOAT_EQ(7.0, y[0]); EXPECT_FLOAT_EQ(8.0, y[1]); @@ -262,7 +262,7 @@ TEST(deserializer_array, read_vector) { theta.push_back(static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); std::vector y - = deserializer.read>(4, 2); + = deserializer.read>(4, 2); EXPECT_EQ(4, y.size()); EXPECT_FLOAT_EQ(0.0, y[0](0)); EXPECT_FLOAT_EQ(1.0, y[0](1)); @@ -325,14 +325,20 @@ TEST(deserializer, zeroSizeVecs) { EXPECT_THROW(deserializer.read>(), std::runtime_error); EXPECT_THROW(deserializer.read>(3), std::runtime_error); EXPECT_THROW(deserializer.read(2), std::runtime_error); - EXPECT_THROW((deserializer.read, Eigen::Dynamic, 1>>(2)), std::runtime_error); - EXPECT_THROW(deserializer.read>(3, 2), std::runtime_error); - EXPECT_THROW(deserializer.read(2), std::runtime_error); - EXPECT_THROW((deserializer.read, 1, Eigen::Dynamic>>(2)), std::runtime_error); - EXPECT_THROW(deserializer.read>(3, 2), std::runtime_error); - EXPECT_THROW(deserializer.read(2, 2), std::runtime_error); - EXPECT_THROW((deserializer.read, Eigen::Dynamic, Eigen::Dynamic>>(2, 2)), std::runtime_error); - EXPECT_THROW(deserializer.read>(2, 3, 2), std::runtime_error); + EXPECT_THROW((deserializer.read, + Eigen::Dynamic, 1>>(2)), std::runtime_error); + EXPECT_THROW(deserializer.read>(3, 2), + std::runtime_error); EXPECT_THROW(deserializer.read(2), + std::runtime_error); + EXPECT_THROW((deserializer.read, 1, + Eigen::Dynamic>>(2)), std::runtime_error); + EXPECT_THROW(deserializer.read>(3, 2), + std::runtime_error); EXPECT_THROW(deserializer.read(2, 2), + std::runtime_error); + EXPECT_THROW((deserializer.read, + Eigen::Dynamic, Eigen::Dynamic>>(2, 2)), std::runtime_error); + EXPECT_THROW(deserializer.read>(2, 3, 2), + std::runtime_error); }*/ // lb @@ -522,9 +528,11 @@ TEST(deserializer_vector, unit_vector_constrain) { theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); double lp = 0; - Eigen::VectorXd reference = stan::math::unit_vector_constrain(stan::math::to_vector(theta)); - Eigen::VectorXd phi(deserializer.read_unit_vector(lp, 4)); - for(size_t i = 0; i < phi.size(); ++i) { + Eigen::VectorXd reference + = stan::math::unit_vector_constrain(stan::math::to_vector(theta)); + Eigen::VectorXd phi( + deserializer.read_unit_vector(lp, 4)); + for (size_t i = 0; i < phi.size(); ++i) { EXPECT_FLOAT_EQ(reference(i), phi[i]); } } @@ -539,9 +547,11 @@ TEST(deserializer_vector, unit_vector_jacobian) { stan::io::deserializer deserializer(theta, theta_i); double lp = 0.0; double lp_ref = 0.0; - Eigen::VectorXd reference = stan::math::unit_vector_constrain(stan::math::to_vector(theta), lp_ref); - Eigen::VectorXd phi(deserializer.read_unit_vector(lp, 4)); - for(size_t i = 0; i < phi.size(); ++i) { + Eigen::VectorXd reference + = stan::math::unit_vector_constrain(stan::math::to_vector(theta), lp_ref); + Eigen::VectorXd phi( + deserializer.read_unit_vector(lp, 4)); + for (size_t i = 0; i < phi.size(); ++i) { EXPECT_FLOAT_EQ(reference(i), phi[i]); } EXPECT_FLOAT_EQ(lp_ref, lp); @@ -558,9 +568,10 @@ TEST(deserializer_vector, simplex_constrain) { theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); double lp = 0; - Eigen::VectorXd reference = stan::math::simplex_constrain(stan::math::to_vector(theta)); + Eigen::VectorXd reference + = stan::math::simplex_constrain(stan::math::to_vector(theta)); Eigen::VectorXd phi(deserializer.read_simplex(lp, 4)); - for(size_t i = 0; i < phi.size(); ++i) { + for (size_t i = 0; i < phi.size(); ++i) { EXPECT_FLOAT_EQ(reference(i), phi[i]); } } @@ -575,9 +586,10 @@ TEST(deserializer_vector, simplex_jacobian) { stan::io::deserializer deserializer(theta, theta_i); double lp = 0.0; double lp_ref = 0.0; - Eigen::VectorXd reference = stan::math::simplex_constrain(stan::math::to_vector(theta), lp_ref); + Eigen::VectorXd reference + = stan::math::simplex_constrain(stan::math::to_vector(theta), lp_ref); Eigen::VectorXd phi(deserializer.read_simplex(lp, 4)); - for(size_t i = 0; i < phi.size(); ++i) { + for (size_t i = 0; i < phi.size(); ++i) { EXPECT_FLOAT_EQ(reference(i), phi[i]); } EXPECT_FLOAT_EQ(lp_ref, lp); @@ -684,9 +696,11 @@ TEST(deserializer_matrix, cholesky_factor_cov_constrain) { theta.push_back(-static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); double lp = 0; - Eigen::MatrixXd reference = - stan::math::cholesky_factor_constrain(stan::math::to_vector(theta).segment(0, 6), 3, 3); - Eigen::MatrixXd L(deserializer.read_cholesky_factor_cov(lp, 3U, 3U)); + Eigen::MatrixXd reference = stan::math::cholesky_factor_constrain( + stan::math::to_vector(theta).segment(0, 6), 3, 3); + Eigen::MatrixXd L( + deserializer.read_cholesky_factor_cov(lp, 3U, + 3U)); EXPECT_EQ(3, L.rows()); EXPECT_EQ(3, L.cols()); EXPECT_EQ(9, L.size()); @@ -702,9 +716,10 @@ TEST(deserializer_matrix, cholesky_factor_cov_jacobian) { stan::io::deserializer deserializer(theta, theta_i); double lp_ref = 0.0; double lp = 0.0; - Eigen::MatrixXd reference = - stan::math::cholesky_factor_constrain(stan::math::to_vector(theta).segment(0, 6), 3, 3, lp_ref); - Eigen::MatrixXd L(deserializer.read_cholesky_factor_cov(lp, 3U, 3U)); + Eigen::MatrixXd reference = stan::math::cholesky_factor_constrain( + stan::math::to_vector(theta).segment(0, 6), 3, 3, lp_ref); + Eigen::MatrixXd L( + deserializer.read_cholesky_factor_cov(lp, 3U, 3U)); EXPECT_EQ(3, L.rows()); EXPECT_EQ(3, L.cols()); EXPECT_EQ(9, L.size()); @@ -720,9 +735,11 @@ TEST(deserializer_matrix, cholesky_factor_cov_constrain_non_square) { theta.push_back(-static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); double lp = 0; - Eigen::MatrixXd reference = - stan::math::cholesky_factor_constrain(stan::math::to_vector(theta).segment(0, 5), 3, 2); - Eigen::MatrixXd L(deserializer.read_cholesky_factor_cov(lp, 3U, 2U)); + Eigen::MatrixXd reference = stan::math::cholesky_factor_constrain( + stan::math::to_vector(theta).segment(0, 5), 3, 2); + Eigen::MatrixXd L( + deserializer.read_cholesky_factor_cov(lp, 3U, + 2U)); EXPECT_EQ(3, L.rows()); EXPECT_EQ(2, L.cols()); EXPECT_EQ(6, L.size()); @@ -738,9 +755,10 @@ TEST(deserializer_matrix, cholesky_factor_cov_jacobian_non_square) { stan::io::deserializer deserializer(theta, theta_i); double lp_ref = 0.0; double lp = 0.0; - Eigen::MatrixXd reference = - stan::math::cholesky_factor_constrain(stan::math::to_vector(theta).segment(0, 5), 3, 2, lp_ref); - Eigen::MatrixXd L(deserializer.read_cholesky_factor_cov(lp, 3U, 2U)); + Eigen::MatrixXd reference = stan::math::cholesky_factor_constrain( + stan::math::to_vector(theta).segment(0, 5), 3, 2, lp_ref); + Eigen::MatrixXd L( + deserializer.read_cholesky_factor_cov(lp, 3U, 2U)); EXPECT_EQ(3, L.rows()); EXPECT_EQ(2, L.cols()); EXPECT_EQ(6, L.size()); @@ -758,8 +776,10 @@ TEST(deserializer_matrix, cholesky_factor_corr_constrain) { theta.push_back(-static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); double lp = 0; - Eigen::MatrixXd reference = stan::math::cholesky_corr_constrain(stan::math::to_vector(theta).segment(0, 3), 3); - Eigen::MatrixXd L(deserializer.read_cholesky_factor_corr(lp, 3U)); + Eigen::MatrixXd reference = stan::math::cholesky_corr_constrain( + stan::math::to_vector(theta).segment(0, 3), 3); + Eigen::MatrixXd L( + deserializer.read_cholesky_factor_corr(lp, 3U)); EXPECT_NO_THROW(stan::math::check_cholesky_factor_corr( "test_cholesky_factor_corr_constrain", "L", L)); EXPECT_EQ(3, L.rows()); @@ -777,8 +797,10 @@ TEST(deserializer_matrix, cholesky_factor_corr_jacobian) { stan::io::deserializer deserializer(theta, theta_i); double lp_ref = 0.0; double lp = 0.0; - Eigen::MatrixXd reference = stan::math::cholesky_corr_constrain(stan::math::to_vector(theta).segment(0, 3), 3, lp_ref); - Eigen::MatrixXd L(deserializer.read_cholesky_factor_corr(lp, 3U)); + Eigen::MatrixXd reference = stan::math::cholesky_corr_constrain( + stan::math::to_vector(theta).segment(0, 3), 3, lp_ref); + Eigen::MatrixXd L( + deserializer.read_cholesky_factor_corr(lp, 3U)); EXPECT_NO_THROW(stan::math::check_cholesky_factor_corr( "test_cholesky_factor_corr_constrain", "L", L)); EXPECT_EQ(3, L.rows()); @@ -798,8 +820,10 @@ TEST(deserializer_matrix, cov_matrix_constrain) { theta.push_back(-static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); double lp = 0; - Eigen::MatrixXd reference = stan::math::cov_matrix_constrain(stan::math::to_vector(theta).segment(0, 6), 3); - Eigen::MatrixXd L(deserializer.read_cov_matrix(lp, 3U)); + Eigen::MatrixXd reference = stan::math::cov_matrix_constrain( + stan::math::to_vector(theta).segment(0, 6), 3); + Eigen::MatrixXd L( + deserializer.read_cov_matrix(lp, 3U)); EXPECT_EQ(3, L.rows()); EXPECT_EQ(3, L.cols()); EXPECT_EQ(9, L.size()); @@ -815,8 +839,10 @@ TEST(deserializer_matrix, cov_matrix_jacobian) { stan::io::deserializer deserializer(theta, theta_i); double lp_ref = 0.0; double lp = 0.0; - Eigen::MatrixXd reference = stan::math::cov_matrix_constrain(stan::math::to_vector(theta).segment(0, 6), 3, lp_ref); - Eigen::MatrixXd L(deserializer.read_cov_matrix(lp, 3U)); + Eigen::MatrixXd reference = stan::math::cov_matrix_constrain( + stan::math::to_vector(theta).segment(0, 6), 3, lp_ref); + Eigen::MatrixXd L( + deserializer.read_cov_matrix(lp, 3U)); EXPECT_EQ(3, L.rows()); EXPECT_EQ(3, L.cols()); EXPECT_EQ(9, L.size()); @@ -834,8 +860,10 @@ TEST(deserializer_matrix, corr_matrix_constrain) { theta.push_back(-static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); double lp = 0; - Eigen::MatrixXd reference = stan::math::corr_matrix_constrain(stan::math::to_vector(theta).segment(0, 3), 3); - Eigen::MatrixXd L(deserializer.read_corr_matrix(lp, 3U)); + Eigen::MatrixXd reference = stan::math::corr_matrix_constrain( + stan::math::to_vector(theta).segment(0, 3), 3); + Eigen::MatrixXd L( + deserializer.read_corr_matrix(lp, 3U)); EXPECT_EQ(3, L.rows()); EXPECT_EQ(3, L.cols()); EXPECT_EQ(9, L.size()); @@ -851,8 +879,10 @@ TEST(deserializer_matrix, corr_matrix_jacobian) { stan::io::deserializer deserializer(theta, theta_i); double lp_ref = 0.0; double lp = 0.0; - Eigen::MatrixXd reference = stan::math::corr_matrix_constrain(stan::math::to_vector(theta).segment(0, 3), 3, lp_ref); - Eigen::MatrixXd L(deserializer.read_corr_matrix(lp, 3U)); + Eigen::MatrixXd reference = stan::math::corr_matrix_constrain( + stan::math::to_vector(theta).segment(0, 3), 3, lp_ref); + Eigen::MatrixXd L( + deserializer.read_corr_matrix(lp, 3U)); EXPECT_EQ(3, L.rows()); EXPECT_EQ(3, L.cols()); EXPECT_EQ(9, L.size()); diff --git a/src/test/unit/io/deserializer_varmat_test.cpp b/src/test/unit/io/deserializer_varmat_test.cpp index 4a5717a7566..7d55ece66c4 100644 --- a/src/test/unit/io/deserializer_varmat_test.cpp +++ b/src/test/unit/io/deserializer_varmat_test.cpp @@ -127,7 +127,8 @@ TEST(deserializer, read_lb_constrain_jacobian) { stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp_ref = 0.0; stan::math::var lp = 0.0; - auto reference = stan::math::lb_constrain(stan::math::to_vector(theta), 1.5, lp_ref); + auto reference + = stan::math::lb_constrain(stan::math::to_vector(theta), 1.5, lp_ref); auto y = deserializer.read_lb(1.5, lp, theta.size()); EXPECT_TRUE((std::is_same::value)); stan::test::expect_near_rel("deserializer tests", reference.val(), y.val()); @@ -161,7 +162,8 @@ TEST(deserializer, read_ub_constrain_jacobian) { stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp_ref = 0.0; stan::math::var lp = 0.0; - auto reference = stan::math::ub_constrain(stan::math::to_vector(theta), 1.5, lp_ref); + auto reference + = stan::math::ub_constrain(stan::math::to_vector(theta), 1.5, lp_ref); auto y = deserializer.read_ub(1.5, lp, theta.size()); EXPECT_TRUE((std::is_same::value)); stan::test::expect_near_rel("deserializer tests", reference.val(), y.val()); @@ -179,8 +181,10 @@ TEST(deserializer, read_lub_constrain) { theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp = 0.0; - auto reference = stan::math::lub_constrain(stan::math::to_vector(theta), 1.0, 2.0); - auto y = deserializer.read_lub(1.0, 2.0, lp, theta.size()); + auto reference + = stan::math::lub_constrain(stan::math::to_vector(theta), 1.0, 2.0); + auto y + = deserializer.read_lub(1.0, 2.0, lp, theta.size()); EXPECT_TRUE((std::is_same::value)); stan::test::expect_near_rel("deserializer tests", reference.val(), y.val()); } @@ -195,8 +199,10 @@ TEST(deserializer, read_lub_constrain_jacobian) { stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp_ref = 0.0; stan::math::var lp = 0.0; - auto reference = stan::math::lub_constrain(stan::math::to_vector(theta), 1.0, 2.0, lp_ref); - auto y = deserializer.read_lub(1.0, 2.0, lp, theta.size()); + auto reference = stan::math::lub_constrain(stan::math::to_vector(theta), 1.0, + 2.0, lp_ref); + auto y + = deserializer.read_lub(1.0, 2.0, lp, theta.size()); EXPECT_TRUE((std::is_same::value)); stan::test::expect_near_rel("deserializer tests", reference.val(), y.val()); EXPECT_FLOAT_EQ(lp_ref.val(), lp.val()); @@ -213,8 +219,10 @@ TEST(deserializer, read_offset_multiplier_constrain) { theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp = 0.0; - auto reference = stan::math::offset_multiplier_constrain(stan::math::to_vector(theta), 1.0, 2.0); - auto y = deserializer.read_offset_multiplier(1.0, 2.0, lp, theta.size()); + auto reference = stan::math::offset_multiplier_constrain( + stan::math::to_vector(theta), 1.0, 2.0); + auto y = deserializer.read_offset_multiplier( + 1.0, 2.0, lp, theta.size()); EXPECT_TRUE((std::is_same::value)); stan::test::expect_near_rel("deserializer tests", reference.val(), y.val()); } @@ -229,8 +237,10 @@ TEST(deserializer, read_offset_multiplier_jacobian) { stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp_ref = 0.0; stan::math::var lp = 0.0; - auto reference = stan::math::offset_multiplier_constrain(stan::math::to_vector(theta), 1.0, 2.0, lp_ref); - auto y = deserializer.read_offset_multiplier(1.0, 2.0, lp, theta.size()); + auto reference = stan::math::offset_multiplier_constrain( + stan::math::to_vector(theta), 1.0, 2.0, lp_ref); + auto y = deserializer.read_offset_multiplier( + 1.0, 2.0, lp, theta.size()); EXPECT_TRUE((std::is_same::value)); stan::test::expect_near_rel("deserializer tests", reference.val(), y.val()); EXPECT_FLOAT_EQ(lp_ref.val(), lp.val()); @@ -247,7 +257,8 @@ TEST(deserializer, read_unit_vector_constrain) { theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp = 0.0; - auto reference = stan::math::unit_vector_constrain(stan::math::to_vector(theta)); + auto reference + = stan::math::unit_vector_constrain(stan::math::to_vector(theta)); auto y = deserializer.read_unit_vector(lp, theta.size()); EXPECT_TRUE((std::is_same::value)); stan::test::expect_near_rel("deserializer tests", reference.val(), y.val()); @@ -263,7 +274,8 @@ TEST(deserializer, read_unit_vector_jacobian) { stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp_ref = 0.0; stan::math::var lp = 0.0; - auto reference = stan::math::unit_vector_constrain(stan::math::to_vector(theta), lp_ref); + auto reference + = stan::math::unit_vector_constrain(stan::math::to_vector(theta), lp_ref); auto y = deserializer.read_unit_vector(lp, theta.size()); EXPECT_TRUE((std::is_same::value)); stan::test::expect_near_rel("deserializer tests", reference.val(), y.val()); @@ -297,7 +309,8 @@ TEST(deserializer, read_simplex_jacobian) { stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp_ref = 0.0; stan::math::var lp = 0.0; - auto reference = stan::math::simplex_constrain(stan::math::to_vector(theta), lp_ref); + auto reference + = stan::math::simplex_constrain(stan::math::to_vector(theta), lp_ref); auto y = deserializer.read_simplex(lp, theta.size()); EXPECT_TRUE((std::is_same::value)); stan::test::expect_near_rel("deserializer tests", reference.val(), y.val()); @@ -331,7 +344,8 @@ TEST(deserializer, read_ordered_jacobian) { stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp_ref = 0.0; stan::math::var lp = 0.0; - auto reference = stan::math::ordered_constrain(stan::math::to_vector(theta), lp_ref); + auto reference + = stan::math::ordered_constrain(stan::math::to_vector(theta), lp_ref); auto y = deserializer.read_ordered(lp, theta.size()); EXPECT_TRUE((std::is_same::value)); stan::test::expect_near_rel("deserializer tests", reference.val(), y.val()); @@ -349,8 +363,10 @@ TEST(deserializer, read_positive_ordered_constrain) { theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp = 0.0; - auto reference = stan::math::positive_ordered_constrain(stan::math::to_vector(theta)); - auto y = deserializer.read_positive_ordered(lp, theta.size()); + auto reference + = stan::math::positive_ordered_constrain(stan::math::to_vector(theta)); + auto y = deserializer.read_positive_ordered( + lp, theta.size()); EXPECT_TRUE((std::is_same::value)); stan::test::expect_near_rel("deserializer tests", reference.val(), y.val()); } @@ -365,8 +381,10 @@ TEST(deserializer, read_positive_ordered_jacobian) { stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp_ref = 0.0; stan::math::var lp = 0.0; - auto reference = stan::math::positive_ordered_constrain(stan::math::to_vector(theta), lp_ref); - auto y = deserializer.read_positive_ordered(lp, theta.size()); + auto reference = stan::math::positive_ordered_constrain( + stan::math::to_vector(theta), lp_ref); + auto y = deserializer.read_positive_ordered(lp, + theta.size()); EXPECT_TRUE((std::is_same::value)); stan::test::expect_near_rel("deserializer tests", reference.val(), y.val()); EXPECT_FLOAT_EQ(lp_ref.val(), lp.val()); @@ -381,9 +399,10 @@ TEST(deserializer_var_matrix, cholesky_factor_cov_constrain) { theta.push_back(-static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp = 0; - auto reference = - stan::math::cholesky_factor_constrain(stan::math::to_vector(theta).segment(0, 6), 3, 3); - auto L = deserializer.read_cholesky_factor_cov(lp, 3U, 3U); + auto reference = stan::math::cholesky_factor_constrain( + stan::math::to_vector(theta).segment(0, 6), 3, 3); + auto L + = deserializer.read_cholesky_factor_cov(lp, 3U, 3U); EXPECT_TRUE((std::is_same::value)); EXPECT_EQ(3, L.rows()); EXPECT_EQ(3, L.cols()); @@ -400,9 +419,10 @@ TEST(deserializer_var_matrix, cholesky_factor_cov_jacobian) { stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp_ref = 0.0; stan::math::var lp = 0.0; - auto reference = - stan::math::cholesky_factor_constrain(stan::math::to_vector(theta).segment(0, 6), 3, 3, lp_ref); - auto L = deserializer.read_cholesky_factor_cov(lp, 3U, 3U); + auto reference = stan::math::cholesky_factor_constrain( + stan::math::to_vector(theta).segment(0, 6), 3, 3, lp_ref); + auto L + = deserializer.read_cholesky_factor_cov(lp, 3U, 3U); EXPECT_TRUE((std::is_same::value)); EXPECT_EQ(3, L.rows()); EXPECT_EQ(3, L.cols()); @@ -419,9 +439,10 @@ TEST(deserializer_var_matrix, cholesky_factor_cov_constrain_non_square) { theta.push_back(-static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp = 0; - auto reference = - stan::math::cholesky_factor_constrain(stan::math::to_vector(theta).segment(0, 5), 3, 2); - auto L = deserializer.read_cholesky_factor_cov(lp, 3U, 2U); + auto reference = stan::math::cholesky_factor_constrain( + stan::math::to_vector(theta).segment(0, 5), 3, 2); + auto L + = deserializer.read_cholesky_factor_cov(lp, 3U, 2U); EXPECT_TRUE((std::is_same::value)); EXPECT_EQ(3, L.rows()); EXPECT_EQ(2, L.cols()); @@ -438,9 +459,10 @@ TEST(deserializer_var_matrix, cholesky_factor_cov_jacobian_non_square) { stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp_ref = 0.0; stan::math::var lp = 0.0; - auto reference = - stan::math::cholesky_factor_constrain(stan::math::to_vector(theta).segment(0, 5), 3, 2, lp_ref); - auto L = deserializer.read_cholesky_factor_cov(lp, 3U, 2U); + auto reference = stan::math::cholesky_factor_constrain( + stan::math::to_vector(theta).segment(0, 5), 3, 2, lp_ref); + auto L + = deserializer.read_cholesky_factor_cov(lp, 3U, 2U); EXPECT_TRUE((std::is_same::value)); EXPECT_EQ(3, L.rows()); EXPECT_EQ(2, L.cols()); @@ -459,8 +481,8 @@ TEST(deserializer_var_matrix, cholesky_factor_corr_constrain) { theta.push_back(-static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp = 0; - auto reference = - stan::math::cholesky_corr_constrain(stan::math::to_vector(theta).segment(0, 3), 3); + auto reference = stan::math::cholesky_corr_constrain( + stan::math::to_vector(theta).segment(0, 3), 3); auto L = deserializer.read_cholesky_factor_corr(lp, 3U); EXPECT_TRUE((std::is_same::value)); EXPECT_EQ(3, L.rows()); @@ -478,8 +500,8 @@ TEST(deserializer_var_matrix, cholesky_factor_corr_jacobian) { stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp_ref = 0.0; stan::math::var lp = 0.0; - auto reference = - stan::math::cholesky_corr_constrain(stan::math::to_vector(theta).segment(0, 3), 3, lp_ref); + auto reference = stan::math::cholesky_corr_constrain( + stan::math::to_vector(theta).segment(0, 3), 3, lp_ref); auto L = deserializer.read_cholesky_factor_corr(lp, 3U); EXPECT_TRUE((std::is_same::value)); EXPECT_EQ(3, L.rows()); @@ -499,8 +521,8 @@ TEST(deserializer_var_matrix, cov_matrix_constrain) { theta.push_back(-static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp = 0; - auto reference = - stan::math::cov_matrix_constrain(stan::math::to_vector(theta).segment(0, 6), 3); + auto reference = stan::math::cov_matrix_constrain( + stan::math::to_vector(theta).segment(0, 6), 3); auto L = deserializer.read_cov_matrix(lp, 3U); EXPECT_TRUE((std::is_same::value)); EXPECT_EQ(3, L.rows()); @@ -518,8 +540,8 @@ TEST(deserializer_var_matrix, cov_matrix_jacobian) { stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp_ref = 0.0; stan::math::var lp = 0.0; - auto reference = - stan::math::cov_matrix_constrain(stan::math::to_vector(theta).segment(0, 6), 3, lp_ref); + auto reference = stan::math::cov_matrix_constrain( + stan::math::to_vector(theta).segment(0, 6), 3, lp_ref); auto L = deserializer.read_cov_matrix(lp, 3U); EXPECT_TRUE((std::is_same::value)); EXPECT_EQ(3, L.rows()); @@ -539,8 +561,8 @@ TEST(deserializer_var_matrix, corr_matrix_constrain) { theta.push_back(-static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp = 0; - auto reference = - stan::math::corr_matrix_constrain(stan::math::to_vector(theta).segment(0, 3), 3); + auto reference = stan::math::corr_matrix_constrain( + stan::math::to_vector(theta).segment(0, 3), 3); auto L = deserializer.read_corr_matrix(lp, 3U); EXPECT_TRUE((std::is_same::value)); EXPECT_EQ(3, L.rows()); @@ -558,8 +580,8 @@ TEST(deserializer_var_matrix, corr_matrix_jacobian) { stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp_ref = 0.0; stan::math::var lp = 0.0; - auto reference = - stan::math::corr_matrix_constrain(stan::math::to_vector(theta).segment(0, 3), 3, lp_ref); + auto reference = stan::math::corr_matrix_constrain( + stan::math::to_vector(theta).segment(0, 3), 3, lp_ref); auto L = deserializer.read_corr_matrix(lp, 3U); EXPECT_TRUE((std::is_same::value)); EXPECT_EQ(3, L.rows()); From 790620827f312e68f5b33ca1648c3896c3cc8f61 Mon Sep 17 00:00:00 2001 From: Ben Date: Mon, 8 Mar 2021 13:57:31 -0500 Subject: [PATCH 21/29] Added back out of bounds checks --- src/test/unit/io/deserializer_test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/unit/io/deserializer_test.cpp b/src/test/unit/io/deserializer_test.cpp index ff5ba9dc68b..7ba1e47043e 100644 --- a/src/test/unit/io/deserializer_test.cpp +++ b/src/test/unit/io/deserializer_test.cpp @@ -299,7 +299,7 @@ TEST(deserializer, zeroSizeVecs) { // out of memory -/*TEST(deserializer, eos_exception) { +TEST(deserializer, eos_exception) { std::vector theta; theta.push_back(1.0); theta.push_back(2.0); @@ -333,7 +333,7 @@ TEST(deserializer, zeroSizeVecs) { EXPECT_THROW(deserializer.read(2, 2), std::runtime_error); EXPECT_THROW((deserializer.read, Eigen::Dynamic, Eigen::Dynamic>>(2, 2)), std::runtime_error); EXPECT_THROW(deserializer.read>(2, 3, 2), std::runtime_error); - }*/ +} // lb From a216878d747544f116d14f8ba5254f0dcf8e197f Mon Sep 17 00:00:00 2001 From: Stan Jenkins Date: Mon, 8 Mar 2021 18:58:41 +0000 Subject: [PATCH 22/29] [Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.04.1 (tags/RELEASE_600/final) --- src/test/unit/io/deserializer_test.cpp | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/test/unit/io/deserializer_test.cpp b/src/test/unit/io/deserializer_test.cpp index e02b6076b40..ca09dce043b 100644 --- a/src/test/unit/io/deserializer_test.cpp +++ b/src/test/unit/io/deserializer_test.cpp @@ -325,14 +325,27 @@ TEST(deserializer, eos_exception) { EXPECT_THROW(deserializer.read>(), std::runtime_error); EXPECT_THROW(deserializer.read>(3), std::runtime_error); EXPECT_THROW(deserializer.read(2), std::runtime_error); - EXPECT_THROW((deserializer.read, Eigen::Dynamic, 1>>(2)), std::runtime_error); - EXPECT_THROW(deserializer.read>(3, 2), std::runtime_error); + EXPECT_THROW( + (deserializer + .read, Eigen::Dynamic, 1>>(2)), + std::runtime_error); + EXPECT_THROW(deserializer.read>(3, 2), + std::runtime_error); EXPECT_THROW(deserializer.read(2), std::runtime_error); - EXPECT_THROW((deserializer.read, 1, Eigen::Dynamic>>(2)), std::runtime_error); - EXPECT_THROW(deserializer.read>(3, 2), std::runtime_error); + EXPECT_THROW( + (deserializer + .read, 1, Eigen::Dynamic>>(2)), + std::runtime_error); + EXPECT_THROW(deserializer.read>(3, 2), + std::runtime_error); EXPECT_THROW(deserializer.read(2, 2), std::runtime_error); - EXPECT_THROW((deserializer.read, Eigen::Dynamic, Eigen::Dynamic>>(2, 2)), std::runtime_error); - EXPECT_THROW(deserializer.read>(2, 3, 2), std::runtime_error); + EXPECT_THROW( + (deserializer.read< + Eigen::Matrix, Eigen::Dynamic, Eigen::Dynamic>>( + 2, 2)), + std::runtime_error); + EXPECT_THROW(deserializer.read>(2, 3, 2), + std::runtime_error); } // lb From 53364a2199250b7745adbb4a4627e33bf4dc2a09 Mon Sep 17 00:00:00 2001 From: Ben Date: Mon, 8 Mar 2021 14:58:36 -0500 Subject: [PATCH 23/29] Added var tests for deserializer --- src/test/unit/io/deserializer_var_test.cpp | 829 +++++++++++++++++++++ 1 file changed, 829 insertions(+) create mode 100644 src/test/unit/io/deserializer_var_test.cpp diff --git a/src/test/unit/io/deserializer_var_test.cpp b/src/test/unit/io/deserializer_var_test.cpp new file mode 100644 index 00000000000..c4248c0c8c2 --- /dev/null +++ b/src/test/unit/io/deserializer_var_test.cpp @@ -0,0 +1,829 @@ +#include +// expect_near_rel comes from lib/stan_math +#include +#include + +TEST(deserializer_scalar, read) { + std::vector theta_i; + std::vector theta; + theta.push_back(1.0); + theta.push_back(2.0); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var x = deserializer.read(); + EXPECT_FLOAT_EQ(1.0, x.val()); + stan::math::var y = deserializer.read(); + EXPECT_FLOAT_EQ(2.0, y.val()); + EXPECT_EQ(0U, deserializer.available()); +} + +TEST(deserializer_scalar, complex_read) { + std::vector theta_i; + std::vector theta; + theta.push_back(1.0); + theta.push_back(2.0); + theta.push_back(3.0); + theta.push_back(4.0); + stan::io::deserializer deserializer(theta, theta_i); + std::complex x = deserializer.read>(); + EXPECT_FLOAT_EQ(1.0, x.real().val()); + EXPECT_FLOAT_EQ(2.0, x.imag().val()); + std::complex y = deserializer.read>(); + EXPECT_FLOAT_EQ(3.0, y.real().val()); + EXPECT_FLOAT_EQ(4.0, y.imag().val()); + EXPECT_EQ(0U, deserializer.available()); +} + +TEST(deserializer, read_int) { + Eigen::Matrix theta_i(1); + Eigen::Matrix theta(2); + theta[0] = 1.0; + theta[1] = 2.0; + theta_i[0] = 1; + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var x = deserializer.read(); + EXPECT_FLOAT_EQ(1.0, x.val()); + stan::math::var y = deserializer.read(); + EXPECT_FLOAT_EQ(2.0, y.val()); + int z = deserializer.read(); + EXPECT_EQ(1, z); + EXPECT_EQ(0U, deserializer.available()); +} + +// vector + +TEST(deserializer_vector, read) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100U; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (size_t i = 0; i < 7U; ++i) { + stan::math::var x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x.val()); + } + Eigen::Matrix y + = deserializer.read>(4); + EXPECT_EQ(4, y.rows()); + EXPECT_EQ(1, y.cols()); + EXPECT_EQ(4, y.size()); + EXPECT_FLOAT_EQ(7.0, y[0].val()); + EXPECT_FLOAT_EQ(8.0, y[1].val()); + EXPECT_FLOAT_EQ(9.0, y[2].val()); + EXPECT_FLOAT_EQ(10.0, y[3].val()); + + stan::math::var z = deserializer.read(); + EXPECT_FLOAT_EQ(11.0, z.val()); +} + +TEST(deserializer_vector, complex_read) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100U; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (size_t i = 0; i < 7U; ++i) { + stan::math::var x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x.val()); + } + using complex_vec = Eigen::Matrix, Eigen::Dynamic, 1>; + complex_vec y = deserializer.read(4); + EXPECT_EQ(4, y.rows()); + EXPECT_EQ(1, y.cols()); + EXPECT_EQ(4, y.size()); + double sentinal = 7; + for (int i = 0; i < y.size(); ++i) { + EXPECT_FLOAT_EQ(sentinal, y[i].real().val()); + ++sentinal; + EXPECT_FLOAT_EQ(sentinal, y[i].imag().val()); + ++sentinal; + } + + stan::math::var z = deserializer.read(); + EXPECT_FLOAT_EQ(15.0, z.val()); +} + +// row vector + +TEST(deserializer_row_vector, read) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100U; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (size_t i = 0; i < 7U; ++i) { + stan::math::var x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x.val()); + } + Eigen::Matrix y + = deserializer.read>(4); + EXPECT_EQ(4, y.cols()); + EXPECT_EQ(1, y.rows()); + EXPECT_EQ(4, y.size()); + EXPECT_FLOAT_EQ(7.0, y[0].val()); + EXPECT_FLOAT_EQ(8.0, y[1].val()); + EXPECT_FLOAT_EQ(9.0, y[2].val()); + EXPECT_FLOAT_EQ(10.0, y[3].val()); + + stan::math::var z = deserializer.read(); + EXPECT_FLOAT_EQ(11.0, z.val()); +} + +TEST(deserializer_row_vector, complex_read) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100U; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (size_t i = 0; i < 7U; ++i) { + stan::math::var x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x.val()); + } + using complex_row_vec + = Eigen::Matrix, 1, Eigen::Dynamic>; + complex_row_vec y = deserializer.read(4); + EXPECT_EQ(1, y.rows()); + EXPECT_EQ(4, y.cols()); + EXPECT_EQ(4, y.size()); + double sentinal = 7; + for (int i = 0; i < y.size(); ++i) { + EXPECT_FLOAT_EQ(sentinal, y[i].real().val()); + ++sentinal; + EXPECT_FLOAT_EQ(sentinal, y[i].imag().val()); + ++sentinal; + } + + stan::math::var z = deserializer.read(); + EXPECT_FLOAT_EQ(15.0, z.val()); +} + +// matrix + +TEST(deserializer_matrix, read) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (int i = 0; i < 7; ++i) { + stan::math::var x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x.val()); + } + using eig_mat = Eigen::Matrix; + eig_mat y = deserializer.read(3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + EXPECT_FLOAT_EQ(7.0, y(0, 0).val()); + EXPECT_FLOAT_EQ(8.0, y(1, 0).val()); + EXPECT_FLOAT_EQ(9.0, y(2, 0).val()); + EXPECT_FLOAT_EQ(10.0, y(0, 1).val()); + EXPECT_FLOAT_EQ(11.0, y(1, 1).val()); + EXPECT_FLOAT_EQ(12.0, y(2, 1).val()); + + stan::math::var a = deserializer.read(); + EXPECT_FLOAT_EQ(13.0, a.val()); +} + +TEST(deserializer_matrix, complex_read) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100.0; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (int i = 0; i < 7; ++i) { + stan::math::var x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x.val()); + } + using eig_mat + = Eigen::Matrix, Eigen::Dynamic, Eigen::Dynamic>; + eig_mat y = deserializer.read(3, 2); + EXPECT_EQ(3, y.rows()); + EXPECT_EQ(2, y.cols()); + double sentinal = 7; + for (int i = 0; i < y.size(); ++i) { + EXPECT_FLOAT_EQ(sentinal, y(i).real().val()); + sentinal++; + EXPECT_FLOAT_EQ(sentinal, y(i).imag().val()); + sentinal++; + } +} + +// array + +TEST(deserializer_array, read) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100U; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (size_t i = 0; i < 7U; ++i) { + stan::math::var x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x.val()); + } + std::vector y = deserializer.read>(4); + EXPECT_EQ(4, y.size()); + EXPECT_FLOAT_EQ(7.0, y[0].val()); + EXPECT_FLOAT_EQ(8.0, y[1].val()); + EXPECT_FLOAT_EQ(9.0, y[2].val()); + EXPECT_FLOAT_EQ(10.0, y[3].val()); + + stan::math::var z = deserializer.read(); + EXPECT_FLOAT_EQ(11.0, z.val()); +} + +TEST(deserializer_array, complex_read) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100U; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + for (size_t i = 0; i < 7U; ++i) { + stan::math::var x = deserializer.read(); + EXPECT_FLOAT_EQ(static_cast(i), x.val()); + } + using complex_array = std::vector>; + complex_array y = deserializer.read(4); + EXPECT_EQ(4, y.size()); + double sentinal = 7; + for (int i = 0; i < y.size(); ++i) { + EXPECT_FLOAT_EQ(sentinal, y[i].real().val()); + ++sentinal; + EXPECT_FLOAT_EQ(sentinal, y[i].imag().val()); + ++sentinal; + } + + stan::math::var z = deserializer.read(); + EXPECT_FLOAT_EQ(15.0, z.val()); +} + +TEST(deserializer_array, read_vector) { + std::vector theta_i; + std::vector theta; + for (size_t i = 0; i < 100U; ++i) + theta.push_back(static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + std::vector> y + = deserializer.read>>(4, 2); + EXPECT_EQ(4, y.size()); + EXPECT_FLOAT_EQ(0.0, y[0](0).val()); + EXPECT_FLOAT_EQ(1.0, y[0](1).val()); + EXPECT_FLOAT_EQ(2.0, y[1](0).val()); + EXPECT_FLOAT_EQ(3.0, y[1](1).val()); + EXPECT_FLOAT_EQ(4.0, y[2](0).val()); + EXPECT_FLOAT_EQ(5.0, y[2](1).val()); + EXPECT_FLOAT_EQ(6.0, y[3](0).val()); + EXPECT_FLOAT_EQ(7.0, y[3](1).val()); + + stan::math::var z = deserializer.read(); + EXPECT_FLOAT_EQ(8.0, z.val()); +} + +// lb + +TEST(deserializer_scalar, read_lb_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp = 0.0; + EXPECT_FLOAT_EQ(1.0 + exp(-2.0), + (deserializer.read_lb(1.0, lp)).val()); + EXPECT_FLOAT_EQ(5.0 + exp(3.0), + (deserializer.read_lb(5.0, lp)).val()); + EXPECT_FLOAT_EQ(-2.0 + exp(-1.0), + (deserializer.read_lb(-2.0, lp)).val()); + EXPECT_FLOAT_EQ(15.0 + exp(0.0), + (deserializer.read_lb(15.0, lp)).val()); +} + +TEST(deserializer_scalar, read_lb_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp = -1.5; + EXPECT_FLOAT_EQ(1.0 + exp(-2.0), + (deserializer.read_lb(1.0, lp)).val()); + EXPECT_FLOAT_EQ(5.0 + exp(3.0), + (deserializer.read_lb(5.0, lp)).val()); + EXPECT_FLOAT_EQ(-2.0 + exp(-1.0), + (deserializer.read_lb(-2.0, lp)).val()); + EXPECT_FLOAT_EQ(15.0 + exp(0.0), + (deserializer.read_lb(15.0, lp)).val()); + EXPECT_FLOAT_EQ(-1.5 - 2.0 + 3.0 - 1.0, lp.val()); +} + +// ub + +TEST(deserializer_scalar, read_ub_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp = 0; + EXPECT_FLOAT_EQ(1.0 - exp(-2.0), + (deserializer.read_ub(1.0, lp)).val()); + EXPECT_FLOAT_EQ(5.0 - exp(3.0), + (deserializer.read_ub(5.0, lp)).val()); + EXPECT_FLOAT_EQ(-2.0 - exp(-1.0), + (deserializer.read_ub(-2.0, lp)).val()); + EXPECT_FLOAT_EQ(15.0 - exp(0.0), + (deserializer.read_ub(15.0, lp)).val()); +} +TEST(deserializer_scalar, read_ub_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp = -12.9; + EXPECT_FLOAT_EQ(1.0 - exp(-2.0), + (deserializer.read_ub(1.0, lp)).val()); + EXPECT_FLOAT_EQ(5.0 - exp(3.0), + (deserializer.read_ub(5.0, lp)).val()); + EXPECT_FLOAT_EQ(-2.0 - exp(-1.0), + (deserializer.read_ub(-2.0, lp)).val()); + EXPECT_FLOAT_EQ(15.0 - exp(0.0), + (deserializer.read_ub(15.0, lp)).val()); + EXPECT_FLOAT_EQ(-12.9 - 2.0 + 3.0 - 1.0, lp.val()); +} + +// lub + +const double inv_logit_m2 = 0.1192029; // stan::math::inv_logit(-2.0) +const double inv_logit_m1 = 0.2689414; // stan::math::inv_logit(-1.0) +const double inv_logit_0 = 0.5; // stan::math::inv_logit(0) +const double inv_logit_3 = 0.9525741; // stan::math::inv_logit(3.0) + +TEST(deserializer_scalar, read_lub_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp = 0; + EXPECT_FLOAT_EQ(inv_logit_m2, + (deserializer.read_lub(0.0, 1.0, lp)).val()); + EXPECT_FLOAT_EQ(3.0 + 2.0 * inv_logit_3, + (deserializer.read_lub(3.0, 5.0, lp)).val()); + EXPECT_FLOAT_EQ(-3.0 + 5.0 * inv_logit_m1, + (deserializer.read_lub(-3.0, 2.0, lp)).val()); + EXPECT_FLOAT_EQ(-15.0 + 30.0 * inv_logit_0, + (deserializer.read_lub(-15.0, 15.0, lp)).val()); +} +TEST(deserializer_scalar, read_lub_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp = -7.2; + EXPECT_FLOAT_EQ(0.0 + 1.0 * inv_logit_m2, + (deserializer.read_lub(0.0, 1.0, lp)).val()); + EXPECT_FLOAT_EQ(3.0 + 2.0 * inv_logit_3, + (deserializer.read_lub(3.0, 5.0, lp)).val()); + EXPECT_FLOAT_EQ(-3.0 + 5.0 * inv_logit_m1, + (deserializer.read_lub(-3.0, 2.0, lp)).val()); + EXPECT_FLOAT_EQ(-15.0 + 30.0 * inv_logit_0, + (deserializer.read_lub(-15.0, 15.0, lp)).val()); + double expected_lp = -7.2 + + log((1.0 - 0.0) * inv_logit_m2 * (1 - inv_logit_m2)) + + log((5.0 - 3.0) * inv_logit_3 * (1 - inv_logit_3)) + + log((2.0 - -3.0) * inv_logit_m1 * (1 - inv_logit_m1)) + + log((15.0 - -15.0) * inv_logit_0 * (1 - inv_logit_0)); + EXPECT_FLOAT_EQ(expected_lp, lp.val()); +} + +// offset multiplier +TEST(deserializer_scalar, offset_multiplier_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp = 0; + EXPECT_FLOAT_EQ( + -2.0, (deserializer.read_offset_multiplier(0.0, 1.0, lp)).val()); + EXPECT_FLOAT_EQ( + 3.0 + 5.0 * 3.0, + (deserializer.read_offset_multiplier(3.0, 5.0, lp)).val()); + EXPECT_FLOAT_EQ( + -3.0 + 2.0 * -1.0, + (deserializer.read_offset_multiplier(-3.0, 2.0, lp)).val()); + EXPECT_FLOAT_EQ(-15.0, (deserializer.read_offset_multiplier( + -15.0, 15.0, lp)).val()); +} + +TEST(deserializer_scalar, offset_multiplier_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(-2.0); + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp = -7.2; + EXPECT_FLOAT_EQ( + -2.0, (deserializer.read_offset_multiplier(0.0, 1.0, lp)).val()); + EXPECT_FLOAT_EQ( + 3.0 + 5.0 * 3.0, + (deserializer.read_offset_multiplier(3.0, 5.0, lp)).val()); + EXPECT_FLOAT_EQ( + -3.0 + 2.0 * -1.0, + (deserializer.read_offset_multiplier(-3.0, 2.0, lp)).val()); + EXPECT_FLOAT_EQ(-15.0, (deserializer.read_offset_multiplier( + -15.0, 15.0, lp)).val()); + double expected_lp = -7.2 + log(1.0) + log(5.0) + log(2.0) + log(15.0); + EXPECT_FLOAT_EQ(expected_lp, lp.val()); +} + +// unit vector + +TEST(deserializer_vector, unit_vector_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp = 0; + Eigen::Matrix reference + = stan::math::unit_vector_constrain(stan::math::to_vector(theta)); + Eigen::Matrix phi( + deserializer.read_unit_vector, false>(lp, 4)); + for (size_t i = 0; i < phi.size(); ++i) { + EXPECT_FLOAT_EQ(reference(i).val(), phi[i].val()); + } +} + +TEST(deserializer_vector, unit_vector_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp = 0.0; + stan::math::var lp_ref = 0.0; + Eigen::Matrix reference + = stan::math::unit_vector_constrain(stan::math::to_vector(theta), lp_ref); + Eigen::Matrix phi( + deserializer.read_unit_vector, true>(lp, 4)); + for (size_t i = 0; i < phi.size(); ++i) { + EXPECT_FLOAT_EQ(reference(i).val(), phi[i].val()); + } + EXPECT_FLOAT_EQ(lp_ref.val(), lp.val()); +} + +// simplex + +TEST(deserializer_vector, simplex_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp = 0; + Eigen::Matrix reference + = stan::math::simplex_constrain(stan::math::to_vector(theta)); + Eigen::Matrix phi(deserializer.read_simplex, false>(lp, 4)); + for (size_t i = 0; i < phi.size(); ++i) { + EXPECT_FLOAT_EQ(reference(i).val(), phi[i].val()); + } +} + +TEST(deserializer_vector, simplex_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp = 0.0; + stan::math::var lp_ref = 0.0; + Eigen::Matrix reference + = stan::math::simplex_constrain(stan::math::to_vector(theta), lp_ref); + Eigen::Matrix phi(deserializer.read_simplex, true>(lp, 4)); + for (size_t i = 0; i < phi.size(); ++i) { + EXPECT_FLOAT_EQ(reference(i).val(), phi[i].val()); + } + EXPECT_FLOAT_EQ(lp_ref.val(), lp.val()); +} + +// ordered + +TEST(deserializer_vector, ordered_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + stan::math::var v0 = 3.0; + stan::math::var v1 = v0 + exp(-1.0); + stan::math::var v2 = v1 + exp(-2.0); + stan::math::var v3 = v2 + exp(0.0); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp = 0; + Eigen::Matrix phi( + deserializer.read_ordered, false>(lp, 4)); + EXPECT_FLOAT_EQ(v0.val(), phi[0].val()); + EXPECT_FLOAT_EQ(v1.val(), phi[1].val()); + EXPECT_FLOAT_EQ(v2.val(), phi[2].val()); + EXPECT_FLOAT_EQ(v3.val(), phi[3].val()); +} + +TEST(deserializer_vector, ordered_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + stan::math::var v0 = 3.0; + stan::math::var v1 = v0 + exp(-1.0); + stan::math::var v2 = v1 + exp(-2.0); + stan::math::var v3 = v2 + exp(0.0); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp = -101.1; + double expected_lp = lp.val() - 1.0 - 2.0 + 0.0; + Eigen::Matrix phi( + deserializer.read_ordered, true>(lp, 4)); + EXPECT_FLOAT_EQ(v0.val(), phi[0].val()); + EXPECT_FLOAT_EQ(v1.val(), phi[1].val()); + EXPECT_FLOAT_EQ(v2.val(), phi[2].val()); + EXPECT_FLOAT_EQ(v3.val(), phi[3].val()); + EXPECT_FLOAT_EQ(expected_lp, lp.val()); +} + +// positive ordered + +TEST(deserializer_vector, positive_ordered_constrain) { + std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + stan::math::var v0 = exp(3.0); + stan::math::var v1 = v0 + exp(-1.0); + stan::math::var v2 = v1 + exp(-2.0); + stan::math::var v3 = v2 + exp(0.0); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp = 0; + Eigen::Matrix phi( + deserializer.read_positive_ordered, false>(lp, 4)); + EXPECT_FLOAT_EQ(v0.val(), phi[0].val()); + EXPECT_FLOAT_EQ(v1.val(), phi[1].val()); + EXPECT_FLOAT_EQ(v2.val(), phi[2].val()); + EXPECT_FLOAT_EQ(v3.val(), phi[3].val()); +} + +TEST(deserializer_vector, positive_ordered_constrain_jacobian) { + std::vector theta_i; + std::vector theta; + theta.push_back(3.0); + theta.push_back(-1.0); + theta.push_back(-2.0); + theta.push_back(0.0); + stan::math::var v0 = exp(3.0); + stan::math::var v1 = v0 + exp(-1.0); + stan::math::var v2 = v1 + exp(-2.0); + stan::math::var v3 = v2 + exp(0.0); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp = -101.1; + double expected_lp = lp.val() + 3.0 - 1.0 - 2.0 + 0.0; + Eigen::Matrix phi( + deserializer.read_positive_ordered, true>(lp, 4)); + EXPECT_FLOAT_EQ(v0.val(), phi[0].val()); + EXPECT_FLOAT_EQ(v1.val(), phi[1].val()); + EXPECT_FLOAT_EQ(v2.val(), phi[2].val()); + EXPECT_FLOAT_EQ(v3.val(), phi[3].val()); + EXPECT_FLOAT_EQ(expected_lp, lp.val()); +} + +// chol cov + +TEST(deserializer_matrix, cholesky_factor_cov_constrain) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 8; ++i) + theta.push_back(-static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp = 0; + Eigen::Matrix reference = stan::math::cholesky_factor_constrain( + stan::math::to_vector(theta).segment(0, 6), 3, 3); + Eigen::Matrix L( + deserializer.read_cholesky_factor_cov, false>(lp, 3U, + 3U)); + EXPECT_EQ(3, L.rows()); + EXPECT_EQ(3, L.cols()); + EXPECT_EQ(9, L.size()); + stan::test::expect_near_rel("deserializer tests", reference.val(), L.val()); + EXPECT_EQ(2U, deserializer.available()); +} + +TEST(deserializer_matrix, cholesky_factor_cov_jacobian) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 8; ++i) + theta.push_back(-static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp_ref = 0.0; + stan::math::var lp = 0.0; + Eigen::Matrix reference = stan::math::cholesky_factor_constrain( + stan::math::to_vector(theta).segment(0, 6), 3, 3, lp_ref); + Eigen::Matrix L( + deserializer.read_cholesky_factor_cov, true>(lp, 3U, 3U)); + EXPECT_EQ(3, L.rows()); + EXPECT_EQ(3, L.cols()); + EXPECT_EQ(9, L.size()); + stan::test::expect_near_rel("deserializer tests", reference.val(), L.val()); + EXPECT_EQ(2U, deserializer.available()); + EXPECT_FLOAT_EQ(lp_ref.val(), lp.val()); +} + +TEST(deserializer_matrix, cholesky_factor_cov_constrain_non_square) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 8; ++i) + theta.push_back(-static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp = 0; + Eigen::Matrix reference = stan::math::cholesky_factor_constrain( + stan::math::to_vector(theta).segment(0, 5), 3, 2); + Eigen::Matrix L( + deserializer.read_cholesky_factor_cov, false>(lp, 3U, + 2U)); + EXPECT_EQ(3, L.rows()); + EXPECT_EQ(2, L.cols()); + EXPECT_EQ(6, L.size()); + stan::test::expect_near_rel("deserializer tests", reference.val(), L.val()); + EXPECT_EQ(3U, deserializer.available()); +} + +TEST(deserializer_matrix, cholesky_factor_cov_jacobian_non_square) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 8; ++i) + theta.push_back(-static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp_ref = 0.0; + stan::math::var lp = 0.0; + Eigen::Matrix reference = stan::math::cholesky_factor_constrain( + stan::math::to_vector(theta).segment(0, 5), 3, 2, lp_ref); + Eigen::Matrix L( + deserializer.read_cholesky_factor_cov, true>(lp, 3U, 2U)); + EXPECT_EQ(3, L.rows()); + EXPECT_EQ(2, L.cols()); + EXPECT_EQ(6, L.size()); + stan::test::expect_near_rel("deserializer tests", reference.val(), L.val()); + EXPECT_EQ(3U, deserializer.available()); + EXPECT_FLOAT_EQ(lp_ref.val(), lp.val()); +} + +// chol corr + +TEST(deserializer_matrix, cholesky_factor_corr_constrain) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 8; ++i) + theta.push_back(-static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp = 0; + Eigen::Matrix reference = stan::math::cholesky_corr_constrain( + stan::math::to_vector(theta).segment(0, 3), 3); + Eigen::Matrix L( + deserializer.read_cholesky_factor_corr, false>(lp, 3U)); + EXPECT_NO_THROW(stan::math::check_cholesky_factor_corr( + "test_cholesky_factor_corr_constrain", "L", L)); + EXPECT_EQ(3, L.rows()); + EXPECT_EQ(3, L.cols()); + EXPECT_EQ(9, L.size()); + stan::test::expect_near_rel("deserializer tests", reference.val(), L.val()); + EXPECT_EQ(5U, deserializer.available()); +} + +TEST(deserializer_matrix, cholesky_factor_corr_jacobian) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 8; ++i) + theta.push_back(-static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp_ref = 0.0; + stan::math::var lp = 0.0; + Eigen::Matrix reference = stan::math::cholesky_corr_constrain( + stan::math::to_vector(theta).segment(0, 3), 3, lp_ref); + Eigen::Matrix L( + deserializer.read_cholesky_factor_corr, true>(lp, 3U)); + EXPECT_NO_THROW(stan::math::check_cholesky_factor_corr( + "test_cholesky_factor_corr_constrain", "L", L)); + EXPECT_EQ(3, L.rows()); + EXPECT_EQ(3, L.cols()); + EXPECT_EQ(9, L.size()); + stan::test::expect_near_rel("deserializer tests", reference.val(), L.val()); + EXPECT_EQ(5U, deserializer.available()); + EXPECT_FLOAT_EQ(lp_ref.val(), lp.val()); +} + +// cov + +TEST(deserializer_matrix, cov_matrix_constrain) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 8; ++i) + theta.push_back(-static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp = 0; + Eigen::Matrix reference = stan::math::cov_matrix_constrain( + stan::math::to_vector(theta).segment(0, 6), 3); + Eigen::Matrix L( + deserializer.read_cov_matrix, false>(lp, 3U)); + EXPECT_EQ(3, L.rows()); + EXPECT_EQ(3, L.cols()); + EXPECT_EQ(9, L.size()); + stan::test::expect_near_rel("deserializer tests", reference.val(), L.val()); + EXPECT_EQ(2U, deserializer.available()); +} + +TEST(deserializer_matrix, cov_matrix_jacobian) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 8; ++i) + theta.push_back(-static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp_ref = 0.0; + stan::math::var lp = 0.0; + Eigen::Matrix reference = stan::math::cov_matrix_constrain( + stan::math::to_vector(theta).segment(0, 6), 3, lp_ref); + Eigen::Matrix L( + deserializer.read_cov_matrix, true>(lp, 3U)); + EXPECT_EQ(3, L.rows()); + EXPECT_EQ(3, L.cols()); + EXPECT_EQ(9, L.size()); + stan::test::expect_near_rel("deserializer tests", reference.val(), L.val()); + EXPECT_EQ(2U, deserializer.available()); + EXPECT_FLOAT_EQ(lp_ref.val(), lp.val()); +} + +// corr + +TEST(deserializer_matrix, corr_matrix_constrain) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 8; ++i) + theta.push_back(-static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp = 0; + Eigen::Matrix reference = stan::math::corr_matrix_constrain( + stan::math::to_vector(theta).segment(0, 3), 3); + Eigen::Matrix L( + deserializer.read_corr_matrix, false>(lp, 3U)); + EXPECT_EQ(3, L.rows()); + EXPECT_EQ(3, L.cols()); + EXPECT_EQ(9, L.size()); + stan::test::expect_near_rel("deserializer tests", reference.val(), L.val()); + EXPECT_EQ(5U, deserializer.available()); +} + +TEST(deserializer_matrix, corr_matrix_jacobian) { + std::vector theta_i; + std::vector theta; + for (int i = 0; i < 8; ++i) + theta.push_back(-static_cast(i)); + stan::io::deserializer deserializer(theta, theta_i); + stan::math::var lp_ref = 0.0; + stan::math::var lp = 0.0; + Eigen::Matrix reference = stan::math::corr_matrix_constrain( + stan::math::to_vector(theta).segment(0, 3), 3, lp_ref); + Eigen::Matrix L( + deserializer.read_corr_matrix, true>(lp, 3U)); + EXPECT_EQ(3, L.rows()); + EXPECT_EQ(3, L.cols()); + EXPECT_EQ(9, L.size()); + stan::test::expect_near_rel("deserializer tests", reference.val(), L.val()); + EXPECT_EQ(5U, deserializer.available()); + EXPECT_FLOAT_EQ(lp_ref.val(), lp.val()); +} + From d427420ddbbfa180d73b030ce9f4292e0cb706f5 Mon Sep 17 00:00:00 2001 From: Stan Jenkins Date: Mon, 8 Mar 2021 20:07:36 +0000 Subject: [PATCH 24/29] [Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.04.1 (tags/RELEASE_600/final) --- src/test/unit/io/deserializer_var_test.cpp | 287 +++++++++++++-------- 1 file changed, 181 insertions(+), 106 deletions(-) diff --git a/src/test/unit/io/deserializer_var_test.cpp b/src/test/unit/io/deserializer_var_test.cpp index c4248c0c8c2..36862965887 100644 --- a/src/test/unit/io/deserializer_var_test.cpp +++ b/src/test/unit/io/deserializer_var_test.cpp @@ -24,10 +24,12 @@ TEST(deserializer_scalar, complex_read) { theta.push_back(3.0); theta.push_back(4.0); stan::io::deserializer deserializer(theta, theta_i); - std::complex x = deserializer.read>(); + std::complex x + = deserializer.read>(); EXPECT_FLOAT_EQ(1.0, x.real().val()); EXPECT_FLOAT_EQ(2.0, x.imag().val()); - std::complex y = deserializer.read>(); + std::complex y + = deserializer.read>(); EXPECT_FLOAT_EQ(3.0, y.real().val()); EXPECT_FLOAT_EQ(4.0, y.imag().val()); EXPECT_EQ(0U, deserializer.available()); @@ -85,7 +87,8 @@ TEST(deserializer_vector, complex_read) { stan::math::var x = deserializer.read(); EXPECT_FLOAT_EQ(static_cast(i), x.val()); } - using complex_vec = Eigen::Matrix, Eigen::Dynamic, 1>; + using complex_vec + = Eigen::Matrix, Eigen::Dynamic, 1>; complex_vec y = deserializer.read(4); EXPECT_EQ(4, y.rows()); EXPECT_EQ(1, y.cols()); @@ -168,7 +171,8 @@ TEST(deserializer_matrix, read) { stan::math::var x = deserializer.read(); EXPECT_FLOAT_EQ(static_cast(i), x.val()); } - using eig_mat = Eigen::Matrix; + using eig_mat + = Eigen::Matrix; eig_mat y = deserializer.read(3, 2); EXPECT_EQ(3, y.rows()); EXPECT_EQ(2, y.cols()); @@ -193,8 +197,8 @@ TEST(deserializer_matrix, complex_read) { stan::math::var x = deserializer.read(); EXPECT_FLOAT_EQ(static_cast(i), x.val()); } - using eig_mat - = Eigen::Matrix, Eigen::Dynamic, Eigen::Dynamic>; + using eig_mat = Eigen::Matrix, Eigen::Dynamic, + Eigen::Dynamic>; eig_mat y = deserializer.read(3, 2); EXPECT_EQ(3, y.rows()); EXPECT_EQ(2, y.cols()); @@ -219,7 +223,8 @@ TEST(deserializer_array, read) { stan::math::var x = deserializer.read(); EXPECT_FLOAT_EQ(static_cast(i), x.val()); } - std::vector y = deserializer.read>(4); + std::vector y + = deserializer.read>(4); EXPECT_EQ(4, y.size()); EXPECT_FLOAT_EQ(7.0, y[0].val()); EXPECT_FLOAT_EQ(8.0, y[1].val()); @@ -262,7 +267,8 @@ TEST(deserializer_array, read_vector) { theta.push_back(static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); std::vector> y - = deserializer.read>>(4, 2); + = deserializer.read< + std::vector>>(4, 2); EXPECT_EQ(4, y.size()); EXPECT_FLOAT_EQ(0.0, y[0](0).val()); EXPECT_FLOAT_EQ(1.0, y[0](1).val()); @@ -288,14 +294,18 @@ TEST(deserializer_scalar, read_lb_constrain) { theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp = 0.0; - EXPECT_FLOAT_EQ(1.0 + exp(-2.0), - (deserializer.read_lb(1.0, lp)).val()); - EXPECT_FLOAT_EQ(5.0 + exp(3.0), - (deserializer.read_lb(5.0, lp)).val()); - EXPECT_FLOAT_EQ(-2.0 + exp(-1.0), - (deserializer.read_lb(-2.0, lp)).val()); - EXPECT_FLOAT_EQ(15.0 + exp(0.0), - (deserializer.read_lb(15.0, lp)).val()); + EXPECT_FLOAT_EQ( + 1.0 + exp(-2.0), + (deserializer.read_lb(1.0, lp)).val()); + EXPECT_FLOAT_EQ( + 5.0 + exp(3.0), + (deserializer.read_lb(5.0, lp)).val()); + EXPECT_FLOAT_EQ( + -2.0 + exp(-1.0), + (deserializer.read_lb(-2.0, lp)).val()); + EXPECT_FLOAT_EQ( + 15.0 + exp(0.0), + (deserializer.read_lb(15.0, lp)).val()); } TEST(deserializer_scalar, read_lb_constrain_jacobian) { @@ -311,10 +321,12 @@ TEST(deserializer_scalar, read_lb_constrain_jacobian) { (deserializer.read_lb(1.0, lp)).val()); EXPECT_FLOAT_EQ(5.0 + exp(3.0), (deserializer.read_lb(5.0, lp)).val()); - EXPECT_FLOAT_EQ(-2.0 + exp(-1.0), - (deserializer.read_lb(-2.0, lp)).val()); - EXPECT_FLOAT_EQ(15.0 + exp(0.0), - (deserializer.read_lb(15.0, lp)).val()); + EXPECT_FLOAT_EQ( + -2.0 + exp(-1.0), + (deserializer.read_lb(-2.0, lp)).val()); + EXPECT_FLOAT_EQ( + 15.0 + exp(0.0), + (deserializer.read_lb(15.0, lp)).val()); EXPECT_FLOAT_EQ(-1.5 - 2.0 + 3.0 - 1.0, lp.val()); } @@ -329,14 +341,18 @@ TEST(deserializer_scalar, read_ub_constrain) { theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp = 0; - EXPECT_FLOAT_EQ(1.0 - exp(-2.0), - (deserializer.read_ub(1.0, lp)).val()); - EXPECT_FLOAT_EQ(5.0 - exp(3.0), - (deserializer.read_ub(5.0, lp)).val()); - EXPECT_FLOAT_EQ(-2.0 - exp(-1.0), - (deserializer.read_ub(-2.0, lp)).val()); - EXPECT_FLOAT_EQ(15.0 - exp(0.0), - (deserializer.read_ub(15.0, lp)).val()); + EXPECT_FLOAT_EQ( + 1.0 - exp(-2.0), + (deserializer.read_ub(1.0, lp)).val()); + EXPECT_FLOAT_EQ( + 5.0 - exp(3.0), + (deserializer.read_ub(5.0, lp)).val()); + EXPECT_FLOAT_EQ( + -2.0 - exp(-1.0), + (deserializer.read_ub(-2.0, lp)).val()); + EXPECT_FLOAT_EQ( + 15.0 - exp(0.0), + (deserializer.read_ub(15.0, lp)).val()); } TEST(deserializer_scalar, read_ub_constrain_jacobian) { std::vector theta_i; @@ -351,10 +367,12 @@ TEST(deserializer_scalar, read_ub_constrain_jacobian) { (deserializer.read_ub(1.0, lp)).val()); EXPECT_FLOAT_EQ(5.0 - exp(3.0), (deserializer.read_ub(5.0, lp)).val()); - EXPECT_FLOAT_EQ(-2.0 - exp(-1.0), - (deserializer.read_ub(-2.0, lp)).val()); - EXPECT_FLOAT_EQ(15.0 - exp(0.0), - (deserializer.read_ub(15.0, lp)).val()); + EXPECT_FLOAT_EQ( + -2.0 - exp(-1.0), + (deserializer.read_ub(-2.0, lp)).val()); + EXPECT_FLOAT_EQ( + 15.0 - exp(0.0), + (deserializer.read_ub(15.0, lp)).val()); EXPECT_FLOAT_EQ(-12.9 - 2.0 + 3.0 - 1.0, lp.val()); } @@ -374,14 +392,18 @@ TEST(deserializer_scalar, read_lub_constrain) { theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp = 0; - EXPECT_FLOAT_EQ(inv_logit_m2, - (deserializer.read_lub(0.0, 1.0, lp)).val()); - EXPECT_FLOAT_EQ(3.0 + 2.0 * inv_logit_3, - (deserializer.read_lub(3.0, 5.0, lp)).val()); - EXPECT_FLOAT_EQ(-3.0 + 5.0 * inv_logit_m1, - (deserializer.read_lub(-3.0, 2.0, lp)).val()); - EXPECT_FLOAT_EQ(-15.0 + 30.0 * inv_logit_0, - (deserializer.read_lub(-15.0, 15.0, lp)).val()); + EXPECT_FLOAT_EQ( + inv_logit_m2, + (deserializer.read_lub(0.0, 1.0, lp)).val()); + EXPECT_FLOAT_EQ( + 3.0 + 2.0 * inv_logit_3, + (deserializer.read_lub(3.0, 5.0, lp)).val()); + EXPECT_FLOAT_EQ( + -3.0 + 5.0 * inv_logit_m1, + (deserializer.read_lub(-3.0, 2.0, lp)).val()); + EXPECT_FLOAT_EQ( + -15.0 + 30.0 * inv_logit_0, + (deserializer.read_lub(-15.0, 15.0, lp)).val()); } TEST(deserializer_scalar, read_lub_constrain_jacobian) { std::vector theta_i; @@ -392,14 +414,18 @@ TEST(deserializer_scalar, read_lub_constrain_jacobian) { theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp = -7.2; - EXPECT_FLOAT_EQ(0.0 + 1.0 * inv_logit_m2, - (deserializer.read_lub(0.0, 1.0, lp)).val()); - EXPECT_FLOAT_EQ(3.0 + 2.0 * inv_logit_3, - (deserializer.read_lub(3.0, 5.0, lp)).val()); - EXPECT_FLOAT_EQ(-3.0 + 5.0 * inv_logit_m1, - (deserializer.read_lub(-3.0, 2.0, lp)).val()); - EXPECT_FLOAT_EQ(-15.0 + 30.0 * inv_logit_0, - (deserializer.read_lub(-15.0, 15.0, lp)).val()); + EXPECT_FLOAT_EQ( + 0.0 + 1.0 * inv_logit_m2, + (deserializer.read_lub(0.0, 1.0, lp)).val()); + EXPECT_FLOAT_EQ( + 3.0 + 2.0 * inv_logit_3, + (deserializer.read_lub(3.0, 5.0, lp)).val()); + EXPECT_FLOAT_EQ( + -3.0 + 5.0 * inv_logit_m1, + (deserializer.read_lub(-3.0, 2.0, lp)).val()); + EXPECT_FLOAT_EQ( + -15.0 + 30.0 * inv_logit_0, + (deserializer.read_lub(-15.0, 15.0, lp)).val()); double expected_lp = -7.2 + log((1.0 - 0.0) * inv_logit_m2 * (1 - inv_logit_m2)) + log((5.0 - 3.0) * inv_logit_3 * (1 - inv_logit_3)) @@ -418,16 +444,22 @@ TEST(deserializer_scalar, offset_multiplier_constrain) { theta.push_back(0.0); stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp = 0; - EXPECT_FLOAT_EQ( - -2.0, (deserializer.read_offset_multiplier(0.0, 1.0, lp)).val()); - EXPECT_FLOAT_EQ( - 3.0 + 5.0 * 3.0, - (deserializer.read_offset_multiplier(3.0, 5.0, lp)).val()); - EXPECT_FLOAT_EQ( - -3.0 + 2.0 * -1.0, - (deserializer.read_offset_multiplier(-3.0, 2.0, lp)).val()); - EXPECT_FLOAT_EQ(-15.0, (deserializer.read_offset_multiplier( - -15.0, 15.0, lp)).val()); + EXPECT_FLOAT_EQ(-2.0, + (deserializer.read_offset_multiplier( + 0.0, 1.0, lp)) + .val()); + EXPECT_FLOAT_EQ(3.0 + 5.0 * 3.0, + (deserializer.read_offset_multiplier( + 3.0, 5.0, lp)) + .val()); + EXPECT_FLOAT_EQ(-3.0 + 2.0 * -1.0, + (deserializer.read_offset_multiplier( + -3.0, 2.0, lp)) + .val()); + EXPECT_FLOAT_EQ(-15.0, + (deserializer.read_offset_multiplier( + -15.0, 15.0, lp)) + .val()); } TEST(deserializer_scalar, offset_multiplier_constrain_jacobian) { @@ -440,15 +472,21 @@ TEST(deserializer_scalar, offset_multiplier_constrain_jacobian) { stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp = -7.2; EXPECT_FLOAT_EQ( - -2.0, (deserializer.read_offset_multiplier(0.0, 1.0, lp)).val()); + -2.0, + (deserializer.read_offset_multiplier(0.0, 1.0, lp)) + .val()); EXPECT_FLOAT_EQ( 3.0 + 5.0 * 3.0, - (deserializer.read_offset_multiplier(3.0, 5.0, lp)).val()); - EXPECT_FLOAT_EQ( - -3.0 + 2.0 * -1.0, - (deserializer.read_offset_multiplier(-3.0, 2.0, lp)).val()); - EXPECT_FLOAT_EQ(-15.0, (deserializer.read_offset_multiplier( - -15.0, 15.0, lp)).val()); + (deserializer.read_offset_multiplier(3.0, 5.0, lp)) + .val()); + EXPECT_FLOAT_EQ(-3.0 + 2.0 * -1.0, + (deserializer.read_offset_multiplier( + -3.0, 2.0, lp)) + .val()); + EXPECT_FLOAT_EQ(-15.0, + (deserializer.read_offset_multiplier( + -15.0, 15.0, lp)) + .val()); double expected_lp = -7.2 + log(1.0) + log(5.0) + log(2.0) + log(15.0); EXPECT_FLOAT_EQ(expected_lp, lp.val()); } @@ -467,7 +505,8 @@ TEST(deserializer_vector, unit_vector_constrain) { Eigen::Matrix reference = stan::math::unit_vector_constrain(stan::math::to_vector(theta)); Eigen::Matrix phi( - deserializer.read_unit_vector, false>(lp, 4)); + deserializer.read_unit_vector< + Eigen::Matrix, false>(lp, 4)); for (size_t i = 0; i < phi.size(); ++i) { EXPECT_FLOAT_EQ(reference(i).val(), phi[i].val()); } @@ -486,7 +525,8 @@ TEST(deserializer_vector, unit_vector_jacobian) { Eigen::Matrix reference = stan::math::unit_vector_constrain(stan::math::to_vector(theta), lp_ref); Eigen::Matrix phi( - deserializer.read_unit_vector, true>(lp, 4)); + deserializer.read_unit_vector< + Eigen::Matrix, true>(lp, 4)); for (size_t i = 0; i < phi.size(); ++i) { EXPECT_FLOAT_EQ(reference(i).val(), phi[i].val()); } @@ -506,7 +546,9 @@ TEST(deserializer_vector, simplex_constrain) { stan::math::var lp = 0; Eigen::Matrix reference = stan::math::simplex_constrain(stan::math::to_vector(theta)); - Eigen::Matrix phi(deserializer.read_simplex, false>(lp, 4)); + Eigen::Matrix phi( + deserializer.read_simplex< + Eigen::Matrix, false>(lp, 4)); for (size_t i = 0; i < phi.size(); ++i) { EXPECT_FLOAT_EQ(reference(i).val(), phi[i].val()); } @@ -524,7 +566,9 @@ TEST(deserializer_vector, simplex_jacobian) { stan::math::var lp_ref = 0.0; Eigen::Matrix reference = stan::math::simplex_constrain(stan::math::to_vector(theta), lp_ref); - Eigen::Matrix phi(deserializer.read_simplex, true>(lp, 4)); + Eigen::Matrix phi( + deserializer.read_simplex< + Eigen::Matrix, true>(lp, 4)); for (size_t i = 0; i < phi.size(); ++i) { EXPECT_FLOAT_EQ(reference(i).val(), phi[i].val()); } @@ -547,7 +591,8 @@ TEST(deserializer_vector, ordered_constrain) { stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp = 0; Eigen::Matrix phi( - deserializer.read_ordered, false>(lp, 4)); + deserializer.read_ordered< + Eigen::Matrix, false>(lp, 4)); EXPECT_FLOAT_EQ(v0.val(), phi[0].val()); EXPECT_FLOAT_EQ(v1.val(), phi[1].val()); EXPECT_FLOAT_EQ(v2.val(), phi[2].val()); @@ -569,7 +614,8 @@ TEST(deserializer_vector, ordered_constrain_jacobian) { stan::math::var lp = -101.1; double expected_lp = lp.val() - 1.0 - 2.0 + 0.0; Eigen::Matrix phi( - deserializer.read_ordered, true>(lp, 4)); + deserializer.read_ordered< + Eigen::Matrix, true>(lp, 4)); EXPECT_FLOAT_EQ(v0.val(), phi[0].val()); EXPECT_FLOAT_EQ(v1.val(), phi[1].val()); EXPECT_FLOAT_EQ(v2.val(), phi[2].val()); @@ -593,7 +639,8 @@ TEST(deserializer_vector, positive_ordered_constrain) { stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp = 0; Eigen::Matrix phi( - deserializer.read_positive_ordered, false>(lp, 4)); + deserializer.read_positive_ordered< + Eigen::Matrix, false>(lp, 4)); EXPECT_FLOAT_EQ(v0.val(), phi[0].val()); EXPECT_FLOAT_EQ(v1.val(), phi[1].val()); EXPECT_FLOAT_EQ(v2.val(), phi[2].val()); @@ -615,7 +662,8 @@ TEST(deserializer_vector, positive_ordered_constrain_jacobian) { stan::math::var lp = -101.1; double expected_lp = lp.val() + 3.0 - 1.0 - 2.0 + 0.0; Eigen::Matrix phi( - deserializer.read_positive_ordered, true>(lp, 4)); + deserializer.read_positive_ordered< + Eigen::Matrix, true>(lp, 4)); EXPECT_FLOAT_EQ(v0.val(), phi[0].val()); EXPECT_FLOAT_EQ(v1.val(), phi[1].val()); EXPECT_FLOAT_EQ(v2.val(), phi[2].val()); @@ -632,11 +680,13 @@ TEST(deserializer_matrix, cholesky_factor_cov_constrain) { theta.push_back(-static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp = 0; - Eigen::Matrix reference = stan::math::cholesky_factor_constrain( - stan::math::to_vector(theta).segment(0, 6), 3, 3); + Eigen::Matrix reference + = stan::math::cholesky_factor_constrain( + stan::math::to_vector(theta).segment(0, 6), 3, 3); Eigen::Matrix L( - deserializer.read_cholesky_factor_cov, false>(lp, 3U, - 3U)); + deserializer.read_cholesky_factor_cov< + Eigen::Matrix, + false>(lp, 3U, 3U)); EXPECT_EQ(3, L.rows()); EXPECT_EQ(3, L.cols()); EXPECT_EQ(9, L.size()); @@ -652,10 +702,13 @@ TEST(deserializer_matrix, cholesky_factor_cov_jacobian) { stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp_ref = 0.0; stan::math::var lp = 0.0; - Eigen::Matrix reference = stan::math::cholesky_factor_constrain( - stan::math::to_vector(theta).segment(0, 6), 3, 3, lp_ref); + Eigen::Matrix reference + = stan::math::cholesky_factor_constrain( + stan::math::to_vector(theta).segment(0, 6), 3, 3, lp_ref); Eigen::Matrix L( - deserializer.read_cholesky_factor_cov, true>(lp, 3U, 3U)); + deserializer.read_cholesky_factor_cov< + Eigen::Matrix, true>( + lp, 3U, 3U)); EXPECT_EQ(3, L.rows()); EXPECT_EQ(3, L.cols()); EXPECT_EQ(9, L.size()); @@ -671,11 +724,13 @@ TEST(deserializer_matrix, cholesky_factor_cov_constrain_non_square) { theta.push_back(-static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp = 0; - Eigen::Matrix reference = stan::math::cholesky_factor_constrain( - stan::math::to_vector(theta).segment(0, 5), 3, 2); + Eigen::Matrix reference + = stan::math::cholesky_factor_constrain( + stan::math::to_vector(theta).segment(0, 5), 3, 2); Eigen::Matrix L( - deserializer.read_cholesky_factor_cov, false>(lp, 3U, - 2U)); + deserializer.read_cholesky_factor_cov< + Eigen::Matrix, + false>(lp, 3U, 2U)); EXPECT_EQ(3, L.rows()); EXPECT_EQ(2, L.cols()); EXPECT_EQ(6, L.size()); @@ -691,10 +746,13 @@ TEST(deserializer_matrix, cholesky_factor_cov_jacobian_non_square) { stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp_ref = 0.0; stan::math::var lp = 0.0; - Eigen::Matrix reference = stan::math::cholesky_factor_constrain( - stan::math::to_vector(theta).segment(0, 5), 3, 2, lp_ref); + Eigen::Matrix reference + = stan::math::cholesky_factor_constrain( + stan::math::to_vector(theta).segment(0, 5), 3, 2, lp_ref); Eigen::Matrix L( - deserializer.read_cholesky_factor_cov, true>(lp, 3U, 2U)); + deserializer.read_cholesky_factor_cov< + Eigen::Matrix, true>( + lp, 3U, 2U)); EXPECT_EQ(3, L.rows()); EXPECT_EQ(2, L.cols()); EXPECT_EQ(6, L.size()); @@ -712,10 +770,13 @@ TEST(deserializer_matrix, cholesky_factor_corr_constrain) { theta.push_back(-static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp = 0; - Eigen::Matrix reference = stan::math::cholesky_corr_constrain( - stan::math::to_vector(theta).segment(0, 3), 3); + Eigen::Matrix reference + = stan::math::cholesky_corr_constrain( + stan::math::to_vector(theta).segment(0, 3), 3); Eigen::Matrix L( - deserializer.read_cholesky_factor_corr, false>(lp, 3U)); + deserializer.read_cholesky_factor_corr< + Eigen::Matrix, + false>(lp, 3U)); EXPECT_NO_THROW(stan::math::check_cholesky_factor_corr( "test_cholesky_factor_corr_constrain", "L", L)); EXPECT_EQ(3, L.rows()); @@ -733,10 +794,13 @@ TEST(deserializer_matrix, cholesky_factor_corr_jacobian) { stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp_ref = 0.0; stan::math::var lp = 0.0; - Eigen::Matrix reference = stan::math::cholesky_corr_constrain( - stan::math::to_vector(theta).segment(0, 3), 3, lp_ref); + Eigen::Matrix reference + = stan::math::cholesky_corr_constrain( + stan::math::to_vector(theta).segment(0, 3), 3, lp_ref); Eigen::Matrix L( - deserializer.read_cholesky_factor_corr, true>(lp, 3U)); + deserializer.read_cholesky_factor_corr< + Eigen::Matrix, true>( + lp, 3U)); EXPECT_NO_THROW(stan::math::check_cholesky_factor_corr( "test_cholesky_factor_corr_constrain", "L", L)); EXPECT_EQ(3, L.rows()); @@ -756,10 +820,13 @@ TEST(deserializer_matrix, cov_matrix_constrain) { theta.push_back(-static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp = 0; - Eigen::Matrix reference = stan::math::cov_matrix_constrain( - stan::math::to_vector(theta).segment(0, 6), 3); + Eigen::Matrix reference + = stan::math::cov_matrix_constrain( + stan::math::to_vector(theta).segment(0, 6), 3); Eigen::Matrix L( - deserializer.read_cov_matrix, false>(lp, 3U)); + deserializer.read_cov_matrix< + Eigen::Matrix, + false>(lp, 3U)); EXPECT_EQ(3, L.rows()); EXPECT_EQ(3, L.cols()); EXPECT_EQ(9, L.size()); @@ -775,10 +842,13 @@ TEST(deserializer_matrix, cov_matrix_jacobian) { stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp_ref = 0.0; stan::math::var lp = 0.0; - Eigen::Matrix reference = stan::math::cov_matrix_constrain( - stan::math::to_vector(theta).segment(0, 6), 3, lp_ref); + Eigen::Matrix reference + = stan::math::cov_matrix_constrain( + stan::math::to_vector(theta).segment(0, 6), 3, lp_ref); Eigen::Matrix L( - deserializer.read_cov_matrix, true>(lp, 3U)); + deserializer.read_cov_matrix< + Eigen::Matrix, true>( + lp, 3U)); EXPECT_EQ(3, L.rows()); EXPECT_EQ(3, L.cols()); EXPECT_EQ(9, L.size()); @@ -796,10 +866,13 @@ TEST(deserializer_matrix, corr_matrix_constrain) { theta.push_back(-static_cast(i)); stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp = 0; - Eigen::Matrix reference = stan::math::corr_matrix_constrain( - stan::math::to_vector(theta).segment(0, 3), 3); + Eigen::Matrix reference + = stan::math::corr_matrix_constrain( + stan::math::to_vector(theta).segment(0, 3), 3); Eigen::Matrix L( - deserializer.read_corr_matrix, false>(lp, 3U)); + deserializer.read_corr_matrix< + Eigen::Matrix, + false>(lp, 3U)); EXPECT_EQ(3, L.rows()); EXPECT_EQ(3, L.cols()); EXPECT_EQ(9, L.size()); @@ -815,10 +888,13 @@ TEST(deserializer_matrix, corr_matrix_jacobian) { stan::io::deserializer deserializer(theta, theta_i); stan::math::var lp_ref = 0.0; stan::math::var lp = 0.0; - Eigen::Matrix reference = stan::math::corr_matrix_constrain( - stan::math::to_vector(theta).segment(0, 3), 3, lp_ref); + Eigen::Matrix reference + = stan::math::corr_matrix_constrain( + stan::math::to_vector(theta).segment(0, 3), 3, lp_ref); Eigen::Matrix L( - deserializer.read_corr_matrix, true>(lp, 3U)); + deserializer.read_corr_matrix< + Eigen::Matrix, true>( + lp, 3U)); EXPECT_EQ(3, L.rows()); EXPECT_EQ(3, L.cols()); EXPECT_EQ(9, L.size()); @@ -826,4 +902,3 @@ TEST(deserializer_matrix, corr_matrix_jacobian) { EXPECT_EQ(5U, deserializer.available()); EXPECT_FLOAT_EQ(lp_ref.val(), lp.val()); } - From 49401010f323ceeb4e5bab6252315b1501ca1ec2 Mon Sep 17 00:00:00 2001 From: Ben Date: Tue, 9 Mar 2021 07:25:34 -0500 Subject: [PATCH 25/29] Updated deserializer to check for memory left --- src/stan/io/deserializer.hpp | 33 ++++++--- src/test/unit/io/deserializer_test.cpp | 98 ++++++++++++++++++++------ 2 files changed, 101 insertions(+), 30 deletions(-) diff --git a/src/stan/io/deserializer.hpp b/src/stan/io/deserializer.hpp index 0f3c3615153..6df0235157b 100644 --- a/src/stan/io/deserializer.hpp +++ b/src/stan/io/deserializer.hpp @@ -48,10 +48,12 @@ class deserializer { } /** - * Check if there is anything left to read for scalars. + * Check there are at least m reals left to read + * @param m Number of reals to read + * @throws std::runtime_error if there aren't at least m reals left */ - void check_r_capacity() const { - if (pos_r_ >= r_size_) { + void check_r_capacity(size_t m) const { + if (pos_r_ + m > r_size_) { []() STAN_COLD_PATH { throw std::runtime_error("no more scalars to read"); }(); @@ -59,10 +61,12 @@ class deserializer { } /** - * Check if there is anything left to read for integers. + * Check there are at least m integers left to read + * @param m Number of integers to read + * @throws std::runtime_error if there aren't at least m integers left */ - void check_i_capacity() const { - if (pos_i_ >= i_size_) { + void check_i_capacity(size_t m) const { + if (pos_i_ + m > i_size_) { []() STAN_COLD_PATH { throw std::runtime_error("no more integers to read"); }(); @@ -134,13 +138,18 @@ class deserializer { */ template >* = nullptr> inline auto read() { - check_r_capacity(); + check_r_capacity(1); return map_r_.coeffRef(pos_r_++); } + /** + * Construct a complex variable from the next two reals in the sequence + * + * @return Next complex value + */ template * = nullptr> inline auto read() { - check_r_capacity(); + check_r_capacity(2); return std::complex{map_r_.coeffRef(pos_r_++), map_r_.coeffRef(pos_r_++)}; } @@ -152,7 +161,7 @@ class deserializer { */ template * = nullptr> inline auto read() { - check_i_capacity(); + check_i_capacity(1); return map_i_.coeffRef(pos_i_++); } @@ -167,6 +176,7 @@ class deserializer { if (unlikely(m == 0)) { return map_vector_t(nullptr, m); } else { + check_r_capacity(m); return map_vector_t(&scalar_ptr_increment(m), m); } } @@ -182,6 +192,7 @@ class deserializer { if (unlikely(m == 0)) { return Ret(map_vector_t(nullptr, m)); } else { + check_r_capacity(2 * m); Ret ret(m); for (Eigen::Index i = 0; i < m; ++i) { ret.coeffRef(i) = std::complex{map_r_.coeffRef(pos_r_++), @@ -202,6 +213,7 @@ class deserializer { if (unlikely(m == 0)) { return map_row_vector_t(nullptr, m); } else { + check_r_capacity(m); return map_row_vector_t(&scalar_ptr_increment(m), m); } } @@ -217,6 +229,7 @@ class deserializer { if (unlikely(m == 0)) { return Ret(map_row_vector_t(nullptr, m)); } else { + check_r_capacity(2 * m); Ret ret(m); for (Eigen::Index i = 0; i < m; ++i) { ret.coeffRef(i) = std::complex{map_r_.coeffRef(pos_r_++), @@ -238,6 +251,7 @@ class deserializer { if (rows == 0 || cols == 0) { return map_matrix_t(nullptr, rows, cols); } else { + check_r_capacity(rows * cols); return map_matrix_t(&scalar_ptr_increment(rows * cols), rows, cols); } } @@ -254,6 +268,7 @@ class deserializer { if (rows == 0 || cols == 0) { return Ret(map_matrix_t(nullptr, rows, cols)); } else { + check_r_capacity(2 * rows * cols); Ret ret(rows, cols); for (Eigen::Index i = 0; i < rows * cols; ++i) { ret.coeffRef(i) = std::complex{map_r_.coeffRef(pos_r_++), diff --git a/src/test/unit/io/deserializer_test.cpp b/src/test/unit/io/deserializer_test.cpp index ca09dce043b..412cbc2526f 100644 --- a/src/test/unit/io/deserializer_test.cpp +++ b/src/test/unit/io/deserializer_test.cpp @@ -322,30 +322,86 @@ TEST(deserializer, eos_exception) { EXPECT_THROW(deserializer.read(), std::runtime_error); EXPECT_THROW(deserializer.read(), std::runtime_error); - EXPECT_THROW(deserializer.read>(), std::runtime_error); - EXPECT_THROW(deserializer.read>(3), std::runtime_error); - EXPECT_THROW(deserializer.read(2), std::runtime_error); - EXPECT_THROW( + // The strategy for all the following checks is to allocate 1 less than + // the required memory and make sure an error happens + { + std::vector theta(1); + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_THROW(deserializer.read>(), std::runtime_error); + } + + { + std::vector theta(2); + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_THROW(deserializer.read>(3), std::runtime_error); + } + + { + std::vector theta(1); + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_THROW(deserializer.read(2), std::runtime_error); + } + + { + std::vector theta(3); + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_THROW( (deserializer .read, Eigen::Dynamic, 1>>(2)), std::runtime_error); - EXPECT_THROW(deserializer.read>(3, 2), - std::runtime_error); - EXPECT_THROW(deserializer.read(2), std::runtime_error); - EXPECT_THROW( - (deserializer - .read, 1, Eigen::Dynamic>>(2)), - std::runtime_error); - EXPECT_THROW(deserializer.read>(3, 2), - std::runtime_error); - EXPECT_THROW(deserializer.read(2, 2), std::runtime_error); - EXPECT_THROW( - (deserializer.read< - Eigen::Matrix, Eigen::Dynamic, Eigen::Dynamic>>( - 2, 2)), - std::runtime_error); - EXPECT_THROW(deserializer.read>(2, 3, 2), - std::runtime_error); + } + + { + std::vector theta(5); + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_THROW(deserializer.read>(3, 2), + std::runtime_error); + } + + { + std::vector theta(1); + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_THROW(deserializer.read(2), std::runtime_error); + } + + { + std::vector theta(3); + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_THROW( + (deserializer + .read, 1, Eigen::Dynamic>>(2)), + std::runtime_error); + } + + { + std::vector theta(5); + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_THROW(deserializer.read>(3, 2), + std::runtime_error); + } + + { + std::vector theta(3); + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_THROW(deserializer.read(2, 2), std::runtime_error); + } + + { + std::vector theta(7); + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_THROW( + (deserializer.read< + Eigen::Matrix, Eigen::Dynamic, Eigen::Dynamic>>( + 2, 2)), + std::runtime_error); + } + + { + std::vector theta(11); + stan::io::deserializer deserializer(theta, theta_i); + EXPECT_THROW(deserializer.read>(2, 3, 2), + std::runtime_error); + } } // lb From 78e8bebf4db202e606f6e03efade1df62806403b Mon Sep 17 00:00:00 2001 From: Stan Jenkins Date: Tue, 9 Mar 2021 12:26:24 +0000 Subject: [PATCH 26/29] [Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.04.1 (tags/RELEASE_600/final) --- src/test/unit/io/deserializer_test.cpp | 43 +++++++++++++------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/src/test/unit/io/deserializer_test.cpp b/src/test/unit/io/deserializer_test.cpp index 412cbc2526f..a062e424a59 100644 --- a/src/test/unit/io/deserializer_test.cpp +++ b/src/test/unit/io/deserializer_test.cpp @@ -338,69 +338,68 @@ TEST(deserializer, eos_exception) { { std::vector theta(1); - stan::io::deserializer deserializer(theta, theta_i); + stan::io::deserializer deserializer(theta, theta_i); EXPECT_THROW(deserializer.read(2), std::runtime_error); } { std::vector theta(3); - stan::io::deserializer deserializer(theta, theta_i); + stan::io::deserializer deserializer(theta, theta_i); EXPECT_THROW( - (deserializer - .read, Eigen::Dynamic, 1>>(2)), - std::runtime_error); + (deserializer + .read, Eigen::Dynamic, 1>>(2)), + std::runtime_error); } { std::vector theta(5); - stan::io::deserializer deserializer(theta, theta_i); + stan::io::deserializer deserializer(theta, theta_i); EXPECT_THROW(deserializer.read>(3, 2), - std::runtime_error); + std::runtime_error); } { std::vector theta(1); - stan::io::deserializer deserializer(theta, theta_i); + stan::io::deserializer deserializer(theta, theta_i); EXPECT_THROW(deserializer.read(2), std::runtime_error); } { std::vector theta(3); - stan::io::deserializer deserializer(theta, theta_i); + stan::io::deserializer deserializer(theta, theta_i); EXPECT_THROW( - (deserializer - .read, 1, Eigen::Dynamic>>(2)), - std::runtime_error); + (deserializer + .read, 1, Eigen::Dynamic>>(2)), + std::runtime_error); } { std::vector theta(5); - stan::io::deserializer deserializer(theta, theta_i); + stan::io::deserializer deserializer(theta, theta_i); EXPECT_THROW(deserializer.read>(3, 2), - std::runtime_error); + std::runtime_error); } { std::vector theta(3); - stan::io::deserializer deserializer(theta, theta_i); + stan::io::deserializer deserializer(theta, theta_i); EXPECT_THROW(deserializer.read(2, 2), std::runtime_error); } { std::vector theta(7); - stan::io::deserializer deserializer(theta, theta_i); + stan::io::deserializer deserializer(theta, theta_i); EXPECT_THROW( - (deserializer.read< - Eigen::Matrix, Eigen::Dynamic, Eigen::Dynamic>>( - 2, 2)), - std::runtime_error); + (deserializer.read, Eigen::Dynamic, + Eigen::Dynamic>>(2, 2)), + std::runtime_error); } { std::vector theta(11); - stan::io::deserializer deserializer(theta, theta_i); + stan::io::deserializer deserializer(theta, theta_i); EXPECT_THROW(deserializer.read>(2, 3, 2), - std::runtime_error); + std::runtime_error); } } From a67b47195d3b923f76df7d43902c3fe23114410e Mon Sep 17 00:00:00 2001 From: Ben Date: Tue, 9 Mar 2021 17:08:08 -0500 Subject: [PATCH 27/29] Update code to avoid sequence point warnings --- src/stan/io/deserializer.hpp | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/stan/io/deserializer.hpp b/src/stan/io/deserializer.hpp index 6df0235157b..99c0347165d 100644 --- a/src/stan/io/deserializer.hpp +++ b/src/stan/io/deserializer.hpp @@ -39,7 +39,7 @@ class deserializer { size_t pos_i_{0}; // current position in map of integers. /** - * Return pointer to current scalar and incriment the internal counter. + * Return reference to current scalar and increment the internal counter. * @param m amount to move `pos_r_` up. */ inline T& scalar_ptr_increment(size_t m) { @@ -150,8 +150,9 @@ class deserializer { template * = nullptr> inline auto read() { check_r_capacity(2); - return std::complex{map_r_.coeffRef(pos_r_++), - map_r_.coeffRef(pos_r_++)}; + auto real = scalar_ptr_increment(1); + auto imag = scalar_ptr_increment(1); + return std::complex{real, imag}; } /** @@ -195,8 +196,9 @@ class deserializer { check_r_capacity(2 * m); Ret ret(m); for (Eigen::Index i = 0; i < m; ++i) { - ret.coeffRef(i) = std::complex{map_r_.coeffRef(pos_r_++), - map_r_.coeffRef(pos_r_++)}; + auto real = scalar_ptr_increment(1); + auto imag = scalar_ptr_increment(1); + ret.coeffRef(i) = std::complex{real, imag}; } return ret; } @@ -232,8 +234,9 @@ class deserializer { check_r_capacity(2 * m); Ret ret(m); for (Eigen::Index i = 0; i < m; ++i) { - ret.coeffRef(i) = std::complex{map_r_.coeffRef(pos_r_++), - map_r_.coeffRef(pos_r_++)}; + auto real = scalar_ptr_increment(1); + auto imag = scalar_ptr_increment(1); + ret.coeffRef(i) = std::complex{real, imag}; } return ret; } @@ -271,8 +274,9 @@ class deserializer { check_r_capacity(2 * rows * cols); Ret ret(rows, cols); for (Eigen::Index i = 0; i < rows * cols; ++i) { - ret.coeffRef(i) = std::complex{map_r_.coeffRef(pos_r_++), - map_r_.coeffRef(pos_r_++)}; + auto real = scalar_ptr_increment(1); + auto imag = scalar_ptr_increment(1); + ret.coeffRef(i) = std::complex{real, imag}; } return ret; } @@ -642,7 +646,6 @@ class deserializer { * @tparam Sizes A parameter pack of integral types. * @tparam LP Type of log probability. * @param lp The reference to the variable holding the log - * @param vecsize The size of the return vector. * @param sizes Pack of integrals to use to construct the return's type. * probability to increment. * @return Next positive_ordered vector of the specified size. From defffe78aa4074d4fd3442f04658f80a412fb2f6 Mon Sep 17 00:00:00 2001 From: Ben Date: Wed, 10 Mar 2021 12:19:43 -0500 Subject: [PATCH 28/29] Bump --- src/test/unit/io/deserializer_var_test.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/test/unit/io/deserializer_var_test.cpp b/src/test/unit/io/deserializer_var_test.cpp index 36862965887..001f672de49 100644 --- a/src/test/unit/io/deserializer_var_test.cpp +++ b/src/test/unit/io/deserializer_var_test.cpp @@ -24,8 +24,7 @@ TEST(deserializer_scalar, complex_read) { theta.push_back(3.0); theta.push_back(4.0); stan::io::deserializer deserializer(theta, theta_i); - std::complex x - = deserializer.read>(); + std::complex x = deserializer.read>(); EXPECT_FLOAT_EQ(1.0, x.real().val()); EXPECT_FLOAT_EQ(2.0, x.imag().val()); std::complex y From 0e2ecb854b01e9b6233456762bc3ad31e7d3bb27 Mon Sep 17 00:00:00 2001 From: Stan Jenkins Date: Wed, 10 Mar 2021 17:33:18 +0000 Subject: [PATCH 29/29] [Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.04.1 (tags/RELEASE_600/final) --- src/stan/io/deserializer.hpp | 12 ++++++------ src/test/unit/io/deserializer_var_test.cpp | 3 ++- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/stan/io/deserializer.hpp b/src/stan/io/deserializer.hpp index 99c0347165d..3dd0f3e27fd 100644 --- a/src/stan/io/deserializer.hpp +++ b/src/stan/io/deserializer.hpp @@ -196,8 +196,8 @@ class deserializer { check_r_capacity(2 * m); Ret ret(m); for (Eigen::Index i = 0; i < m; ++i) { - auto real = scalar_ptr_increment(1); - auto imag = scalar_ptr_increment(1); + auto real = scalar_ptr_increment(1); + auto imag = scalar_ptr_increment(1); ret.coeffRef(i) = std::complex{real, imag}; } return ret; @@ -234,8 +234,8 @@ class deserializer { check_r_capacity(2 * m); Ret ret(m); for (Eigen::Index i = 0; i < m; ++i) { - auto real = scalar_ptr_increment(1); - auto imag = scalar_ptr_increment(1); + auto real = scalar_ptr_increment(1); + auto imag = scalar_ptr_increment(1); ret.coeffRef(i) = std::complex{real, imag}; } return ret; @@ -274,8 +274,8 @@ class deserializer { check_r_capacity(2 * rows * cols); Ret ret(rows, cols); for (Eigen::Index i = 0; i < rows * cols; ++i) { - auto real = scalar_ptr_increment(1); - auto imag = scalar_ptr_increment(1); + auto real = scalar_ptr_increment(1); + auto imag = scalar_ptr_increment(1); ret.coeffRef(i) = std::complex{real, imag}; } return ret; diff --git a/src/test/unit/io/deserializer_var_test.cpp b/src/test/unit/io/deserializer_var_test.cpp index 001f672de49..36862965887 100644 --- a/src/test/unit/io/deserializer_var_test.cpp +++ b/src/test/unit/io/deserializer_var_test.cpp @@ -24,7 +24,8 @@ TEST(deserializer_scalar, complex_read) { theta.push_back(3.0); theta.push_back(4.0); stan::io::deserializer deserializer(theta, theta_i); - std::complex x = deserializer.read>(); + std::complex x + = deserializer.read>(); EXPECT_FLOAT_EQ(1.0, x.real().val()); EXPECT_FLOAT_EQ(2.0, x.imag().val()); std::complex y