1 #ifndef STAN_MATH_PRIM_FUN_TO_MATRIX_HPP
2 #define STAN_MATH_PRIM_FUN_TO_MATRIX_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 * Returns a matrix with dynamic dimensions constructed from an
14 * Eigen matrix which is either a row vector, column vector,
15 * or matrix.
16 * The runtime dimensions will be the same as the input.
17 *
18 * @tparam EigMat type of the matrix
19 *
20 * @param x matrix
21 * @return the matrix representation of the input
22 */
23 template <typename EigMat, require_eigen_t<EigMat>* = nullptr>
to_matrix(EigMat && x)24 inline EigMat to_matrix(EigMat&& x) {
25 return std::forward<EigMat>(x);
26 }
27
28 /**
29 * Returns a matrix representation of a standard vector of Eigen
30 * row vectors with the same dimensions and indexing order.
31 *
32 * @tparam T type of the elements in the vector
33 * @param x Eigen vector of vectors of scalar values
34 * @return the matrix representation of the input
35 */
36 template <typename T>
to_matrix(const std::vector<Eigen::Matrix<T,1,Eigen::Dynamic>> & x)37 inline Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> to_matrix(
38 const std::vector<Eigen::Matrix<T, 1, Eigen::Dynamic>>& x) {
39 int rows = x.size();
40 if (rows == 0) {
41 return {};
42 }
43 int cols = x[0].size();
44 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> result(rows, cols);
45 for (int i = 0, ij = 0; i < cols; i++) {
46 for (int j = 0; j < rows; j++, ij++) {
47 result.coeffRef(ij) = x[j][i];
48 }
49 }
50 return result;
51 }
52
53 /**
54 * Returns a matrix representation of the standard vector of
55 * standard vectors with the same dimensions and indexing order.
56 *
57 * @tparam T type of elements in the vector
58 * @param x vector of vectors of scalar values
59 * @return the matrix representation of the input
60 */
61 template <typename T>
62 inline Eigen::Matrix<return_type_t<T, double>, Eigen::Dynamic, Eigen::Dynamic>
to_matrix(const std::vector<std::vector<T>> & x)63 to_matrix(const std::vector<std::vector<T>>& x) {
64 size_t rows = x.size();
65 if (rows == 0) {
66 return {};
67 }
68 size_t cols = x[0].size();
69 Eigen::Matrix<return_type_t<T, double>, Eigen::Dynamic, Eigen::Dynamic>
70 result(rows, cols);
71 for (size_t i = 0, ij = 0; i < cols; i++) {
72 for (size_t j = 0; j < rows; j++, ij++) {
73 result.coeffRef(ij) = x[j][i];
74 }
75 }
76 return result;
77 }
78
79 /**
80 * Returns a matrix representation of the vector in column-major
81 * order with the specified number of rows and columns.
82 *
83 * @tparam EigMat type of the matrix
84 *
85 * @param x matrix
86 * @param m rows
87 * @param n columns
88 * @return Reshaped inputted matrix
89 * @throw <code>std::invalid_argument</code> if the sizes
90 * do not match
91 */
92 template <typename EigMat, require_eigen_t<EigMat>* = nullptr>
93 inline Eigen::Matrix<value_type_t<EigMat>, Eigen::Dynamic, Eigen::Dynamic>
to_matrix(EigMat && x,int m,int n)94 to_matrix(EigMat&& x, int m, int n) {
95 static const char* function = "to_matrix(matrix)";
96 check_size_match(function, "rows * columns", m * n, "vector size", x.size());
97 Eigen::Matrix<value_type_t<EigMat>, Eigen::Dynamic, Eigen::Dynamic> y
98 = std::forward<EigMat>(x);
99 y.resize(m, n);
100 return y;
101 }
102
103 /**
104 * Returns a matrix representation of the vector in column-major
105 * order with the specified number of rows and columns.
106 *
107 * @tparam T type of elements in the vector
108 * @param x vector of values
109 * @param m rows
110 * @param n columns
111 * @return the matrix representation of the input
112 * @throw <code>std::invalid_argument</code>
113 * if the sizes do not match
114 */
115 template <typename T>
to_matrix(const std::vector<T> & x,int m,int n)116 inline auto to_matrix(const std::vector<T>& x, int m, int n) {
117 static const char* function = "to_matrix(array)";
118 check_size_match(function, "rows * columns", m * n, "vector size", x.size());
119 return Eigen::Map<const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>>(
120 &x[0], m, n);
121 }
122
123 /**
124 * Returns a matrix representation of the vector in column-major
125 * order with the specified number of rows and columns.
126 *
127 * @param x vector of values
128 * @param m rows
129 * @param n columns
130 * @return the matrix representation of the input
131 * @throw <code>std::invalid_argument</code>
132 * if the sizes do not match
133 */
to_matrix(const std::vector<int> & x,int m,int n)134 inline Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> to_matrix(
135 const std::vector<int>& x, int m, int n) {
136 static const char* function = "to_matrix(array)";
137 int x_size = x.size();
138 check_size_match(function, "rows * columns", m * n, "vector size", x_size);
139 Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> result(m, n);
140 for (int i = 0; i < x_size; i++) {
141 result.coeffRef(i) = x[i];
142 }
143 return result;
144 }
145
146 /**
147 * Returns a matrix representation of the vector in column-major
148 * order with the specified number of rows and columns.
149 *
150 * @tparam EigMat type of the matrix
151 *
152 * @param x matrix
153 * @param m rows
154 * @param n columns
155 * @param col_major column-major indicator:
156 * if 1, output matrix is transversed in column-major order,
157 * if 0, output matrix is transversed in row-major order,
158 * otherwise function throws std::invalid_argument
159 * @return Reshaped inputted matrix
160 * @throw <code>std::invalid_argument</code>
161 * if the sizes do not match
162 */
163 template <typename EigMat, require_eigen_t<EigMat>* = nullptr>
164 inline Eigen::Matrix<value_type_t<EigMat>, Eigen::Dynamic, Eigen::Dynamic>
to_matrix(EigMat && x,int m,int n,bool col_major)165 to_matrix(EigMat&& x, int m, int n, bool col_major) {
166 if (col_major) {
167 return to_matrix(std::forward<EigMat>(x), m, n);
168 } else {
169 Eigen::Matrix<value_type_t<EigMat>, Eigen::Dynamic, Eigen::Dynamic> res
170 = to_matrix(std::forward<EigMat>(x), n, m);
171 res.transposeInPlace();
172 return res;
173 }
174 }
175
176 /**
177 * Returns a matrix representation of the vector in column-major
178 * order with the specified number of rows and columns.
179 *
180 * @tparam T type of elements in the vector
181 * @param x vector of values
182 * @param m rows
183 * @param n columns
184 * @param col_major column-major indicator:
185 * if 1, output matrix is transversed in column-major order,
186 * if 0, output matrix is transversed in row-major order,
187 * otherwise function throws std::invalid_argument
188 * @return the matrix representation of the input
189 * @throw <code>std::invalid_argument</code>
190 * if the sizes do not match
191 */
192 template <typename T>
193 inline Eigen::Matrix<return_type_t<T, double>, Eigen::Dynamic, Eigen::Dynamic>
to_matrix(const std::vector<T> & x,int m,int n,bool col_major)194 to_matrix(const std::vector<T>& x, int m, int n, bool col_major) {
195 if (col_major) {
196 return to_matrix(x, m, n);
197 }
198 check_size_match("to_matrix", "rows * columns", m * n, "matrix size",
199 x.size());
200 Eigen::Matrix<return_type_t<T, double>, Eigen::Dynamic, Eigen::Dynamic>
201 result(m, n);
202 for (int i = 0, ij = 0; i < m; i++) {
203 for (int j = 0; j < n; j++, ij++) {
204 result.coeffRef(i, j) = x[ij];
205 }
206 }
207 return result;
208 }
209
210 } // namespace math
211 } // namespace stan
212
213 #endif
214