From 39e9930764d71e17ba02dd6ca3b2d9e23e9d3628 Mon Sep 17 00:00:00 2001 From: Steve Bronder Date: Mon, 11 Nov 2024 11:41:43 -0500 Subject: [PATCH 1/4] use eigen internal traits for getting the scalar type of a eigen type --- stan/math/prim/meta/is_eigen.hpp | 2 +- test/unit/math/prim/meta/value_type_test.cpp | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/stan/math/prim/meta/is_eigen.hpp b/stan/math/prim/meta/is_eigen.hpp index a1f2ab332ee..ee0e5a00317 100644 --- a/stan/math/prim/meta/is_eigen.hpp +++ b/stan/math/prim/meta/is_eigen.hpp @@ -41,7 +41,7 @@ struct scalar_type::value>> { */ template struct value_type::value>> { - using type = typename std::decay_t::Scalar; + using type = typename Eigen::internal::traits>::Scalar; }; /*! \ingroup require_eigens_types */ diff --git a/test/unit/math/prim/meta/value_type_test.cpp b/test/unit/math/prim/meta/value_type_test.cpp index c4c61e6de5e..400e4009ac9 100644 --- a/test/unit/math/prim/meta/value_type_test.cpp +++ b/test/unit/math/prim/meta/value_type_test.cpp @@ -1,5 +1,6 @@ -#include #include +#include +#include #include #include @@ -35,3 +36,11 @@ TEST(MathMetaPrim, value_type_matrix) { EXPECT_SAME_TYPE(Eigen::RowVectorXd, value_type >::type); } + +TEST(MathMetaPrim, value_type_kronecker) { + Eigen::Matrix A; + const auto B = Eigen::kroneckerProduct(A, Eigen::Matrix::Identity()); + Eigen::Matrix C = Eigen::Matrix::Random(4, 1); + EXPECT_TRUE((std::is_same>::value)); + Eigen::MatrixXd D = B * C; +} From 3f065fa41627de7c6e290070d4be366415532453 Mon Sep 17 00:00:00 2001 From: Stan Jenkins Date: Mon, 11 Nov 2024 11:44:41 -0500 Subject: [PATCH 2/4] [Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1 --- stan/math/prim/meta/is_eigen.hpp | 2 +- test/unit/math/prim/meta/value_type_test.cpp | 21 ++++++++++---------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/stan/math/prim/meta/is_eigen.hpp b/stan/math/prim/meta/is_eigen.hpp index ee0e5a00317..2222ac6e063 100644 --- a/stan/math/prim/meta/is_eigen.hpp +++ b/stan/math/prim/meta/is_eigen.hpp @@ -41,7 +41,7 @@ struct scalar_type::value>> { */ template struct value_type::value>> { - using type = typename Eigen::internal::traits>::Scalar; + using type = typename Eigen::internal::traits>::Scalar; }; /*! \ingroup require_eigens_types */ diff --git a/test/unit/math/prim/meta/value_type_test.cpp b/test/unit/math/prim/meta/value_type_test.cpp index 400e4009ac9..018aba6467d 100644 --- a/test/unit/math/prim/meta/value_type_test.cpp +++ b/test/unit/math/prim/meta/value_type_test.cpp @@ -9,16 +9,16 @@ TEST(MathMetaPrim, value_type_vector) { using std::vector; EXPECT_SAME_TYPE(vector::value_type, - value_type >::type); + value_type>::type); EXPECT_SAME_TYPE(vector::value_type, - value_type >::type); + value_type>::type); - EXPECT_SAME_TYPE(vector >::value_type, - value_type > >::type); + EXPECT_SAME_TYPE(vector>::value_type, + value_type>>::type); - EXPECT_SAME_TYPE(vector >::value_type, - value_type > >::type); + EXPECT_SAME_TYPE(vector>::value_type, + value_type>>::type); } TEST(MathMetaPrim, value_type_matrix) { @@ -34,13 +34,14 @@ TEST(MathMetaPrim, value_type_matrix) { value_type::type); EXPECT_SAME_TYPE(Eigen::RowVectorXd, - value_type >::type); + value_type>::type); } TEST(MathMetaPrim, value_type_kronecker) { - Eigen::Matrix A; - const auto B = Eigen::kroneckerProduct(A, Eigen::Matrix::Identity()); - Eigen::Matrix C = Eigen::Matrix::Random(4, 1); + Eigen::Matrix A; + const auto B + = Eigen::kroneckerProduct(A, Eigen::Matrix::Identity()); + Eigen::Matrix C = Eigen::Matrix::Random(4, 1); EXPECT_TRUE((std::is_same>::value)); Eigen::MatrixXd D = B * C; } From 62094ed11be174092a68e82449806fa790ecc85f Mon Sep 17 00:00:00 2001 From: Steve Bronder Date: Mon, 11 Nov 2024 14:39:33 -0500 Subject: [PATCH 3/4] breakup value_type and scalar_type for Eigen types based on whether they have a Scalar type trait --- stan/math/prim/meta/is_eigen.hpp | 52 +++++++++++++++++++++++++++-- stan/math/rev/core/arena_matrix.hpp | 1 + 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/stan/math/prim/meta/is_eigen.hpp b/stan/math/prim/meta/is_eigen.hpp index 2222ac6e063..480dc601330 100644 --- a/stan/math/prim/meta/is_eigen.hpp +++ b/stan/math/prim/meta/is_eigen.hpp @@ -20,6 +20,28 @@ template struct is_eigen : bool_constant::value> {}; +namespace internal { +// primary template handles types that have no nested ::type member: +template +struct has_internal_trait : std::false_type {}; + +// specialization recognizes types that do have a nested ::type member: +template +struct has_internal_trait>>> + : std::true_type {}; + +// primary template handles types that have no nested ::type member: +template +struct has_scalar_trait : std::false_type {}; + +// specialization recognizes types that do have a nested ::type member: +template +struct has_scalar_trait::Scalar>> + : std::true_type {}; + +} // namespace internal + + /** * Template metaprogram defining the base scalar type of * values stored in an Eigen matrix. @@ -28,7 +50,7 @@ struct is_eigen * @ingroup type_trait */ template -struct scalar_type::value>> { +struct scalar_type::value && internal::has_scalar_trait::value>> { using type = scalar_type_t::Scalar>; }; @@ -40,10 +62,36 @@ struct scalar_type::value>> { * @ingroup type_trait */ template -struct value_type::value>> { +struct value_type::value && internal::has_scalar_trait::value>> { + using type = typename std::decay_t::Scalar; +}; + + +/** + * Template metaprogram defining the base scalar type of + * values stored in an Eigen matrix. + * + * @tparam T type to check. + * @ingroup type_trait + */ +template +struct scalar_type::value && !internal::has_scalar_trait::value>> { + using type = scalar_type_t>::Scalar>; +}; + +/** + * Template metaprogram defining the type of values stored in an + * Eigen matrix, vector, or row vector. + * + * @tparam T type to check + * @ingroup type_trait + */ +template +struct value_type::value && !internal::has_scalar_trait::value>> { using type = typename Eigen::internal::traits>::Scalar; }; + /*! \ingroup require_eigens_types */ /*! \defgroup eigen_types eigen */ /*! \addtogroup eigen_types */ diff --git a/stan/math/rev/core/arena_matrix.hpp b/stan/math/rev/core/arena_matrix.hpp index 8913d4adc70..da9094abcb2 100644 --- a/stan/math/rev/core/arena_matrix.hpp +++ b/stan/math/rev/core/arena_matrix.hpp @@ -482,6 +482,7 @@ namespace internal { template struct traits> { using base = traits>; + using Scalar = typename base::Scalar; using XprKind = typename Eigen::internal::traits>::XprKind; enum { PlainObjectTypeInnerSize = base::PlainObjectTypeInnerSize, From 283f7bf7cf2eee8c049320ab403fe4bc69123ca4 Mon Sep 17 00:00:00 2001 From: Stan Jenkins Date: Mon, 11 Nov 2024 14:40:32 -0500 Subject: [PATCH 4/4] [Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1 --- stan/math/prim/meta/is_eigen.hpp | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/stan/math/prim/meta/is_eigen.hpp b/stan/math/prim/meta/is_eigen.hpp index 480dc601330..5489a713b94 100644 --- a/stan/math/prim/meta/is_eigen.hpp +++ b/stan/math/prim/meta/is_eigen.hpp @@ -27,7 +27,8 @@ struct has_internal_trait : std::false_type {}; // specialization recognizes types that do have a nested ::type member: template -struct has_internal_trait>>> +struct has_internal_trait>>> : std::true_type {}; // primary template handles types that have no nested ::type member: @@ -41,7 +42,6 @@ struct has_scalar_trait::Scalar>> } // namespace internal - /** * Template metaprogram defining the base scalar type of * values stored in an Eigen matrix. @@ -50,7 +50,9 @@ struct has_scalar_trait::Scalar>> * @ingroup type_trait */ template -struct scalar_type::value && internal::has_scalar_trait::value>> { +struct scalar_type::value + && internal::has_scalar_trait::value>> { using type = scalar_type_t::Scalar>; }; @@ -62,11 +64,12 @@ struct scalar_type::value && internal::has_scala * @ingroup type_trait */ template -struct value_type::value && internal::has_scalar_trait::value>> { +struct value_type::value + && internal::has_scalar_trait::value>> { using type = typename std::decay_t::Scalar; }; - /** * Template metaprogram defining the base scalar type of * values stored in an Eigen matrix. @@ -75,8 +78,11 @@ struct value_type::value && internal::has_scalar * @ingroup type_trait */ template -struct scalar_type::value && !internal::has_scalar_trait::value>> { - using type = scalar_type_t>::Scalar>; +struct scalar_type::value + && !internal::has_scalar_trait::value>> { + using type = scalar_type_t< + typename Eigen::internal::traits>::Scalar>; }; /** @@ -87,11 +93,12 @@ struct scalar_type::value && !internal::has_scal * @ingroup type_trait */ template -struct value_type::value && !internal::has_scalar_trait::value>> { +struct value_type::value + && !internal::has_scalar_trait::value>> { using type = typename Eigen::internal::traits>::Scalar; }; - /*! \ingroup require_eigens_types */ /*! \defgroup eigen_types eigen */ /*! \addtogroup eigen_types */