@@ -17,7 +17,7 @@ namespace test {
1717 * @param f functor to apply to inputs.
1818 */
1919template <typename F, typename T1, typename T2,
20- require_all_not_std_vector_t <T1, T2>* = nullptr >
20+ require_all_not_vector_t <T1, T2>* = nullptr >
2121void binary_scalar_tester_impl (const F& f, const T1& x, const T2& y) {
2222 auto vec_vec = f (x, y);
2323 auto vec_scal = f (x, y (0 ));
@@ -87,7 +87,7 @@ void binary_scalar_tester_impl(const F& f, const T1& x, const T2& y) {
8787 * @param f functor to apply to inputs.
8888 */
8989template <typename F, typename T1, typename T2,
90- require_all_std_vector_t <T1, T2>* = nullptr >
90+ require_all_vector_t <T1, T2>* = nullptr >
9191void binary_scalar_tester_impl (const F& f, const T1& x, const T2& y) {
9292 auto vec_vec = f (x, y);
9393 auto vec_scal = f (x, y[0 ]);
@@ -97,13 +97,13 @@ void binary_scalar_tester_impl(const F& f, const T1& x, const T2& y) {
9797 EXPECT_FLOAT_EQ (f (x[i], y[0 ]), vec_scal[i]);
9898 EXPECT_FLOAT_EQ (f (x[0 ], y[i]), scal_vec[i]);
9999 }
100- T1 x_zero;
101- T2 y_zero;
100+ plain_type_t <T1> x_zero;
101+ plain_type_t <T2> y_zero;
102102 EXPECT_THROW (f (x_zero, y), std::invalid_argument);
103103 EXPECT_THROW (f (x, y_zero), std::invalid_argument);
104104
105- std::vector<T1 > nest_x{x, x, x};
106- std::vector<T2 > nest_y{y, y, y};
105+ std::vector<plain_type_t <T1> > nest_x{x, x, x};
106+ std::vector<plain_type_t <T2> > nest_y{y, y, y};
107107 auto nestvec_nestvec = f (nest_x, nest_y);
108108 auto nestvec_scal = f (nest_x, y[0 ]);
109109 auto scal_nestvec = f (x[0 ], nest_y);
@@ -114,13 +114,13 @@ void binary_scalar_tester_impl(const F& f, const T1& x, const T2& y) {
114114 EXPECT_FLOAT_EQ (f (x[0 ], nest_y[i][j]), scal_nestvec[i][j]);
115115 }
116116 }
117- std::vector<T1 > nest_x_small{x, x};
118- std::vector<T2 > nest_y_small{y, y};
117+ std::vector<plain_type_t <T1> > nest_x_small{x, x};
118+ std::vector<plain_type_t <T2> > nest_y_small{y, y};
119119 EXPECT_THROW (f (nest_x, nest_y_small), std::invalid_argument);
120120 EXPECT_THROW (f (nest_x_small, nest_y), std::invalid_argument);
121121
122- std::vector<std::vector<T1 >> nest_nest_x{nest_x, nest_x, nest_x};
123- std::vector<std::vector<T2 >> nest_nest_y{nest_y, nest_y, nest_y};
122+ std::vector<std::vector<plain_type_t <T1> >> nest_nest_x{nest_x, nest_x, nest_x};
123+ std::vector<std::vector<plain_type_t <T2> >> nest_nest_y{nest_y, nest_y, nest_y};
124124 auto nestnestvec_nestnestvec = f (nest_nest_x, nest_nest_y);
125125 auto nestnestvec_scal = f (nest_nest_x, y[0 ]);
126126 auto scal_nestnestvec = f (x[0 ], nest_nest_y);
@@ -136,12 +136,129 @@ void binary_scalar_tester_impl(const F& f, const T1& x, const T2& y) {
136136 }
137137 }
138138 }
139- std::vector<std::vector<T1>> nest_nest_x_small{nest_x, nest_x};
139+ std::vector<std::vector<plain_type_t <T1>>> nest_nest_x_small{nest_x, nest_x};
140+ std::vector<std::vector<plain_type_t <T2>>> nest_nest_y_small{nest_y, nest_y};
141+ EXPECT_THROW (f (nest_nest_x, nest_nest_y_small), std::invalid_argument);
142+ EXPECT_THROW (f (nest_nest_x_small, nest_nest_y), std::invalid_argument);
143+ }
144+
145+
146+ /* *
147+ * Implementation function which checks that the binary vectorisation
148+ * framework returns the same value as the function with scalar inputs,
149+ * for all valid combinations of scalar/vector/nested vector.
150+ *
151+ * @tparam F Type of functor to apply.
152+ * @tparam T1 Type of first vector.
153+ * @tparam T2 Type of second vector.
154+ * @param x First vector input to which operation is applied.
155+ * @param y Second vector input to which operation is applied.
156+ * @param f functor to apply to inputs.
157+ */
158+ template <typename F, typename T1, typename T2,
159+ typename T1_plain = plain_type_t <T1>,
160+ require_eigen_matrix_t <T1>* = nullptr ,
161+ require_std_vector_t <T2>* = nullptr >
162+ void binary_scalar_tester_impl (const F& f, const T1& x, const T2& y) {
163+ auto vec_vec = f (x, y);
164+ for (int r = 0 ; r < x.rows (); ++r) {
165+ for (int c = 0 ; c < x.cols (); ++c) {
166+ EXPECT_FLOAT_EQ (f (x (r, c), y[r][c]), vec_vec (r, c));
167+ }
168+ }
169+
170+ T1_plain x_zero;
171+ T2 y_zero;
172+ EXPECT_THROW (f (x_zero, y), std::invalid_argument);
173+ EXPECT_THROW (f (x, y_zero), std::invalid_argument);
174+
175+ std::vector<T1_plain> nest_x{x, x, x};
176+ std::vector<T2> nest_y{y, y, y};
177+ auto nestvec_nestvec = f (nest_x, nest_y);
178+ for (int i = 0 ; i < 3 ; ++i) {
179+ for (int r = 0 ; r < x.rows (); ++r) {
180+ for (int c = 0 ; c < x.cols (); ++c) {
181+ EXPECT_FLOAT_EQ (f (nest_x[i](r, c), nest_y[i][r][c]), nestvec_nestvec[i](r, c));
182+ }
183+ }
184+ }
185+ std::vector<T1_plain> nest_x_small{x, x};
186+ std::vector<T2> nest_y_small{y, y};
187+ EXPECT_THROW (f (nest_x, nest_y_small), std::invalid_argument);
188+ EXPECT_THROW (f (nest_x_small, nest_y), std::invalid_argument);
189+
190+ std::vector<std::vector<T1_plain>> nest_nest_x{nest_x, nest_x, nest_x};
191+ std::vector<std::vector<T2>> nest_nest_y{nest_y, nest_y, nest_y};
192+
193+ auto nestnestvec_nestnestvec = f (nest_nest_x, nest_nest_y);
194+ for (int i = 0 ; i < 3 ; ++i) {
195+ for (int j = 0 ; j < 3 ; ++j) {
196+ for (int r = 0 ; r < x.rows (); ++r) {
197+ for (int c = 0 ; c < x.cols (); ++c) {
198+ EXPECT_FLOAT_EQ (f (nest_nest_x[i][j](r, c), nest_nest_y[i][j][r][c]),
199+ nestnestvec_nestnestvec[i][j](r, c));
200+ }
201+ }
202+ }
203+ }
204+ std::vector<std::vector<T1_plain>> nest_nest_x_small{nest_x, nest_x};
140205 std::vector<std::vector<T2>> nest_nest_y_small{nest_y, nest_y};
141206 EXPECT_THROW (f (nest_nest_x, nest_nest_y_small), std::invalid_argument);
142207 EXPECT_THROW (f (nest_nest_x_small, nest_nest_y), std::invalid_argument);
143208}
144209
210+ template <typename F, typename T1, typename T2,
211+ typename T2_plain = plain_type_t <T2>,
212+ require_std_vector_t <T1>* = nullptr ,
213+ require_eigen_matrix_t <T2>* = nullptr >
214+ void binary_scalar_tester_impl (const F& f, const T1& x, const T2& y) {
215+ auto vec_vec = f (x, y);
216+ for (int r = 0 ; r < y.rows (); ++r) {
217+ for (int c = 0 ; c < y.cols (); ++c) {
218+ EXPECT_FLOAT_EQ (f (x[r][c], y (r, c)), vec_vec (r, c));
219+ }
220+ }
221+
222+ T1 x_zero;
223+ T2_plain y_zero;
224+ EXPECT_THROW (f (x_zero, y), std::invalid_argument);
225+ EXPECT_THROW (f (x, y_zero), std::invalid_argument);
226+
227+ std::vector<T1> nest_x{x, x, x};
228+ std::vector<T2_plain> nest_y{y, y, y};
229+ auto nestvec_nestvec = f (nest_x, nest_y);
230+ for (int i = 0 ; i < 3 ; ++i) {
231+ for (int r = 0 ; r < y.rows (); ++r) {
232+ for (int c = 0 ; c < y.cols (); ++c) {
233+ EXPECT_FLOAT_EQ (f (nest_x[i][r][c], nest_y[i](r, c)), nestvec_nestvec[i](r, c));
234+ }
235+ }
236+ }
237+ std::vector<T1> nest_x_small{x, x};
238+ std::vector<T2_plain> nest_y_small{y, y};
239+ EXPECT_THROW (f (nest_x, nest_y_small), std::invalid_argument);
240+ EXPECT_THROW (f (nest_x_small, nest_y), std::invalid_argument);
241+
242+ std::vector<std::vector<T1>> nest_nest_x{nest_x, nest_x, nest_x};
243+ std::vector<std::vector<T2_plain>> nest_nest_y{nest_y, nest_y, nest_y};
244+
245+ auto nestnestvec_nestnestvec = f (nest_nest_x, nest_nest_y);
246+ for (int i = 0 ; i < 3 ; ++i) {
247+ for (int j = 0 ; j < 3 ; ++j) {
248+ for (int r = 0 ; r < y.rows (); ++r) {
249+ for (int c = 0 ; c < y.cols (); ++c) {
250+ EXPECT_FLOAT_EQ (f (nest_nest_x[i][j][r][c], nest_nest_y[i][j](r, c)),
251+ nestnestvec_nestnestvec[i][j](r, c));
252+ }
253+ }
254+ }
255+ }
256+ std::vector<std::vector<T1>> nest_nest_x_small{nest_x, nest_x};
257+ std::vector<std::vector<T2_plain>> nest_nest_y_small{nest_y, nest_y};
258+ EXPECT_THROW (f (nest_nest_x, nest_nest_y_small), std::invalid_argument);
259+ EXPECT_THROW (f (nest_nest_x_small, nest_nest_y), std::invalid_argument);
260+ }
261+
145262/* *
146263 * Testing framework for checking that the vectorisation of binary
147264 * functions returns the same results as the binary function with
@@ -172,5 +289,10 @@ void binary_scalar_tester(const F& f, const T1& x, const T2& y) {
172289 std::vector<typename T2::Scalar>(y.data (), y.data () + y.size ()));
173290}
174291
292+ template <typename F, typename T1, typename T2,
293+ require_any_std_vector_t <T1, T2>* = nullptr >
294+ void binary_scalar_tester (const F& f, const T1& x, const T2& y) {
295+ binary_scalar_tester_impl (f, x, y);
296+ }
175297} // namespace test
176298} // namespace stan
0 commit comments