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