Skip to content

KroneckerProduct::Scalar being private prevents use of stan::math::var type

#include <Eigen/Dense>
#include <unsupported/Eigen/KroneckerProduct>
#include <stan/math.hpp>
int main()
{
  Eigen::Matrix<stan::math::var,2,2> A;
  const auto B = Eigen::kroneckerProduct(A, Eigen::Matrix<double,2,2>::Identity());
  Eigen::Matrix<double,4,1> C;
  B * C;
}

fails to compile with errors

build/_deps/stan-src/stan/math/prim/meta/is_eigen.hpp:44:42: error: 'Scalar' is a private member of 'Eigen::KroneckerProductBase<Eigen::KroneckerProduct<Eigen::Matrix<stan::math::var_value<double>, 2, 2, 0>, Eigen::CwiseNullaryOp<Eigen::internal::scalar_identity_op<double>, Eigen::Matrix<double, 2, 2, 0>>>>'
  using type = typename std::decay_t<T>::Scalar;
                                         ^
build/_deps/stan-src/stan/math/prim/meta/value_type.hpp:35:1: note: in instantiation of template class 'stan::value_type<Eigen::KroneckerProduct<Eigen::Matrix<stan::math::var_value<double>, 2, 2, 0>, Eigen::CwiseNullaryOp<Eigen::internal::scalar_identity_op<double>, Eigen::Matrix<double, 2, 2, 0>>>>' requested here
using value_type_t = typename value_type<T>::type;
^
build/_deps/stan-src/stan/math/prim/meta/is_stan_scalar.hpp:27:48: note: in instantiation of template type alias 'value_type_t' requested here
                            std::is_arithmetic<value_type_t<T>>>,
                                               ^
build/_deps/stan-src/stan/math/prim/meta/require_helpers.hpp:19:36: note: in instantiation of template class 'stan::is_stan_scalar<Eigen::KroneckerProduct<Eigen::Matrix<stan::math::var_value<double>, 2, 2, 0>, Eigen::CwiseNullaryOp<Eigen::internal::scalar_identity_op<double>, Eigen::Matrix<double, 2, 2, 0>>>>' requested here
using require_t = std::enable_if_t<Check::value>;
                                   ^
build/_deps/stan-src/stan/math/prim/meta/is_stan_scalar.hpp:39:1: note: in instantiation of template type alias 'require_t' requested here
using require_stan_scalar_t = require_t<is_stan_scalar<std::decay_t<T>>>;
^
build/_deps/stan-src/stan/math/rev/core/std_complex.hpp:45:42: note: in instantiation of template type alias 'require_stan_scalar_t' requested here
  template <typename U, typename = stan::require_stan_scalar_t<U>>
                                         ^
build/_deps/stan-src/stan/math/rev/core/std_complex.hpp:46:3: note: in instantiation of default argument for 'complex<Eigen::KroneckerProduct<Eigen::Matrix<stan::math::var_value<double>, 2, 2, 0>, Eigen::CwiseNullaryOp<Eigen::internal::scalar_identity_op<double>, Eigen::Matrix<double, 2, 2, 0>>>>' required here
  complex(const U& re) : base_t(re) {}  // NOLINT(runtime/explicit)
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.cpp:9:3: note: while substituting deduced template arguments into function template 'complex' [with U = Eigen::KroneckerProduct<Eigen::Matrix<stan::math::var_value<double>, 2, 2, 0>, Eigen::CwiseNullaryOp<Eigen::internal::scalar_identity_op<double>, Eigen::Matrix<double, 2, 2, 0>>>, $1 = (no value)]
  B * C;
  ^
build/_deps/stan-src/lib/eigen_3.4.0/unsupported/Eigen/src/KroneckerProduct/KroneckerTensorProduct.h:29:37: note: declared private here
    typedef typename Traits::Scalar Scalar;
                                    ^
1 error generated.
make[2]: *** [CMakeFiles/example.dir/main.cpp.o] Error 1
make[1]: *** [CMakeFiles/example.dir/all] Error 2
make: *** [all] Error 2

Seems like almost all classes structs in Eigen keep the Scalar public or protected.