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