1 #include <stan/io/deserializer.hpp>
2 #include <stan/io/serializer.hpp>
3 // expect_near_rel comes from lib/stan_math
4 #include <test/unit/math/expect_near_rel.hpp>
5 #include <gtest/gtest.h>
6 
TEST(serializer_scalar,write)7 TEST(serializer_scalar, write) {
8   std::vector<double> theta(2, 0.0);
9   double x = 4.0;
10   double y = 6.0;
11   stan::io::serializer<double> serializer(theta);
12   serializer.write(x);
13   EXPECT_FLOAT_EQ(x, theta[0]);
14   serializer.write(y);
15   EXPECT_FLOAT_EQ(y, theta[1]);
16   EXPECT_EQ(0U, serializer.available());
17   EXPECT_THROW(serializer.write(4), std::runtime_error);
18 }
19 
TEST(serializer_scalar,complex_write)20 TEST(serializer_scalar, complex_write) {
21   std::vector<double> theta(4, 0.0);
22   stan::io::serializer<double> serializer(theta);
23   std::complex<double> x = std::complex<double>(5.0, 6.0);
24   std::complex<double> y = std::complex<double>(7.0, 8.0);
25 
26   serializer.write(x);
27   EXPECT_FLOAT_EQ(x.real(), theta[0]);
28   EXPECT_FLOAT_EQ(x.imag(), theta[1]);
29   serializer.write(y);
30   EXPECT_FLOAT_EQ(y.real(), theta[2]);
31   EXPECT_FLOAT_EQ(y.imag(), theta[3]);
32   EXPECT_EQ(0U, serializer.available());
33   EXPECT_THROW(serializer.write(4), std::runtime_error);
34 }
35 
36 // vector
37 
TEST(serializer_vector,write)38 TEST(serializer_vector, write) {
39   std::vector<double> theta(10, 0.0);
40   Eigen::VectorXd x(10);
41   for (size_t i = 0; i < 10U; ++i) {
42     x.coeffRef(i) = -static_cast<double>(i);
43   }
44   stan::io::serializer<double> serializer(theta);
45   serializer.write(x);
46   for (size_t i = 0; i < 10U; ++i) {
47     EXPECT_FLOAT_EQ(theta[i], x[i]);
48   }
49   EXPECT_THROW(serializer.write(4), std::runtime_error);
50 }
51 
TEST(serializer_vector,complex_write)52 TEST(serializer_vector, complex_write) {
53   std::vector<double> theta(20, 0.0);
54   Eigen::Matrix<std::complex<double>, -1, 1> x(10);
55   for (size_t i = 0; i < 10U; ++i) {
56     x.coeffRef(i) = std::complex<double>(-static_cast<double>(i),
57                                          -static_cast<double>(i + 1));
58   }
59 
60   stan::io::serializer<double> serializer(theta);
61   serializer.write(x);
62   Eigen::Index sentinal = 0;
63   for (size_t i = 0; i < 20U; i += 2) {
64     EXPECT_FLOAT_EQ(theta[i], x[sentinal].real());
65     EXPECT_FLOAT_EQ(theta[i + 1], x[sentinal].imag());
66     ++sentinal;
67   }
68   EXPECT_THROW(serializer.write(4), std::runtime_error);
69 }
70 
71 // row vector
72 
TEST(serializer_rowvector,write)73 TEST(serializer_rowvector, write) {
74   std::vector<double> theta(10, 0.0);
75   Eigen::RowVectorXd x(10);
76   for (size_t i = 0; i < 10U; ++i) {
77     x.coeffRef(i) = -static_cast<double>(i);
78   }
79   stan::io::serializer<double> serializer(theta);
80   serializer.write(x);
81   for (size_t i = 0; i < 10U; ++i) {
82     EXPECT_FLOAT_EQ(theta[i], x[i]);
83   }
84   EXPECT_THROW(serializer.write(4), std::runtime_error);
85 }
86 
TEST(serializer_rowvector,complex_write)87 TEST(serializer_rowvector, complex_write) {
88   std::vector<double> theta(20, 0.0);
89   Eigen::Matrix<std::complex<double>, 1, -1> x(10);
90   for (size_t i = 0; i < 10U; ++i) {
91     x.coeffRef(i) = std::complex<double>(-static_cast<double>(i),
92                                          -static_cast<double>(i + 1));
93   }
94 
95   stan::io::serializer<double> serializer(theta);
96   serializer.write(x);
97   Eigen::Index sentinal = 0;
98   for (size_t i = 0; i < 20U; i += 2) {
99     EXPECT_FLOAT_EQ(theta[i], x[sentinal].real());
100     EXPECT_FLOAT_EQ(theta[i + 1], x[sentinal].imag());
101     ++sentinal;
102   }
103   EXPECT_THROW(serializer.write(4), std::runtime_error);
104 }
105 
106 // matrix
107 
TEST(serializer_matrix,write)108 TEST(serializer_matrix, write) {
109   std::vector<double> theta(16, 0.0);
110   Eigen::MatrixXd x(4, 4);
111   for (size_t i = 0; i < 16U; ++i) {
112     x.coeffRef(i) = -static_cast<double>(i);
113   }
114   stan::io::serializer<double> serializer(theta);
115   serializer.write(x);
116   for (size_t i = 0; i < 16U; ++i) {
117     EXPECT_FLOAT_EQ(theta[i], x(i));
118   }
119   EXPECT_THROW(serializer.write(4), std::runtime_error);
120 }
121 
TEST(serializer_matrix,complex_write)122 TEST(serializer_matrix, complex_write) {
123   std::vector<double> theta(32, 0.0);
124   Eigen::Matrix<std::complex<double>, -1, -1> x(4, 4);
125   for (size_t i = 0; i < 16U; ++i) {
126     x.coeffRef(i) = std::complex<double>(-static_cast<double>(i),
127                                          -static_cast<double>(i + 1));
128   }
129 
130   stan::io::serializer<double> serializer(theta);
131   serializer.write(x);
132   Eigen::Index sentinal = 0;
133   for (size_t i = 0; i < 32U; i += 2) {
134     EXPECT_FLOAT_EQ(theta[i], x(sentinal).real());
135     EXPECT_FLOAT_EQ(theta[i + 1], x(sentinal).imag());
136     ++sentinal;
137   }
138   EXPECT_THROW(serializer.write(4), std::runtime_error);
139 }
140 
141 // array
142 
TEST(serializer_stdvector,write)143 TEST(serializer_stdvector, write) {
144   std::vector<double> theta(10, 0.0);
145   std::vector<double> x;
146   for (size_t i = 0; i < 10U; ++i) {
147     x.push_back(-static_cast<double>(i));
148   }
149   stan::io::serializer<double> serializer(theta);
150   serializer.write(x);
151   for (size_t i = 0; i < 10U; ++i) {
152     EXPECT_FLOAT_EQ(theta[i], x[i]);
153   }
154   EXPECT_THROW(serializer.write(4), std::runtime_error);
155 }
156 
TEST(serializer_stdvector,complex_write)157 TEST(serializer_stdvector, complex_write) {
158   std::vector<double> theta(20, 0.0);
159   std::vector<std::complex<double>> x;
160   for (size_t i = 0; i < 10U; ++i) {
161     x.push_back(std::complex<double>(-static_cast<double>(i),
162                                      -static_cast<double>(i + 1)));
163   }
164 
165   stan::io::serializer<double> serializer(theta);
166   serializer.write(x);
167   Eigen::Index sentinal = 0;
168   for (size_t i = 0; i < 20U; i += 2) {
169     EXPECT_FLOAT_EQ(theta[i], x[sentinal].real());
170     EXPECT_FLOAT_EQ(theta[i + 1], x[sentinal].imag());
171     ++sentinal;
172   }
173   EXPECT_THROW(serializer.write(4), std::runtime_error);
174 }
175 
176 // size zero
177 
TEST(serializer,zeroSizeVecs)178 TEST(serializer, zeroSizeVecs) {
179   std::vector<int> theta_i;
180   std::vector<double> theta;
181   theta.push_back(1.0);
182   stan::io::serializer<double> serializer(theta);
183 
184   EXPECT_NO_THROW(serializer.write(1.5));  // finish available
185 
186   EXPECT_NO_THROW(serializer.write(std::vector<double>(0)));
187   EXPECT_NO_THROW(serializer.write(Eigen::VectorXd(0)));
188   EXPECT_NO_THROW(serializer.write(Eigen::RowVectorXd(0)));
189   EXPECT_NO_THROW(serializer.write(Eigen::MatrixXd(0, 3)));
190   EXPECT_NO_THROW(serializer.write(Eigen::MatrixXd(3, 0)));
191   EXPECT_NO_THROW(
192       serializer.write(std::vector<std::vector<Eigen::MatrixXd>>(0)));
193 }
194 
195 // out of memory
196 
TEST(serializer,eos_exception)197 TEST(serializer, eos_exception) {
198   std::vector<double> theta;
199   theta.push_back(1.0);
200   theta.push_back(2.0);
201   stan::io::serializer<double> serializer(theta);
202 
203   EXPECT_EQ(2U, serializer.available());
204 
205   EXPECT_NO_THROW(serializer.write(double{1}));
206   EXPECT_NO_THROW(serializer.write(double{1}));
207   EXPECT_THROW(serializer.write(double{1}), std::runtime_error);
208 
209   // should keep throwing
210   EXPECT_THROW(serializer.write(double{1}), std::runtime_error);
211 
212   // The strategy for all the following checks is to allocate 1 less than
213   // the required memory and make sure an error happens
214   {
215     std::vector<double> theta(1);
216     stan::io::serializer<double> serializer(theta);
217     EXPECT_THROW(serializer.write(std::complex<double>{-1, 1}),
218                  std::runtime_error);
219   }
220 
221   {
222     std::vector<double> theta(2);
223     stan::io::serializer<double> serializer(theta);
224     EXPECT_THROW(serializer.write(std::vector<double>(3)), std::runtime_error);
225   }
226 
227   {
228     std::vector<double> theta(1);
229     stan::io::serializer<double> serializer(theta);
230     EXPECT_THROW(serializer.write(Eigen::VectorXd(2)), std::runtime_error);
231   }
232 
233   {
234     std::vector<double> theta(3);
235     stan::io::serializer<double> serializer(theta);
236     using complex_colvec
237         = Eigen::Matrix<std::complex<double>, Eigen::Dynamic, 1>;
238     EXPECT_THROW((serializer.write(complex_colvec(4))), std::runtime_error);
239   }
240 
241   {
242     std::vector<double> theta(5);
243     stan::io::serializer<double> serializer(theta);
244     EXPECT_THROW(
245         serializer.write(std::vector<Eigen::VectorXd>(3, Eigen::VectorXd(2))),
246         std::runtime_error);
247   }
248 
249   {
250     std::vector<double> theta(1);
251     stan::io::serializer<double> serializer(theta);
252     EXPECT_THROW(serializer.write(Eigen::RowVectorXd(2)), std::runtime_error);
253   }
254 
255   {
256     std::vector<double> theta(3);
257     stan::io::serializer<double> serializer(theta);
258     using complex_rowvec
259         = Eigen::Matrix<std::complex<double>, 1, Eigen::Dynamic>;
260     EXPECT_THROW((serializer.write(complex_rowvec(4))), std::runtime_error);
261   }
262 
263   {
264     std::vector<double> theta(5);
265     stan::io::serializer<double> serializer(theta);
266     using std_vec_rowvec = std::vector<Eigen::RowVectorXd>;
267     EXPECT_THROW((serializer.write(std_vec_rowvec(3, Eigen::RowVectorXd(2)))),
268                  std::runtime_error);
269   }
270 
271   {
272     std::vector<double> theta(3);
273     stan::io::serializer<double> serializer(theta);
274     EXPECT_THROW(serializer.write(Eigen::MatrixXd(2, 2)), std::runtime_error);
275   }
276 
277   {
278     std::vector<double> theta(7);
279     stan::io::serializer<double> serializer(theta);
280     using eig_complex_mat
281         = Eigen::Matrix<std::complex<double>, Eigen::Dynamic, Eigen::Dynamic>;
282     EXPECT_THROW((serializer.write(eig_complex_mat(2, 2))), std::runtime_error);
283   }
284 
285   {
286     std::vector<double> theta(11);
287     stan::io::serializer<double> serializer(theta);
288     EXPECT_THROW(serializer.write(
289                      std::vector<Eigen::MatrixXd>(2, Eigen::MatrixXd(3, 2))),
290                  std::runtime_error);
291   }
292 }
293 
294 template <typename Ret, typename... Sizes>
write_free_lb_test(Sizes...sizes)295 void write_free_lb_test(Sizes... sizes) {
296   double lb = 0.5;
297   constexpr size_t theta_size = 100;
298   Eigen::VectorXd theta1 = Eigen::VectorXd::Random(theta_size);
299   std::vector<int> theta_i;
300 
301   // Read an constrained variable
302   stan::io::deserializer<double> deserializer(theta1, theta_i);
303   double lp = 0.0;
304   Ret vec_ref = deserializer.read_constrain_lb<Ret, false>(lb, lp, sizes...);
305 
306   // Serialize a constrained variable
307   Eigen::VectorXd theta2 = Eigen::VectorXd::Random(theta_size);
308   stan::io::serializer<double> serializer(theta2);
309   serializer.write_free_lb(lb, vec_ref);
310 
311   size_t used1 = theta1.size() - deserializer.available();
312   size_t used2 = theta2.size() - serializer.available();
313 
314   // Number of variables read should equal number of variables written
315   EXPECT_EQ(used1, used2);
316 
317   // Make sure the variables written back are the same
318   stan::test::expect_near_rel("deserializer read free",
319                               theta1.segment(0, used1),
320                               theta2.segment(0, used1));
321 }
322 
TEST(serializer_vectorized,write_free_lb)323 TEST(serializer_vectorized, write_free_lb) {
324   write_free_lb_test<double>();
325   write_free_lb_test<Eigen::VectorXd>(4);
326   write_free_lb_test<std::vector<Eigen::VectorXd>>(2, 4);
327   write_free_lb_test<std::vector<std::vector<Eigen::VectorXd>>>(3, 2, 4);
328 }
329 
330 template <typename Ret, typename... Sizes>
write_free_ub_test(Sizes...sizes)331 void write_free_ub_test(Sizes... sizes) {
332   double ub = 0.5;
333   constexpr size_t theta_size = 100;
334   Eigen::VectorXd theta1 = Eigen::VectorXd::Random(theta_size);
335   std::vector<int> theta_i;
336 
337   // Read an constrained variable
338   stan::io::deserializer<double> deserializer(theta1, theta_i);
339   double lp = 0.0;
340   Ret vec_ref = deserializer.read_constrain_ub<Ret, false>(ub, lp, sizes...);
341 
342   // Serialize a constrained variable
343   Eigen::VectorXd theta2 = Eigen::VectorXd::Random(theta_size);
344   stan::io::serializer<double> serializer(theta2);
345   serializer.write_free_ub(ub, vec_ref);
346 
347   size_t used1 = theta1.size() - deserializer.available();
348   size_t used2 = theta2.size() - serializer.available();
349 
350   // Number of variables read should equal number of variables written
351   EXPECT_EQ(used1, used2);
352 
353   // Make sure the variables written back are the same
354   stan::test::expect_near_rel("deserializer read free",
355                               theta1.segment(0, used1),
356                               theta2.segment(0, used1));
357 }
358 
TEST(serializer_vectorized,write_free_ub)359 TEST(serializer_vectorized, write_free_ub) {
360   write_free_ub_test<double>();
361   write_free_ub_test<Eigen::VectorXd>(4);
362   write_free_ub_test<std::vector<Eigen::VectorXd>>(2, 4);
363   write_free_ub_test<std::vector<std::vector<Eigen::VectorXd>>>(3, 2, 4);
364 }
365 
366 template <typename Ret, typename... Sizes>
write_free_lub_test(Sizes...sizes)367 void write_free_lub_test(Sizes... sizes) {
368   double ub = 0.5;
369   double lb = 0.1;
370   constexpr size_t theta_size = 100;
371   Eigen::VectorXd theta1 = Eigen::VectorXd::Random(theta_size);
372   std::vector<int> theta_i;
373 
374   // Read an constrained variable
375   stan::io::deserializer<double> deserializer(theta1, theta_i);
376   double lp = 0.0;
377   Ret vec_ref
378       = deserializer.read_constrain_lub<Ret, false>(lb, ub, lp, sizes...);
379 
380   // Serialize a constrained variable
381   Eigen::VectorXd theta2 = Eigen::VectorXd::Random(theta_size);
382   stan::io::serializer<double> serializer(theta2);
383   serializer.write_free_lub(lb, ub, vec_ref);
384 
385   size_t used1 = theta1.size() - deserializer.available();
386   size_t used2 = theta2.size() - serializer.available();
387 
388   // Number of variables read should equal number of variables written
389   EXPECT_EQ(used1, used2);
390 
391   // Make sure the variables written back are the same
392   stan::test::expect_near_rel("deserializer read free",
393                               theta1.segment(0, used1),
394                               theta2.segment(0, used1));
395 }
396 
TEST(serializer_vectorized,write_free_lub)397 TEST(serializer_vectorized, write_free_lub) {
398   write_free_lub_test<double>();
399   write_free_lub_test<Eigen::VectorXd>(4);
400   write_free_lub_test<std::vector<Eigen::VectorXd>>(2, 4);
401   write_free_lub_test<std::vector<std::vector<Eigen::VectorXd>>>(3, 2, 4);
402 }
403 
404 template <typename Ret, typename... Sizes>
write_free_offset_multiplier_test(Sizes...sizes)405 void write_free_offset_multiplier_test(Sizes... sizes) {
406   double offset = 0.5;
407   double multiplier = 0.35;
408   constexpr size_t theta_size = 100;
409   Eigen::VectorXd theta1 = Eigen::VectorXd::Random(theta_size);
410   std::vector<int> theta_i;
411 
412   // Read an constrained variable
413   stan::io::deserializer<double> deserializer(theta1, theta_i);
414   double lp = 0.0;
415   Ret vec_ref = deserializer.read_constrain_offset_multiplier<Ret, false>(
416       offset, multiplier, lp, sizes...);
417 
418   // Serialize a constrained variable
419   Eigen::VectorXd theta2 = Eigen::VectorXd::Random(theta_size);
420   stan::io::serializer<double> serializer(theta2);
421   serializer.write_free_offset_multiplier(offset, multiplier, vec_ref);
422 
423   size_t used1 = theta1.size() - deserializer.available();
424   size_t used2 = theta2.size() - serializer.available();
425 
426   // Number of variables read should equal number of variables written
427   EXPECT_EQ(used1, used2);
428 
429   // Make sure the variables written back are the same
430   stan::test::expect_near_rel("deserializer read free",
431                               theta1.segment(0, used1),
432                               theta2.segment(0, used1));
433 }
434 
TEST(serializer_vectorized,write_free_offset_multiplier)435 TEST(serializer_vectorized, write_free_offset_multiplier) {
436   write_free_offset_multiplier_test<double>();
437   write_free_offset_multiplier_test<Eigen::VectorXd>(4);
438   write_free_offset_multiplier_test<std::vector<Eigen::VectorXd>>(2, 4);
439   write_free_offset_multiplier_test<std::vector<std::vector<Eigen::VectorXd>>>(
440       3, 2, 4);
441 }
442 template <typename Ret, typename... Sizes>
write_free_unit_vector_test(Sizes...sizes)443 void write_free_unit_vector_test(Sizes... sizes) {
444   Eigen::VectorXd theta1 = Eigen::VectorXd::Random(100);
445   std::vector<int> theta_i;
446 
447   // Read an constrained variable
448   stan::io::deserializer<double> deserializer(theta1, theta_i);
449   double lp = 0.0;
450   Ret vec_ref
451       = deserializer.read_constrain_unit_vector<Ret, false>(lp, sizes...);
452 
453   // Serialize a constrained variable
454   Eigen::VectorXd theta2 = Eigen::VectorXd::Random(theta1.size());
455   stan::io::serializer<double> serializer(theta2);
456   serializer.write_free_unit_vector(vec_ref);
457 
458   // For unit vector, it's not actually doing a change of variables so we check
459   // theta2 equals theta2 (freeing doesn't actually get the unconstrained
460   // variable back).
461   size_t used1 = theta1.size() - deserializer.available();
462   size_t used2 = theta1.size() - serializer.available();
463 
464   // Number of variables read should equal number of variables written
465   EXPECT_EQ(used1, used2);
466 
467   // Make sure the variables written back are the same
468   stan::test::expect_near_rel("deserializer read free",
469                               theta2.segment(0, used1),
470                               theta2.segment(0, used2));
471 }
472 
TEST(serializer_vectorized,write_free_unit_vector)473 TEST(serializer_vectorized, write_free_unit_vector) {
474   write_free_unit_vector_test<Eigen::VectorXd>(4);
475   write_free_unit_vector_test<std::vector<Eigen::VectorXd>>(2, 4);
476   write_free_unit_vector_test<std::vector<std::vector<Eigen::VectorXd>>>(3, 2,
477                                                                          4);
478 }
479 
480 template <typename Ret, typename... Sizes>
write_free_simplex_test(Sizes...sizes)481 void write_free_simplex_test(Sizes... sizes) {
482   constexpr size_t theta_size = 100;
483   Eigen::VectorXd theta1 = Eigen::VectorXd::Random(theta_size);
484   std::vector<int> theta_i;
485 
486   // Read an constrained variable
487   stan::io::deserializer<double> deserializer(theta1, theta_i);
488   double lp = 0.0;
489   Ret vec_ref = deserializer.read_constrain_simplex<Ret, false>(lp, sizes...);
490 
491   // Serialize a constrained variable
492   Eigen::VectorXd theta2 = Eigen::VectorXd::Random(theta_size);
493   stan::io::serializer<double> serializer(theta2);
494   serializer.write_free_simplex(vec_ref);
495 
496   size_t used1 = theta1.size() - deserializer.available();
497   size_t used2 = theta2.size() - serializer.available();
498 
499   // Number of variables read should equal number of variables written
500   EXPECT_EQ(used1, used2);
501 
502   // Make sure the variables written back are the same
503   stan::test::expect_near_rel("deserializer read free",
504                               theta1.segment(0, used1),
505                               theta2.segment(0, used1));
506 }
507 
TEST(serializer_vectorized,write_free_simplex)508 TEST(serializer_vectorized, write_free_simplex) {
509   write_free_simplex_test<Eigen::VectorXd>(4);
510   write_free_simplex_test<std::vector<Eigen::VectorXd>>(2, 4);
511   write_free_simplex_test<std::vector<std::vector<Eigen::VectorXd>>>(3, 2, 4);
512 }
513 
514 // ordered
515 
516 template <typename Ret, typename... Sizes>
write_free_ordered_test(Sizes...sizes)517 void write_free_ordered_test(Sizes... sizes) {
518   // Read an constrained variable
519   Eigen::VectorXd theta1 = Eigen::VectorXd::Random(100);
520   std::vector<int> theta_i;
521   stan::io::deserializer<double> deserializer(theta1, theta_i);
522   double lp = 0.0;
523   Ret vec_ref = deserializer.read_constrain_ordered<Ret, false>(lp, sizes...);
524 
525   // Serialize a constrained variable
526   Eigen::VectorXd theta2 = Eigen::VectorXd::Random(theta1.size());
527   stan::io::serializer<double> serializer(theta2);
528   serializer.write_free_ordered(vec_ref);
529 
530   size_t used1 = theta1.size() - deserializer.available();
531   size_t used2 = theta2.size() - serializer.available();
532 
533   // Number of variables read should equal number of variables written
534   EXPECT_EQ(used1, used2);
535 
536   // Make sure the variables written back are the same
537   stan::test::expect_near_rel("deserializer read free",
538                               theta1.segment(0, used1),
539                               theta2.segment(0, used1));
540 }
541 
TEST(serializer_vectorized,write_free_ordered)542 TEST(serializer_vectorized, write_free_ordered) {
543   write_free_ordered_test<Eigen::VectorXd>(4);
544   write_free_ordered_test<std::vector<Eigen::VectorXd>>(2, 4);
545   write_free_ordered_test<std::vector<std::vector<Eigen::VectorXd>>>(3, 2, 4);
546 }
547 
548 // positive_ordered
549 
550 template <typename Ret, typename... Sizes>
write_free_positive_ordered_test(Sizes...sizes)551 void write_free_positive_ordered_test(Sizes... sizes) {
552   Eigen::VectorXd theta1 = Eigen::VectorXd::Random(100);
553   Eigen::VectorXd theta2 = Eigen::VectorXd::Random(theta1.size());
554   std::vector<int> theta_i;
555 
556   // Read an constrained variable
557   stan::io::deserializer<double> deserializer(theta1, theta_i);
558   double lp = 0.0;
559   Ret vec_ref
560       = deserializer.read_constrain_positive_ordered<Ret, false>(lp, sizes...);
561 
562   // Serialize a constrained variable
563   stan::io::serializer<double> serializer(theta2);
564   serializer.write_free_positive_ordered(vec_ref);
565 
566   size_t used1 = theta1.size() - deserializer.available();
567   size_t used2 = theta2.size() - serializer.available();
568 
569   // Number of variables read should equal number of variables written
570   EXPECT_EQ(used1, used2);
571 
572   // Make sure the variables written back are the same
573   stan::test::expect_near_rel("deserializer read free",
574                               theta1.segment(0, used1),
575                               theta2.segment(0, used1));
576 }
577 
TEST(serializer_vectorized,write_free_positive_ordered)578 TEST(serializer_vectorized, write_free_positive_ordered) {
579   write_free_positive_ordered_test<Eigen::VectorXd>(4);
580   write_free_positive_ordered_test<std::vector<Eigen::VectorXd>>(2, 4);
581   write_free_positive_ordered_test<std::vector<std::vector<Eigen::VectorXd>>>(
582       3, 2, 4);
583 }
584 
585 // cholesky_factor_cov
586 
587 template <typename Ret, typename... Sizes>
write_free_cholesky_factor_cov_test(Sizes...sizes)588 void write_free_cholesky_factor_cov_test(Sizes... sizes) {
589   Eigen::VectorXd theta1 = Eigen::VectorXd::Random(100);
590   Eigen::VectorXd theta2 = Eigen::VectorXd::Random(theta1.size());
591   std::vector<int> theta_i;
592 
593   // Read an constrained variable
594   stan::io::deserializer<double> deserializer(theta1, theta_i);
595   double lp = 0.0;
596   Ret vec_ref = deserializer.read_constrain_cholesky_factor_cov<Ret, false>(
597       lp, sizes...);
598 
599   // Serialize a constrained variable
600   stan::io::serializer<double> serializer(theta2);
601   serializer.write_free_cholesky_factor_cov(vec_ref);
602 
603   size_t used1 = theta1.size() - deserializer.available();
604   size_t used2 = theta2.size() - serializer.available();
605 
606   // Number of variables read should equal number of variables written
607   EXPECT_EQ(used1, used2);
608 
609   // Make sure the variables written back are the same
610   stan::test::expect_near_rel("deserializer read free",
611                               theta1.segment(0, used1),
612                               theta2.segment(0, used1));
613 }
614 
TEST(serializer_vectorized,write_free_cholesky_factor_cov)615 TEST(serializer_vectorized, write_free_cholesky_factor_cov) {
616   write_free_cholesky_factor_cov_test<Eigen::MatrixXd>(4, 3);
617   write_free_cholesky_factor_cov_test<std::vector<Eigen::MatrixXd>>(2, 4, 3);
618   write_free_cholesky_factor_cov_test<
619       std::vector<std::vector<Eigen::MatrixXd>>>(3, 2, 4, 3);
620 
621   write_free_cholesky_factor_cov_test<Eigen::MatrixXd>(2, 2);
622   write_free_cholesky_factor_cov_test<std::vector<Eigen::MatrixXd>>(2, 2, 2);
623   write_free_cholesky_factor_cov_test<
624       std::vector<std::vector<Eigen::MatrixXd>>>(3, 2, 2, 2);
625 }
626 
627 // cholesky_factor_corr
628 
629 template <typename Ret, typename... Sizes>
write_free_cholesky_factor_corr_test(Sizes...sizes)630 void write_free_cholesky_factor_corr_test(Sizes... sizes) {
631   // Read an constrained variable
632   Eigen::VectorXd theta1 = Eigen::VectorXd::Random(100);
633   std::vector<int> theta_i;
634   stan::io::deserializer<double> deserializer(theta1, theta_i);
635   double lp = 0.0;
636   Ret vec_ref = deserializer.read_constrain_cholesky_factor_corr<Ret, false>(
637       lp, sizes...);
638 
639   // Serialize a constrained variable
640   Eigen::VectorXd theta2 = Eigen::VectorXd::Random(theta1.size());
641   stan::io::serializer<double> serializer(theta2);
642   serializer.write_free_cholesky_factor_corr(vec_ref);
643 
644   size_t used1 = theta1.size() - deserializer.available();
645   size_t used2 = theta2.size() - serializer.available();
646 
647   // Number of variables read should equal number of variables written
648   EXPECT_EQ(used1, used2);
649 
650   // Make sure the variables written back are the same
651   stan::test::expect_near_rel("deserializer read free",
652                               theta1.segment(0, used1),
653                               theta2.segment(0, used1));
654 }
655 
TEST(serializer_vectorized,write_free_cholesky_factor_corr)656 TEST(serializer_vectorized, write_free_cholesky_factor_corr) {
657   write_free_cholesky_factor_corr_test<Eigen::MatrixXd>(2);
658   write_free_cholesky_factor_corr_test<std::vector<Eigen::MatrixXd>>(2, 2);
659   write_free_cholesky_factor_corr_test<
660       std::vector<std::vector<Eigen::MatrixXd>>>(3, 2, 2);
661 }
662 
663 // cov_matrix
664 
665 template <typename Ret, typename... Sizes>
write_free_cov_matrix_test(Sizes...sizes)666 void write_free_cov_matrix_test(Sizes... sizes) {
667   Eigen::VectorXd theta1 = Eigen::VectorXd::Random(100);
668   Eigen::VectorXd theta2 = Eigen::VectorXd::Random(theta1.size());
669   std::vector<int> theta_i;
670 
671   // Read an constrained variable
672   stan::io::deserializer<double> deserializer(theta1, theta_i);
673   double lp = 0.0;
674   Ret vec_ref
675       = deserializer.read_constrain_cov_matrix<Ret, false>(lp, sizes...);
676 
677   // Serialize a constrained variable
678   stan::io::serializer<double> serializer(theta2);
679   serializer.write_free_cov_matrix(vec_ref);
680 
681   size_t used1 = theta1.size() - deserializer.available();
682   size_t used2 = theta2.size() - serializer.available();
683 
684   // Number of variables read should equal number of variables written
685   EXPECT_EQ(used1, used2);
686 
687   // Make sure the variables written back are the same
688   stan::test::expect_near_rel("deserializer read free",
689                               theta1.segment(0, used1),
690                               theta2.segment(0, used1));
691 }
692 
TEST(serializer_vectorized,write_free_cov_matrix)693 TEST(serializer_vectorized, write_free_cov_matrix) {
694   write_free_cov_matrix_test<Eigen::MatrixXd>(2);
695   write_free_cov_matrix_test<std::vector<Eigen::MatrixXd>>(2, 2);
696   write_free_cov_matrix_test<std::vector<std::vector<Eigen::MatrixXd>>>(3, 2,
697                                                                         2);
698 }
699 
700 // corr_matrix
701 
702 template <typename Ret, typename... Sizes>
write_free_corr_matrix_test(Sizes...sizes)703 void write_free_corr_matrix_test(Sizes... sizes) {
704   Eigen::VectorXd theta1 = Eigen::VectorXd::Random(100);
705   Eigen::VectorXd theta2 = Eigen::VectorXd::Random(theta1.size());
706   std::vector<int> theta_i;
707 
708   // Read an constrained variable
709   stan::io::deserializer<double> deserializer(theta1, theta_i);
710   double lp = 0.0;
711   Ret vec_ref
712       = deserializer.read_constrain_corr_matrix<Ret, false>(lp, sizes...);
713 
714   // Serialize a constrained variable
715   stan::io::serializer<double> serializer(theta2);
716   serializer.write_free_corr_matrix(vec_ref);
717 
718   size_t used1 = theta1.size() - deserializer.available();
719   size_t used2 = theta2.size() - serializer.available();
720 
721   // Number of variables read should equal number of variables written
722   EXPECT_EQ(used1, used2);
723 
724   // Make sure the variables written back are the same
725   stan::test::expect_near_rel("deserializer read free",
726                               theta1.segment(0, used1),
727                               theta2.segment(0, used1));
728 }
729 
TEST(serializer_vectorized,write_free_corr_matrix)730 TEST(serializer_vectorized, write_free_corr_matrix) {
731   write_free_corr_matrix_test<Eigen::MatrixXd>(2);
732   write_free_corr_matrix_test<std::vector<Eigen::MatrixXd>>(2, 2);
733   write_free_corr_matrix_test<std::vector<std::vector<Eigen::MatrixXd>>>(3, 2,
734                                                                          2);
735 }
736