1 #ifndef STAN_MATH_PRIM_FUN_AS_ARRAY_OR_SCALAR_HPP
2 #define STAN_MATH_PRIM_FUN_AS_ARRAY_OR_SCALAR_HPP
3 
4 #include <stan/math/prim/fun/Eigen.hpp>
5 #include <stan/math/prim/meta.hpp>
6 #include <vector>
7 
8 namespace stan {
9 namespace math {
10 
11 /**
12  * Returns specified input value.
13  *
14  * @tparam T Type of element.
15  * @param v Specified value.
16  * @return Same value.
17  */
18 template <typename T, require_stan_scalar_t<T>* = nullptr>
as_array_or_scalar(T && v)19 inline T as_array_or_scalar(T&& v) {
20   return std::forward<T>(v);
21 }
22 
23 /**
24  * Returns a reference to rvalue specified input value.
25  *
26  * @tparam T Type of element.
27  * @param v Specified value.
28  * @return Same value.
29  */
30 template <typename T, require_stan_scalar_t<T>* = nullptr>
as_array_or_scalar(T & v)31 inline T& as_array_or_scalar(T& v) {
32   return v;
33 }
34 
35 /**
36  * Returns specified input value.
37  *
38  * @tparam T Type of element.
39  * @param v Specified value.
40  * @return Same value.
41  */
42 template <typename T, require_eigen_array_t<T>* = nullptr>
as_array_or_scalar(T && v)43 inline T as_array_or_scalar(T&& v) {
44   return std::forward<T>(v);
45 }
46 
47 /**
48  * Converts a matrix type to an array.
49  *
50  * @tparam T Type of \c Eigen \c Matrix or expression
51  * @param v Specified \c Eigen \c Matrix or expression.
52  * @return Matrix converted to an array.
53  */
54 template <typename T, typename = require_eigen_t<T>,
55           require_not_eigen_array_t<T>* = nullptr>
as_array_or_scalar(T && v)56 inline auto as_array_or_scalar(T&& v) {
57   return make_holder([](auto& x) { return x.array(); }, std::forward<T>(v));
58 }
59 
60 /**
61  * Converts a std::vector type to an array.
62  *
63  * @tparam T Type of scalar element.
64  * @param v Specified vector.
65  * @return Matrix converted to an array.
66  */
67 template <typename T, require_std_vector_t<T>* = nullptr,
68           require_not_std_vector_t<value_type_t<T>>* = nullptr>
as_array_or_scalar(T && v)69 inline auto as_array_or_scalar(T&& v) {
70   using T_map
71       = Eigen::Map<const Eigen::Array<value_type_t<T>, Eigen::Dynamic, 1>>;
72   return make_holder([](auto& x) { return T_map(x.data(), x.size()); },
73                      std::forward<T>(v));
74 }
75 
76 /**
77  * Converts an std::vector<std::vector> to an Eigen Array.
78  * @tparam T A standard vector with inner container of a standard vector
79  *  with an inner stan scalar.
80  * @param v specified vector of vectorised
81  * @return An Eigen Array with dynamic rows and columns.
82  */
83 template <typename T, require_std_vector_vt<is_std_vector, T>* = nullptr,
84           require_std_vector_vt<is_stan_scalar, value_type_t<T>>* = nullptr>
as_array_or_scalar(T && v)85 inline auto as_array_or_scalar(T&& v) {
86   Eigen::Array<scalar_type_t<T>, -1, -1> ret(v.size(), v[0].size());
87   for (size_t i = 0; i < v.size(); ++i) {
88     ret.row(i) = Eigen::Map<const Eigen::Array<scalar_type_t<T>, 1, -1>>(
89         v[i].data(), v[i].size());
90   }
91   return ret;
92 }
93 
94 }  // namespace math
95 }  // namespace stan
96 
97 #endif
98