1 #ifndef STAN_MATH_PRIM_FUN_AS_COLUMN_VECTOR_OR_SCALAR_HPP
2 #define STAN_MATH_PRIM_FUN_AS_COLUMN_VECTOR_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 namespace internal {
11 template <typename T, typename S, typename Enable>
12 class empty_broadcast_array;
13 }
14 /**
15  * no-op that passes the scalar
16  *
17  * @tparam T Type of scalar element.
18  * @param a Specified scalar.
19  * @return the scalar.
20  */
21 template <typename T, require_stan_scalar_t<T>* = nullptr>
as_column_vector_or_scalar(const T & a)22 inline T as_column_vector_or_scalar(const T& a) {
23   return a;
24 }
25 
26 /**
27  * No-op used when working with operands and partials.
28  * This is not implimented so it cannot be invoked and only exists so the
29  * compiler can resolve it's output type.
30  */
31 template <typename T, typename S>
32 internal::empty_broadcast_array<T, S, void>& as_column_vector_or_scalar(
33     internal::empty_broadcast_array<T, S, void>& a);
34 
35 /**
36  * no-op that returns a column vector.
37  *
38  * @tparam T Type inheriting from `EigenBase` with dynamic compile time rows
39  *  and fixed column of 1.
40  * @param a Specified vector.
41  * @return Same vector.
42  */
43 template <typename T, require_eigen_col_vector_t<T>* = nullptr>
as_column_vector_or_scalar(T && a)44 inline T&& as_column_vector_or_scalar(T&& a) {
45   return std::forward<T>(a);
46 }
47 
48 /**
49  * Converts a row vector to an eigen column vector. For row vectors this returns
50  *  a `Transpose<Eigen::Matrix<T, 1, -1>>`.
51  *
52  * @tparam T Type inheriting from `EigenBase` with dynamic compile time columns
53  * and fixed row of 1.
54  * @param a Specified vector.
55  * @return Transposed vector.
56  */
57 template <typename T, require_eigen_row_vector_t<T>* = nullptr,
58           require_not_eigen_col_vector_t<T>* = nullptr>
as_column_vector_or_scalar(T && a)59 inline auto as_column_vector_or_scalar(T&& a) {
60   return make_holder([](auto& x) { return x.transpose(); }, std::forward<T>(a));
61 }
62 
63 /**
64  * Converts `std::vector` to a column vector.
65  *
66  * @tparam T `std::vector` type.
67  * @param a Specified vector.
68  * @return input converted to a column vector.
69  */
70 template <typename T, require_std_vector_t<T>* = nullptr>
as_column_vector_or_scalar(T && a)71 inline auto as_column_vector_or_scalar(T&& a) {
72   using plain_vector = Eigen::Matrix<value_type_t<T>, Eigen::Dynamic, 1>;
73   using optionally_const_vector
74       = std::conditional_t<std::is_const<std::remove_reference_t<T>>::value,
75                            const plain_vector, plain_vector>;
76   using T_map = Eigen::Map<optionally_const_vector>;
77   return make_holder([](auto& x) { return T_map(x.data(), x.size()); },
78                      std::forward<T>(a));
79 }
80 
81 }  // namespace math
82 }  // namespace stan
83 
84 #endif
85