1 #include <stan/math/mix.hpp>
2 #include <gtest/gtest.h>
3 #include <vector>
4 
TEST(AgradMixMatrixGetBase1LHS,failing_pre_20_fv)5 TEST(AgradMixMatrixGetBase1LHS, failing_pre_20_fv) {
6   using Eigen::Dynamic;
7   using Eigen::Matrix;
8   using stan::math::fvar;
9   using stan::math::get_base1_lhs;
10   using stan::math::var;
11   Matrix<fvar<var>, Dynamic, 1> y(3);
12   y << 1, 2, 3;
13   fvar<var> z = get_base1_lhs(y, 1, "y", 1);
14   EXPECT_FLOAT_EQ(1, z.val_.val());
15 }
TEST(AgradMixMatrixGetBase1LHS,get_base1_lhs_vec1_fv)16 TEST(AgradMixMatrixGetBase1LHS, get_base1_lhs_vec1_fv) {
17   using stan::math::fvar;
18   using stan::math::get_base1_lhs;
19   using stan::math::var;
20   std::vector<fvar<var> > x(2);
21   x[0] = 10.0;
22   x[1] = 20.0;
23   EXPECT_FLOAT_EQ(10.0, get_base1_lhs(x, 1, "x[1]", 0).val_.val());
24   EXPECT_FLOAT_EQ(20.0, get_base1_lhs(x, 2, "x[1]", 0).val_.val());
25 
26   get_base1_lhs(x, 2, "x[2]", 0) = 5.0;
27   EXPECT_FLOAT_EQ(5.0, get_base1_lhs(x, 2, "x[1]", 0).val_.val());
28 
29   EXPECT_THROW(get_base1_lhs(x, 0, "x[0]", 0), std::out_of_range);
30   EXPECT_THROW(get_base1_lhs(x, 3, "x[3]", 0), std::out_of_range);
31 }
TEST(AgradMixMatrixGetBase1LHS,get_base1_lhs_vec2_fv)32 TEST(AgradMixMatrixGetBase1LHS, get_base1_lhs_vec2_fv) {
33   using stan::math::fvar;
34   using stan::math::get_base1_lhs;
35   using stan::math::var;
36   using std::vector;
37   size_t M = 3;
38   size_t N = 4;
39 
40   vector<vector<fvar<var> > > x(M, vector<fvar<var> >(N, 0.0));
41 
42   for (size_t m = 1; m <= M; ++m)
43     for (size_t n = 1; n <= N; ++n)
44       x[m - 1][n - 1] = (m * 10) + n;
45 
46   for (size_t m = 1; m <= M; ++m) {
47     for (size_t n = 1; n <= N; ++n) {
48       fvar<var> expected = x[m - 1][n - 1];
49       fvar<var> found
50           = get_base1_lhs(get_base1_lhs(x, m, "x[m]", 1), n, "x[m][n]", 2);
51       EXPECT_FLOAT_EQ(expected.val_.val(), found.val_.val());
52     }
53   }
54 
55   get_base1_lhs(get_base1_lhs(x, 1, "", -1), 2, "", -1) = 112.5;
56   EXPECT_FLOAT_EQ(112.5, x[0][1].val_.val());
57 
58   EXPECT_THROW(get_base1_lhs(x, 0, "", -1), std::out_of_range);
59   EXPECT_THROW(get_base1_lhs(x, M + 1, "", -1), std::out_of_range);
60 
61   EXPECT_THROW(get_base1_lhs(get_base1_lhs(x, 1, "", -1), 12, "", -1),
62                std::out_of_range);
63 }
TEST(AgradMixMatrixGetBase1LHS,get_base1_lhs_matrix_fv)64 TEST(AgradMixMatrixGetBase1LHS, get_base1_lhs_matrix_fv) {
65   using Eigen::Dynamic;
66   using Eigen::Matrix;
67   using stan::math::fvar;
68   using stan::math::get_base1_lhs;
69   using stan::math::var;
70   Matrix<fvar<var>, Dynamic, Dynamic> x(4, 3);
71   for (size_t i = 0; i < 4; ++i)
72     for (size_t j = 0; j < 3; ++j)
73       x(i, j) = i * j;
74   for (size_t i = 0; i < 4; ++i) {
75     for (size_t j = 0; j < 3; ++j) {
76       EXPECT_FLOAT_EQ(x(i, j).val_.val(),
77                       get_base1_lhs(x, i + 1, j + 1, "x", 1).val_.val());
78       EXPECT_FLOAT_EQ(x(i, j).val_.val(),
79                       get_base1_lhs(x, i + 1, "x", 1)(0, j).val_.val());
80       Matrix<fvar<var>, 1, Dynamic> xi
81           = get_base1_lhs<fvar<var> >(x, i + 1, "x", 1);
82       EXPECT_FLOAT_EQ(x(i, j).val_.val(), xi[j].val_.val());
83       EXPECT_FLOAT_EQ(x(i, j).val_.val(),
84                       get_base1_lhs(xi, j + 1, "xi", 2).val_.val());
85       // this is no good because can't get ref to inside val
86       // could remedy by adding const versions, but don't need for Stan GM
87       // fvar<var>  xij = get_base1_lhs<fvar<var> >
88       //                        (get_base1_lhs<fvar<var> >(x, i+1, "x", 1),
89       //                                j+1, "xi", 2);
90     }
91   }
92   EXPECT_THROW(get_base1_lhs(x, 10, "x", 1), std::out_of_range);
93   EXPECT_THROW(get_base1_lhs(x, 0, "x", 1), std::out_of_range);
94   EXPECT_THROW(get_base1_lhs(x, 100, 1, "x", 1), std::out_of_range);
95   EXPECT_THROW(get_base1_lhs(x, 1, 100, "x", 1), std::out_of_range);
96   EXPECT_THROW(get_base1_lhs(x, 0, 1, "x", 1), std::out_of_range);
97   EXPECT_THROW(get_base1_lhs(x, 1, 0, "x", 1), std::out_of_range);
98 }
TEST(AgradMixMatrixGetBase1LHS,get_base1_lhs_vector_fv)99 TEST(AgradMixMatrixGetBase1LHS, get_base1_lhs_vector_fv) {
100   using Eigen::Dynamic;
101   using Eigen::Matrix;
102   using stan::math::fvar;
103   using stan::math::get_base1_lhs;
104   using stan::math::var;
105   Matrix<fvar<var>, 1, Dynamic> x(3);
106   x << 1, 2, 3;
107 
108   for (size_t i = 0; i < 3; ++i)
109     EXPECT_FLOAT_EQ(x(i).val_.val(),
110                     get_base1_lhs(x, i + 1, "x", 1).val_.val());
111   EXPECT_THROW(get_base1_lhs(x, 0, "x", 1), std::out_of_range);
112   EXPECT_THROW(get_base1_lhs(x, 100, "x", 1), std::out_of_range);
113 }
TEST(AgradMixMatrixGetBase1LHS,get_base1_lhs_row_vector_fv)114 TEST(AgradMixMatrixGetBase1LHS, get_base1_lhs_row_vector_fv) {
115   using Eigen::Dynamic;
116   using Eigen::Matrix;
117   using stan::math::fvar;
118   using stan::math::get_base1_lhs;
119   using stan::math::var;
120   Matrix<fvar<var>, Dynamic, 1> x(3);
121   x << 1, 2, 3;
122 
123   for (size_t i = 0; i < 3; ++i)
124     EXPECT_FLOAT_EQ(x(i).val_.val(),
125                     get_base1_lhs(x, i + 1, "x", 1).val_.val());
126   EXPECT_THROW(get_base1_lhs(x, 0, "x", 1), std::out_of_range);
127   EXPECT_THROW(get_base1_lhs(x, 100, "x", 1), std::out_of_range);
128 }
TEST(AgradMixMatrixGetBase1LHS,get_base1_lhs_8_fv)129 TEST(AgradMixMatrixGetBase1LHS, get_base1_lhs_8_fv) {
130   using stan::math::fvar;
131   using stan::math::get_base1_lhs;
132   using stan::math::var;
133   using std::vector;
134   fvar<var> x0(42.0);
135   // ~ 4m entries ~ 32MB memory + sizes
136   vector<fvar<var> > x1(9, x0);
137   vector<vector<fvar<var> > > x2(8, x1);
138   vector<vector<vector<fvar<var> > > > x3(7, x2);
139   vector<vector<vector<vector<fvar<var> > > > > x4(6, x3);
140   vector<vector<vector<vector<vector<fvar<var> > > > > > x5(5, x4);
141   vector<vector<vector<vector<vector<vector<fvar<var> > > > > > > x6(4, x5);
142   vector<vector<vector<vector<vector<vector<vector<fvar<var> > > > > > > > x7(
143       3, x6);
144   vector<
145       vector<vector<vector<vector<vector<vector<vector<fvar<var> > > > > > > > >
146       x8(2, x7);
147 
148   EXPECT_EQ(x0.val_.val(), x8[0][0][0][0][0][0][0][0].val_.val());
149 
150   for (size_t i1 = 0; i1 < x8.size(); ++i1)
151     for (size_t i2 = 0; i2 < x8[0].size(); ++i2)
152       for (size_t i3 = 0; i3 < x8[0][0].size(); ++i3)
153         for (size_t i4 = 0; i4 < x8[0][0][0].size(); ++i4)
154           for (size_t i5 = 0; i5 < x8[0][0][0][0].size(); ++i5)
155             for (size_t i6 = 0; i6 < x8[0][0][0][0][0].size(); ++i6)
156               for (size_t i7 = 0; i7 < x8[0][0][0][0][0][0].size(); ++i7)
157                 for (size_t i8 = 0; i8 < x8[0][0][0][0][0][0][0].size(); ++i8)
158                   x8[i1][i2][i3][i4][i5][i6][i7][i8]
159                       = i1 * i2 * i3 * i4 * i5 * i6 * i7 * i8;
160 
161   for (size_t i1 = 0; i1 < x8.size(); ++i1)
162     for (size_t i2 = 0; i2 < x8[0].size(); ++i2)
163       for (size_t i3 = 0; i3 < x8[0][0].size(); ++i3)
164         for (size_t i4 = 0; i4 < x8[0][0][0].size(); ++i4)
165           for (size_t i5 = 0; i5 < x8[0][0][0][0].size(); ++i5)
166             for (size_t i6 = 0; i6 < x8[0][0][0][0][0].size(); ++i6)
167               for (size_t i7 = 0; i7 < x8[0][0][0][0][0][0].size(); ++i7)
168                 for (size_t i8 = 0; i8 < x8[0][0][0][0][0][0][0].size(); ++i8)
169                   EXPECT_FLOAT_EQ(
170                       x8[i1][i2][i3][i4][i5][i6][i7][i8].val_.val(),
171                       get_base1_lhs(x8, i1 + 1, i2 + 1, i3 + 1, i4 + 1, i5 + 1,
172                                     i6 + 1, i7 + 1, i8 + 1, "x8", 1)
173                           .val_.val());
174 }
TEST(AgradMixMatrixGetBase1LHS,failing_pre_20_ffv)175 TEST(AgradMixMatrixGetBase1LHS, failing_pre_20_ffv) {
176   using Eigen::Dynamic;
177   using Eigen::Matrix;
178   using stan::math::fvar;
179   using stan::math::get_base1_lhs;
180   using stan::math::var;
181   Matrix<fvar<fvar<var> >, Dynamic, 1> y(3);
182   y << 1, 2, 3;
183   fvar<fvar<var> > z = get_base1_lhs(y, 1, "y", 1);
184   EXPECT_FLOAT_EQ(1, z.val_.val_.val());
185 }
TEST(AgradMixMatrixGetBase1LHS,get_base1_lhs_vec1_ffv)186 TEST(AgradMixMatrixGetBase1LHS, get_base1_lhs_vec1_ffv) {
187   using stan::math::fvar;
188   using stan::math::get_base1_lhs;
189   using stan::math::var;
190   std::vector<fvar<fvar<var> > > x(2);
191   x[0] = 10.0;
192   x[1] = 20.0;
193   EXPECT_FLOAT_EQ(10.0, get_base1_lhs(x, 1, "x[1]", 0).val_.val_.val());
194   EXPECT_FLOAT_EQ(20.0, get_base1_lhs(x, 2, "x[1]", 0).val_.val_.val());
195 
196   get_base1_lhs(x, 2, "x[2]", 0) = 5.0;
197   EXPECT_FLOAT_EQ(5.0, get_base1_lhs(x, 2, "x[1]", 0).val_.val_.val());
198 
199   EXPECT_THROW(get_base1_lhs(x, 0, "x[0]", 0), std::out_of_range);
200   EXPECT_THROW(get_base1_lhs(x, 3, "x[3]", 0), std::out_of_range);
201 }
TEST(AgradMixMatrixGetBase1LHS,get_base1_lhs_vec2_ffv)202 TEST(AgradMixMatrixGetBase1LHS, get_base1_lhs_vec2_ffv) {
203   using stan::math::fvar;
204   using stan::math::get_base1_lhs;
205   using stan::math::var;
206   using std::vector;
207   size_t M = 3;
208   size_t N = 4;
209 
210   vector<vector<fvar<fvar<var> > > > x(M, vector<fvar<fvar<var> > >(N, 0.0));
211 
212   for (size_t m = 1; m <= M; ++m)
213     for (size_t n = 1; n <= N; ++n)
214       x[m - 1][n - 1] = (m * 10) + n;
215 
216   for (size_t m = 1; m <= M; ++m) {
217     for (size_t n = 1; n <= N; ++n) {
218       fvar<fvar<var> > expected = x[m - 1][n - 1];
219       fvar<fvar<var> > found
220           = get_base1_lhs(get_base1_lhs(x, m, "x[m]", 1), n, "x[m][n]", 2);
221       EXPECT_FLOAT_EQ(expected.val_.val_.val(), found.val_.val_.val());
222     }
223   }
224 
225   get_base1_lhs(get_base1_lhs(x, 1, "", -1), 2, "", -1) = 112.5;
226   EXPECT_FLOAT_EQ(112.5, x[0][1].val_.val_.val());
227 
228   EXPECT_THROW(get_base1_lhs(x, 0, "", -1), std::out_of_range);
229   EXPECT_THROW(get_base1_lhs(x, M + 1, "", -1), std::out_of_range);
230 
231   EXPECT_THROW(get_base1_lhs(get_base1_lhs(x, 1, "", -1), 12, "", -1),
232                std::out_of_range);
233 }
TEST(AgradMixMatrixGetBase1LHS,get_base1_lhs_matrix_ffv)234 TEST(AgradMixMatrixGetBase1LHS, get_base1_lhs_matrix_ffv) {
235   using Eigen::Dynamic;
236   using Eigen::Matrix;
237   using stan::math::fvar;
238   using stan::math::get_base1_lhs;
239   using stan::math::var;
240   Matrix<fvar<fvar<var> >, Dynamic, Dynamic> x(4, 3);
241   for (size_t i = 0; i < 4; ++i)
242     for (size_t j = 0; j < 3; ++j)
243       x(i, j) = i * j;
244   for (size_t i = 0; i < 4; ++i) {
245     for (size_t j = 0; j < 3; ++j) {
246       EXPECT_FLOAT_EQ(x(i, j).val_.val_.val(),
247                       get_base1_lhs(x, i + 1, j + 1, "x", 1).val_.val_.val());
248       EXPECT_FLOAT_EQ(x(i, j).val_.val_.val(),
249                       get_base1_lhs(x, i + 1, "x", 1)(0, j).val_.val_.val());
250       Matrix<fvar<fvar<var> >, 1, Dynamic> xi
251           = get_base1_lhs<fvar<fvar<var> > >(x, i + 1, "x", 1);
252       EXPECT_FLOAT_EQ(x(i, j).val_.val_.val(), xi[j].val_.val_.val());
253       EXPECT_FLOAT_EQ(x(i, j).val_.val_.val(),
254                       get_base1_lhs(xi, j + 1, "xi", 2).val_.val_.val());
255       // this is no good because can't get ref to inside val
256       // could remedy by adding const versions, but don't need for Stan GM
257       // fvar<fvar<var> >  xij = get_base1_lhs<fvar< fvar<var> > >
258       //                          (get_base1_lhs<fvar<fvar<var> > >
259       //                                (x, i+1, "x", 1),
260       //                                j+1, "xi", 2);
261     }
262   }
263   EXPECT_THROW(get_base1_lhs(x, 10, "x", 1), std::out_of_range);
264   EXPECT_THROW(get_base1_lhs(x, 0, "x", 1), std::out_of_range);
265   EXPECT_THROW(get_base1_lhs(x, 100, 1, "x", 1), std::out_of_range);
266   EXPECT_THROW(get_base1_lhs(x, 1, 100, "x", 1), std::out_of_range);
267   EXPECT_THROW(get_base1_lhs(x, 0, 1, "x", 1), std::out_of_range);
268   EXPECT_THROW(get_base1_lhs(x, 1, 0, "x", 1), std::out_of_range);
269 }
TEST(AgradMixMatrixGetBase1LHS,get_base1_lhs_vector_ffv)270 TEST(AgradMixMatrixGetBase1LHS, get_base1_lhs_vector_ffv) {
271   using Eigen::Dynamic;
272   using Eigen::Matrix;
273   using stan::math::fvar;
274   using stan::math::get_base1_lhs;
275   using stan::math::var;
276   Matrix<fvar<fvar<var> >, 1, Dynamic> x(3);
277   x << 1, 2, 3;
278 
279   for (size_t i = 0; i < 3; ++i)
280     EXPECT_FLOAT_EQ(x(i).val_.val_.val(),
281                     get_base1_lhs(x, i + 1, "x", 1).val_.val_.val());
282   EXPECT_THROW(get_base1_lhs(x, 0, "x", 1), std::out_of_range);
283   EXPECT_THROW(get_base1_lhs(x, 100, "x", 1), std::out_of_range);
284 }
TEST(AgradMixMatrixGetBase1LHS,get_base1_lhs_row_vector_ffv)285 TEST(AgradMixMatrixGetBase1LHS, get_base1_lhs_row_vector_ffv) {
286   using Eigen::Dynamic;
287   using Eigen::Matrix;
288   using stan::math::fvar;
289   using stan::math::get_base1_lhs;
290   using stan::math::var;
291   Matrix<fvar<fvar<var> >, Dynamic, 1> x(3);
292   x << 1, 2, 3;
293 
294   for (size_t i = 0; i < 3; ++i)
295     EXPECT_FLOAT_EQ(x(i).val_.val_.val(),
296                     get_base1_lhs(x, i + 1, "x", 1).val_.val_.val());
297   EXPECT_THROW(get_base1_lhs(x, 0, "x", 1), std::out_of_range);
298   EXPECT_THROW(get_base1_lhs(x, 100, "x", 1), std::out_of_range);
299 }
TEST(AgradMixMatrixGetBase1LHS,get_base1_lhs_8_ffv)300 TEST(AgradMixMatrixGetBase1LHS, get_base1_lhs_8_ffv) {
301   using stan::math::fvar;
302   using stan::math::get_base1_lhs;
303   using stan::math::var;
304   using std::vector;
305   fvar<fvar<var> > x0(42.0);
306   // ~ 4m entries ~ 32MB memory + sizes
307   vector<fvar<fvar<var> > > x1(9, x0);
308   vector<vector<fvar<fvar<var> > > > x2(8, x1);
309   vector<vector<vector<fvar<fvar<var> > > > > x3(7, x2);
310   vector<vector<vector<vector<fvar<fvar<var> > > > > > x4(6, x3);
311   vector<vector<vector<vector<vector<fvar<fvar<var> > > > > > > x5(5, x4);
312   vector<vector<vector<vector<vector<vector<fvar<fvar<var> > > > > > > > x6(4,
313                                                                             x5);
314   vector<
315       vector<vector<vector<vector<vector<vector<fvar<fvar<var> > > > > > > > >
316       x7(3, x6);
317   vector<vector<
318       vector<vector<vector<vector<vector<vector<fvar<fvar<var> > > > > > > > > >
319       x8(2, x7);
320 
321   EXPECT_EQ(x0.val_.val_.val(), x8[0][0][0][0][0][0][0][0].val_.val_.val());
322 
323   for (size_t i1 = 0; i1 < x8.size(); ++i1)
324     for (size_t i2 = 0; i2 < x8[0].size(); ++i2)
325       for (size_t i3 = 0; i3 < x8[0][0].size(); ++i3)
326         for (size_t i4 = 0; i4 < x8[0][0][0].size(); ++i4)
327           for (size_t i5 = 0; i5 < x8[0][0][0][0].size(); ++i5)
328             for (size_t i6 = 0; i6 < x8[0][0][0][0][0].size(); ++i6)
329               for (size_t i7 = 0; i7 < x8[0][0][0][0][0][0].size(); ++i7)
330                 for (size_t i8 = 0; i8 < x8[0][0][0][0][0][0][0].size(); ++i8)
331                   x8[i1][i2][i3][i4][i5][i6][i7][i8]
332                       = i1 * i2 * i3 * i4 * i5 * i6 * i7 * i8;
333 
334   for (size_t i1 = 0; i1 < x8.size(); ++i1)
335     for (size_t i2 = 0; i2 < x8[0].size(); ++i2)
336       for (size_t i3 = 0; i3 < x8[0][0].size(); ++i3)
337         for (size_t i4 = 0; i4 < x8[0][0][0].size(); ++i4)
338           for (size_t i5 = 0; i5 < x8[0][0][0][0].size(); ++i5)
339             for (size_t i6 = 0; i6 < x8[0][0][0][0][0].size(); ++i6)
340               for (size_t i7 = 0; i7 < x8[0][0][0][0][0][0].size(); ++i7)
341                 for (size_t i8 = 0; i8 < x8[0][0][0][0][0][0][0].size(); ++i8)
342                   EXPECT_FLOAT_EQ(
343                       x8[i1][i2][i3][i4][i5][i6][i7][i8].val_.val_.val(),
344                       get_base1_lhs(x8, i1 + 1, i2 + 1, i3 + 1, i4 + 1, i5 + 1,
345                                     i6 + 1, i7 + 1, i8 + 1, "x8", 1)
346                           .val_.val_.val());
347 }
348