From 80c9c400339f1c4c87f96a3e970b1ebcd537f940 Mon Sep 17 00:00:00 2001 From: Devesh Vaidya Date: Fri, 23 Oct 2026 20:30:56 +0530 Subject: [PATCH 1/3] Fix dims for arrays of Eigen vectors Signed-off-by: Devesh Vaidya --- stan/math/prim/fun/dims.hpp | 6 +++++- test/unit/math/prim/fun/dims_test.cpp | 28 +++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/stan/math/prim/fun/dims.hpp b/stan/math/prim/fun/dims.hpp index 332a32e6089..f85a7e78410 100644 --- a/stan/math/prim/fun/dims.hpp +++ b/stan/math/prim/fun/dims.hpp @@ -45,7 +45,11 @@ template inline void dims(const std::vector& x, std::vector& result) { result.push_back(x.size()); if (x.size() > 0) { - dims(x[0], result); + if constexpr (is_eigen_vector::value) { + result.push_back(x[0].size()); + } else { + dims(x[0], result); + } } } diff --git a/test/unit/math/prim/fun/dims_test.cpp b/test/unit/math/prim/fun/dims_test.cpp index 67a988a8598..00e00714a6b 100644 --- a/test/unit/math/prim/fun/dims_test.cpp +++ b/test/unit/math/prim/fun/dims_test.cpp @@ -58,4 +58,32 @@ TEST(MathMatrixPrimMat, dims) { EXPECT_EQ(2, dims8[0]); EXPECT_EQ(7, dims8[1]); EXPECT_EQ(8, dims8[2]); +} + TEST(MathMatrixPrimMat, dims_nested_vector_arrays) { + using Eigen::Dynamic; + using Eigen::Matrix; + using stan::math::dims; + using std::vector; + + Matrix v1(1); + vector> inner1{v1}; + vector>> x1{inner1}; + + const auto result1 = dims(x1); + + ASSERT_EQ(3U, result1.size()); + EXPECT_EQ(1, result1[0]); + EXPECT_EQ(1, result1[1]); + EXPECT_EQ(1, result1[2]); + + Matrix v2(5); + vector> inner2(3, v2); + vector>> x2(2, inner2); + + const auto result2 = dims(x2); + + ASSERT_EQ(3U, result2.size()); + EXPECT_EQ(2, result2[0]); + EXPECT_EQ(3, result2[1]); + EXPECT_EQ(5, result2[2]); } From 24f797656acdf338d670ea36313a67ea765c8de7 Mon Sep 17 00:00:00 2001 From: Stan Jenkins Date: Fri, 23 Oct 2026 12:26:59 -0400 Subject: [PATCH 2/3] [Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1 --- test/unit/math/prim/fun/dims_test.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/unit/math/prim/fun/dims_test.cpp b/test/unit/math/prim/fun/dims_test.cpp index 00e00714a6b..bd9fd402c65 100644 --- a/test/unit/math/prim/fun/dims_test.cpp +++ b/test/unit/math/prim/fun/dims_test.cpp @@ -23,7 +23,7 @@ TEST(MathMatrixPrimMat, dims) { EXPECT_EQ(1U, dims3.size()); EXPECT_EQ(2, dims3[0]); - vector > x4; + vector> x4; x4.push_back(x3); x4.push_back(x3); x4.push_back(x3); @@ -50,7 +50,7 @@ TEST(MathMatrixPrimMat, dims) { EXPECT_EQ(1, dims7[0]); EXPECT_EQ(17, dims7[1]); - vector > x8; + vector> x8; x8.push_back(x5); x8.push_back(x5); vector dims8 = dims(x8); @@ -59,7 +59,7 @@ TEST(MathMatrixPrimMat, dims) { EXPECT_EQ(7, dims8[1]); EXPECT_EQ(8, dims8[2]); } - TEST(MathMatrixPrimMat, dims_nested_vector_arrays) { +TEST(MathMatrixPrimMat, dims_nested_vector_arrays) { using Eigen::Dynamic; using Eigen::Matrix; using stan::math::dims; From a185cf40d3827dab662ab45b7d0b124ea75e55bd Mon Sep 17 00:00:00 2001 From: Devesh Vaidya Date: Sat, 24 Oct 2026 13:13:38 +0530 Subject: [PATCH 3/3] Fixed dimensions for arrays of Eigen vectors Signed-off-by: Devesh Vaidya --- stan/math/prim/fun/resize.hpp | 21 +++++++++++++++++---- test/unit/math/prim/fun/resize_test.cpp | 22 ++++++++++++++++++---- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/stan/math/prim/fun/resize.hpp b/stan/math/prim/fun/resize.hpp index 00c9c0a7eed..6b509e3c08a 100644 --- a/stan/math/prim/fun/resize.hpp +++ b/stan/math/prim/fun/resize.hpp @@ -7,24 +7,38 @@ namespace stan { namespace math { namespace internal { + template inline void resize(Eigen::Matrix& x, const std::vector& dims, int pos) { + if constexpr (R == 1 || C == 1) { + if (pos + 1 == static_cast(dims.size())) { + if constexpr (R == 1 && C != 1) { + x.resize(1, dims[pos]); + } else { + x.resize(dims[pos], 1); + } + return; + } + } x.resize(dims[pos], dims[pos + 1]); } template -inline void resize(T /*x*/, const std::vector& /*dims*/, int /*pos*/) { - // no-op +inline void resize(T /*x*/, const std::vector& /*dims*/, + int /*pos*/ = 0) { // no-op } template -inline void resize(std::vector& x, const std::vector& dims, int pos) { +inline void resize(std::vector& x, const std::vector& dims, + int pos = 0) { x.resize(dims[pos]); ++pos; + if (pos >= static_cast(dims.size())) { return; // skips lowest loop to scalar } + for (size_t i = 0; i < x.size(); ++i) { resize(x[i], dims, pos); } @@ -47,5 +61,4 @@ inline void resize(T& x, std::vector dims) { } // namespace math } // namespace stan - #endif diff --git a/test/unit/math/prim/fun/resize_test.cpp b/test/unit/math/prim/fun/resize_test.cpp index f2fe785180c..cc21facf33c 100644 --- a/test/unit/math/prim/fun/resize_test.cpp +++ b/test/unit/math/prim/fun/resize_test.cpp @@ -98,7 +98,7 @@ TEST(MathMatrixPrimMat, resize_svec_svec_double) { using stan::math::matrix_d; using stan::math::row_vector_d; using stan::math::vector_d; - std::vector > xx; + std::vector> xx; EXPECT_EQ(0U, xx.size()); std::vector dims; dims.push_back(4U); @@ -120,7 +120,7 @@ TEST(MathMatrixPrimMat, resize_svec_v_double) { using stan::math::matrix_d; using stan::math::row_vector_d; using stan::math::vector_d; - std::vector > xx; + std::vector> xx; EXPECT_EQ(0U, xx.size()); std::vector dims; dims.push_back(4U); @@ -143,7 +143,7 @@ TEST(MathMatrixPrimMat, resize_svec_rv_double) { using stan::math::matrix_d; using stan::math::row_vector_d; using stan::math::vector_d; - std::vector > xx; + std::vector> xx; EXPECT_EQ(0U, xx.size()); std::vector dims; dims.push_back(4U); @@ -166,7 +166,7 @@ TEST(MathMatrixPrimMat, resize_svec_svec_matrix_double) { using stan::math::matrix_d; using stan::math::row_vector_d; using stan::math::vector_d; - std::vector > > mm; + std::vector>> mm; std::vector dims; dims.push_back(4U); dims.push_back(5U); @@ -178,3 +178,17 @@ TEST(MathMatrixPrimMat, resize_svec_svec_matrix_double) { EXPECT_EQ(6, mm[1][2].rows()); EXPECT_EQ(3, mm[3][4].cols()); } +TEST(MathMatrixPrimMat, resize_nested_vectors_of_eigen_vectors) { + std::vector> x; + + stan::math::resize(x, {2, 3, 4}); + + ASSERT_EQ(x.size(), 2); + for (const auto& row : x) { + ASSERT_EQ(row.size(), 3); + for (const auto& v : row) { + EXPECT_EQ(v.rows(), 4); + EXPECT_EQ(v.cols(), 1); + } + } +}