1 #ifndef STAN_MATH_PRIM_FUN_APPEND_COL_HPP
2 #define STAN_MATH_PRIM_FUN_APPEND_COL_HPP
3
4 #include <stan/math/prim/meta.hpp>
5 #include <stan/math/prim/err.hpp>
6 #include <stan/math/prim/fun/Eigen.hpp>
7 #include <vector>
8
9 namespace stan {
10 namespace math {
11
12 /**
13 * Return the result of appending the second argument matrix after the
14 * first argument matrix, that is, putting them side by side, with
15 * the first matrix followed by the second matrix.
16 *
17 * Given input types result in following outputs:
18 * (matrix, matrix) -> matrix,
19 * (matrix, vector) -> matrix,
20 * (vector, matrix) -> matrix,
21 * (vector, vector) -> matrix,
22 * (row vector, row vector) -> row_vector.
23 *
24 * @tparam T1 type of the first matrix
25 * @tparam T2 type of the second matrix
26 *
27 * @param A First matrix.
28 * @param B Second matrix.
29 * @return Result of appending the first matrix followed by the
30 * second matrix side by side.
31 */
32 template <typename T1, typename T2, typename = require_all_eigen_t<T1, T2>>
append_col(const T1 & A,const T2 & B)33 inline auto append_col(const T1& A, const T2& B) {
34 using Eigen::Dynamic;
35 using Eigen::Matrix;
36 using T_return = return_type_t<T1, T2>;
37 constexpr int row_type
38 = (T1::RowsAtCompileTime == 1 && T2::RowsAtCompileTime == 1)
39 ? 1
40 : Eigen::Dynamic;
41
42 int Arows = A.rows();
43 int Brows = B.rows();
44 int Acols = A.cols();
45 int Bcols = B.cols();
46 check_size_match("append_col", "rows of A", Arows, "rows of B", Brows);
47
48 Matrix<T_return, row_type, Dynamic> result(Arows, Acols + Bcols);
49 result.leftCols(Acols) = A.template cast<T_return>();
50 result.rightCols(Bcols) = B.template cast<T_return>();
51 return result;
52 }
53
54 /**
55 * Return the result of stacking an scalar on top of the
56 * a row vector, with the result being a row vector.
57 *
58 * This function applies to (scalar, row vector) and returns a
59 * row vector.
60 *
61 * @tparam Scal type of the scalar
62 * @tparam RowVec type of the row vector
63 *
64 * @param A scalar.
65 * @param B row vector.
66 * @return Result of stacking the scalar on top of the row vector.
67 */
68 template <typename Scal, typename RowVec,
69 require_stan_scalar_t<Scal>* = nullptr,
70 require_t<is_eigen_row_vector<RowVec>>* = nullptr>
append_col(const Scal & A,const RowVec & B)71 inline Eigen::Matrix<return_type_t<Scal, RowVec>, 1, Eigen::Dynamic> append_col(
72 const Scal& A, const RowVec& B) {
73 using Eigen::Dynamic;
74 using Eigen::Matrix;
75 using T_return = return_type_t<Scal, RowVec>;
76
77 Matrix<T_return, 1, Dynamic> result(B.size() + 1);
78 result << A, B.template cast<T_return>();
79 return result;
80 }
81
82 /**
83 * Return the result of stacking a row vector on top of the
84 * an scalar, with the result being a row vector.
85 *
86 * This function applies to (row vector, scalar) and returns a
87 * row vector.
88 *
89 * @tparam RowVec type of the row vector
90 * @tparam Scal type of the scalar
91 *
92 * @param A row vector.
93 * @param B scalar.
94 * @return Result of stacking the row vector on top of the scalar.
95 */
96 template <typename RowVec, typename Scal,
97 require_t<is_eigen_row_vector<RowVec>>* = nullptr,
98 require_stan_scalar_t<Scal>* = nullptr>
append_col(const RowVec & A,const Scal & B)99 inline Eigen::Matrix<return_type_t<RowVec, Scal>, 1, Eigen::Dynamic> append_col(
100 const RowVec& A, const Scal& B) {
101 using Eigen::Dynamic;
102 using Eigen::Matrix;
103 using T_return = return_type_t<RowVec, Scal>;
104
105 Matrix<T_return, 1, Dynamic> result(A.size() + 1);
106 result << A.template cast<T_return>(), B;
107 return result;
108 }
109
110 } // namespace math
111 } // namespace stan
112
113 #endif
114