1 #ifndef STAN_MATH_PRIM_FUN_GET_BASE1_HPP
2 #define STAN_MATH_PRIM_FUN_GET_BASE1_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 a reference to the value of the specified vector at the
14  * specified base-one index.  If the index is out of range, throw
15  * a <code>std::out_of_range</code> exception with the specified
16  * error message and index indicated.
17  *
18  * @tparam T type of value
19  * @param x Vector from which to get a value.
20  * @param i Index into vector plus 1.
21  * @param error_msg Error message if the index is out of range.
22  * @param idx Nested index level to report in error message if
23  * the index is out of range.
24  * @return Value of vector at <code>i - 1</code>
25  * @throw std::out_of_range if idx is out of range.
26  */
27 template <typename T>
get_base1(const std::vector<T> & x,size_t i,const char * error_msg,size_t idx)28 inline const T& get_base1(const std::vector<T>& x, size_t i,
29                           const char* error_msg, size_t idx) {
30   check_range("[]", "x", x.size(), i, idx, error_msg);
31   return x[i - 1];
32 }
33 
34 /**
35  * Return a reference to the value of the specified vector at the
36  * specified base-one indexes.  If an index is out of range, throw
37  * a <code>std::out_of_range</code> exception with the specified
38  * error message and index indicated.
39  *
40  * @tparam T type of value
41  * @param x Vector from which to get a value.
42  * @param i1 First index plus 1.
43  * @param i2 Second index plus 1.
44  * @param error_msg Error message if an index is out of range.
45  * @param idx Nested index level to report in error message if
46  * the index is out of range.
47  * @return Value of vector at indexes.
48  * @throw std::out_of_range if idx is out of range.
49  */
50 template <typename T>
get_base1(const std::vector<std::vector<T>> & x,size_t i1,size_t i2,const char * error_msg,size_t idx)51 inline const T& get_base1(const std::vector<std::vector<T> >& x, size_t i1,
52                           size_t i2, const char* error_msg, size_t idx) {
53   check_range("[]", "x", x.size(), i1, idx, error_msg);
54   return get_base1(x[i1 - 1], i2, error_msg, idx + 1);
55 }
56 
57 /**
58  * Return a reference to the value of the specified vector at the
59  * specified base-one indexes.  If an index is out of range, throw
60  * a <code>std::out_of_range</code> exception with the specified
61  * error message and index indicated.
62  *
63  * @tparam T type of value
64  * @param x Vector from which to get a value.
65  * @param i1 First index plus 1.
66  * @param i2 Second index plus 1.
67  * @param i3 Third index plus 1.
68  * @param error_msg Error message if an index is out of range.
69  * @param idx Nested index level to report in error message if
70  * the index is out of range.
71  * @return Value of vector at indexes.
72  * @throw std::out_of_range if idx is out of range.
73  */
74 template <typename T>
get_base1(const std::vector<std::vector<std::vector<T>>> & x,size_t i1,size_t i2,size_t i3,const char * error_msg,size_t idx)75 inline const T& get_base1(const std::vector<std::vector<std::vector<T> > >& x,
76                           size_t i1, size_t i2, size_t i3,
77                           const char* error_msg, size_t idx) {
78   check_range("[]", "x", x.size(), i1, idx, error_msg);
79   return get_base1(x[i1 - 1], i2, i3, error_msg, idx + 1);
80 }
81 
82 /**
83  * Return a reference to the value of the specified vector at the
84  * specified base-one indexes.  If an index is out of range, throw
85  * a <code>std::out_of_range</code> exception with the specified
86  * error message and index indicated.
87  *
88  * @tparam T type of value
89  * @param x Vector from which to get a value.
90  * @param i1 First index plus 1.
91  * @param i2 Second index plus 1.
92  * @param i3 Third index plus 1.
93  * @param i4 Fourth index plus 1.
94  * @param error_msg Error message if an index is out of range.
95  * @param idx Nested index level to report in error message if
96  * the index is out of range.
97  * @return Value of vector at indexes.
98  * @throw std::out_of_range if idx is out of range.
99  */
100 template <typename T>
get_base1(const std::vector<std::vector<std::vector<std::vector<T>>>> & x,size_t i1,size_t i2,size_t i3,size_t i4,const char * error_msg,size_t idx)101 inline const T& get_base1(
102     const std::vector<std::vector<std::vector<std::vector<T> > > >& x,
103     size_t i1, size_t i2, size_t i3, size_t i4, const char* error_msg,
104     size_t idx) {
105   check_range("[]", "x", x.size(), i1, idx, error_msg);
106   return get_base1(x[i1 - 1], i2, i3, i4, error_msg, idx + 1);
107 }
108 
109 /**
110  * Return a reference to the value of the specified vector at the
111  * specified base-one indexes.  If an index is out of range, throw
112  * a <code>std::out_of_range</code> exception with the specified
113  * error message and index indicated.
114  *
115  * @tparam T type of value
116  * @param x Vector from which to get a value.
117  * @param i1 First index plus 1.
118  * @param i2 Second index plus 1.
119  * @param i3 Third index plus 1.
120  * @param i4 Fourth index plus 1.
121  * @param i5 Fifth index plus 1.
122  * @param error_msg Error message if an index is out of range.
123  * @param idx Nested index level to report in error message if
124  * the index is out of range.
125  * @return Value of vector at indexes.
126  * @throw std::out_of_range if idx is out of range.
127  */
128 template <typename T>
get_base1(const std::vector<std::vector<std::vector<std::vector<std::vector<T>>>>> & x,size_t i1,size_t i2,size_t i3,size_t i4,size_t i5,const char * error_msg,size_t idx)129 inline const T& get_base1(
130     const std::vector<
131         std::vector<std::vector<std::vector<std::vector<T> > > > >& x,
132     size_t i1, size_t i2, size_t i3, size_t i4, size_t i5,
133     const char* error_msg, size_t idx) {
134   check_range("[]", "x", x.size(), i1, idx, error_msg);
135   return get_base1(x[i1 - 1], i2, i3, i4, i5, error_msg, idx + 1);
136 }
137 
138 /**
139  * Return a reference to the value of the specified vector at the
140  * specified base-one indexes.  If an index is out of range, throw
141  * a <code>std::out_of_range</code> exception with the specified
142  * error message and index indicated.
143  *
144  * @tparam T type of value
145  * @param x Vector from which to get a value.
146  * @param i1 First index plus 1.
147  * @param i2 Second index plus 1.
148  * @param i3 Third index plus 1.
149  * @param i4 Fourth index plus 1.
150  * @param i5 Fifth index plus 1.
151  * @param i6 Sixth index plus 1.
152  * @param error_msg Error message if an index is out of range.
153  * @param idx Nested index level to report in error message if
154  * the index is out of range.
155  * @return Value of vector at indexes.
156  * @throw std::out_of_range if idx is out of range.
157  */
158 template <typename T>
get_base1(const std::vector<std::vector<std::vector<std::vector<std::vector<std::vector<T>>>>>> & x,size_t i1,size_t i2,size_t i3,size_t i4,size_t i5,size_t i6,const char * error_msg,size_t idx)159 inline const T& get_base1(
160     const std::vector<std::vector<
161         std::vector<std::vector<std::vector<std::vector<T> > > > > >& x,
162     size_t i1, size_t i2, size_t i3, size_t i4, size_t i5, size_t i6,
163     const char* error_msg, size_t idx) {
164   check_range("[]", "x", x.size(), i1, idx, error_msg);
165   return get_base1(x[i1 - 1], i2, i3, i4, i5, i6, error_msg, idx + 1);
166 }
167 
168 /**
169  * Return a reference to the value of the specified vector at the
170  * specified base-one indexes.  If an index is out of range, throw
171  * a <code>std::out_of_range</code> exception with the specified
172  * error message and index indicated.
173  *
174  * @tparam T type of value
175  * @param x Vector from which to get a value.
176  * @param i1 First index plus 1.
177  * @param i2 Second index plus 1.
178  * @param i3 Third index plus 1.
179  * @param i4 Fourth index plus 1.
180  * @param i5 Fifth index plus 1.
181  * @param i6 Sixth index plus 1.
182  * @param i7 Seventh index plus 1.
183  * @param error_msg Error message if an index is out of range.
184  * @param idx Nested index level to report in error message if
185  * the index is out of range.
186  * @return Value of vector at indexes.
187  * @throw std::out_of_range if idx is out of range.
188  */
189 template <typename T>
get_base1(const std::vector<std::vector<std::vector<std::vector<std::vector<std::vector<std::vector<T>>>>>>> & x,size_t i1,size_t i2,size_t i3,size_t i4,size_t i5,size_t i6,size_t i7,const char * error_msg,size_t idx)190 inline const T& get_base1(
191     const std::vector<std::vector<std::vector<
192         std::vector<std::vector<std::vector<std::vector<T> > > > > > >& x,
193     size_t i1, size_t i2, size_t i3, size_t i4, size_t i5, size_t i6, size_t i7,
194     const char* error_msg, size_t idx) {
195   check_range("[]", "x", x.size(), i1, idx, error_msg);
196   return get_base1(x[i1 - 1], i2, i3, i4, i5, i6, i7, error_msg, idx + 1);
197 }
198 
199 /**
200  * Return a reference to the value of the specified vector at the
201  * specified base-one indexes.  If an index is out of range, throw
202  * a <code>std::out_of_range</code> exception with the specified
203  * error message and index indicated.
204  *
205  * @tparam T type of value
206  * @param x Vector from which to get a value.
207  * @param i1 First index plus 1.
208  * @param i2 Second index plus 1.
209  * @param i3 Third index plus 1.
210  * @param i4 Fourth index plus 1.
211  * @param i5 Fifth index plus 1.
212  * @param i6 Sixth index plus 1.
213  * @param i7 Seventh index plus 1.
214  * @param i8 Eigth index plus 1.
215  * @param error_msg Error message if an index is out of range.
216  * @param idx Nested index level to report in error message if
217  * the index is out of range.
218  * @return Value of vector at indexes.
219  * @throw std::out_of_range if idx is out of range.
220  */
221 template <typename T>
get_base1(const std::vector<std::vector<std::vector<std::vector<std::vector<std::vector<std::vector<std::vector<T>>>>>>>> & x,size_t i1,size_t i2,size_t i3,size_t i4,size_t i5,size_t i6,size_t i7,size_t i8,const char * error_msg,size_t idx)222 inline const T& get_base1(
223     const std::vector<std::vector<std::vector<std::vector<
224         std::vector<std::vector<std::vector<std::vector<T> > > > > > > >& x,
225     size_t i1, size_t i2, size_t i3, size_t i4, size_t i5, size_t i6, size_t i7,
226     size_t i8, const char* error_msg, size_t idx) {
227   check_range("[]", "x", x.size(), i1, idx, error_msg);
228   return get_base1(x[i1 - 1], i2, i3, i4, i5, i6, i7, i8, error_msg, idx + 1);
229 }
230 
231 /**
232  * Return a copy of the row of the specified matrix at the specified
233  * base-one row index.  If the index is out of range, throw a
234  * <code>std::out_of_range</code> exception with the specified
235  * error message and index indicated.
236  *
237  * <b>Warning</b>:  Because a copy is involved, it is inefficient
238  * to access element of matrices by first using this method
239  * to get a row then using a second call to get the value at
240  a specified column.
241  *
242  * @tparam EigMat type of the matrix
243  * @param x Matrix from which to get a row
244  * @param m Index into matrix plus 1.
245  * @param error_msg Error message if the index is out of range.
246  * @param idx Nested index level to report in error message if
247  * the index is out of range.
248  * @return Row of matrix at <code>i - 1</code>.
249  * @throw std::out_of_range if idx is out of range.
250  */
251 template <typename EigMat, require_eigen_t<EigMat>* = nullptr,
252           require_not_eigen_vector_t<EigMat>* = nullptr>
get_base1(const EigMat & x,size_t m,const char * error_msg,size_t idx)253 inline Eigen::Matrix<value_type_t<EigMat>, 1, Eigen::Dynamic> get_base1(
254     const EigMat& x, size_t m, const char* error_msg, size_t idx) {
255   check_range("[]", "rows of x", x.rows(), m, idx, error_msg);
256   return x.row(m - 1);
257 }
258 
259 /**
260  * Return a reference to the value of the specified matrix at the specified
261  * base-one row and column indexes.  If either index is out of range,
262  * throw a <code>std::out_of_range</code> exception with the
263  * specified error message and index indicated.
264  *
265  * @tparam EigMat type of the matrix
266  * @param x Matrix from which to get a row
267  * @param m Row index plus 1.
268  * @param n Column index plus 1.
269  * @param error_msg Error message if either index is out of range.
270  * @param idx Nested index level to report in error message if
271  * either index is out of range.
272  * @return Value of matrix at row <code>m - 1</code> and column
273  * <code>n - 1</code>.
274  * @throw std::out_of_range if idx is out of range.
275  */
276 template <typename EigMat, require_eigen_t<EigMat>* = nullptr>
get_base1(const EigMat & x,size_t m,size_t n,const char * error_msg,size_t idx)277 inline const value_type_t<EigMat>& get_base1(const EigMat& x, size_t m,
278                                              size_t n, const char* error_msg,
279                                              size_t idx) {
280   check_range("[]", "rows of x", x.rows(), m, idx, error_msg);
281   check_range("[]", "cols of x", x.cols(), n, idx + 1, error_msg);
282   return x.coeff(m - 1, n - 1);
283 }
284 
285 /**
286  * Return a reference to the value of the specified Eigen vector
287  * at the specified base-one index.  If the index is out of range,
288  * throw a <code>std::out_of_range</code> exception with the
289  * specified error message and index indicated.
290  *
291  * @tparam EigVec type of the vector
292  * @param x Eigen vector from which to get a value.
293  * @param m Row index plus 1.
294  * @param error_msg Error message if the index is out of range.
295  * @param idx Nested index level to report in error message if
296  * the index is out of range.
297  * @return Value of Eigen vector at row <code>m - 1</code>.
298  * @throw std::out_of_range if idx is out of range.
299  */
300 template <typename EigVec, require_eigen_vector_t<EigVec>* = nullptr>
get_base1(const EigVec & x,size_t m,const char * error_msg,size_t idx)301 inline const value_type_t<EigVec>& get_base1(const EigVec& x, size_t m,
302                                              const char* error_msg,
303                                              size_t idx) {
304   check_range("[]", "x", x.size(), m, idx, error_msg);
305   return x.coeff(m - 1);
306 }
307 
308 }  // namespace math
309 }  // namespace stan
310 
311 #endif
312