1#ifndef STAN_MATH_PRIM_FUNCTOR_APPLY_SCALAR_BINARY_HPP
2#define STAN_MATH_PRIM_FUNCTOR_APPLY_SCALAR_BINARY_HPP
35template <
typename F,
typename T1,
typename T2,
36 require_all_stan_scalar_t<T1, T2>* =
nullptr>
38 return std::forward<F>(f)(std::forward<T1>(x), std::forward<T2>(y));
54template <
typename F,
typename T1,
typename T2,
59 [](
auto&& f_inner,
auto&& x_inner,
auto&& y_inner) {
60 return std::forward<decltype(x_inner)>(x_inner).binaryExpr(
61 std::forward<
decltype(y_inner)>(y_inner),
62 std::forward<
decltype(f_inner)>(f_inner));
64 std::forward<F>(f), std::forward<T1>(x), std::forward<T2>(y));
79template <
typename F,
typename T1,
typename T2,
80 require_eigen_vector_vt<is_stan_scalar, T1>* =
nullptr,
81 require_std_vector_vt<std::is_integral, T2>* =
nullptr>
85 [](
auto&& f_inner,
auto&& x_inner,
auto&& y_inner) {
90 return Eigen::Map<const int_vec_t>(y_inner_.data(),
93 std::forward<decltype(y_inner)>(y_inner));
94 return std::forward<decltype(x_inner)>(x_inner).binaryExpr(
95 y_map, std::forward<
decltype(f_inner)>(f_inner));
97 std::forward<F>(f), std::forward<T1>(x), std::forward<T2>(y));
112template <
typename F,
typename T1,
typename T2,
118 [](
auto&& f_inner,
auto&& x_inner,
auto&& y_inner) {
122 [](
auto&& x_inner_) {
123 return Eigen::Map<const int_vec_t>(x_inner_.data(),
126 std::forward<decltype(x_inner)>(x_inner));
127 return x_map.binaryExpr(std::forward<
decltype(y_inner)>(y_inner),
128 std::forward<
decltype(f_inner)>(f_inner));
130 std::forward<F>(f), std::forward<T1>(x), std::forward<T2>(y));
145template <
typename F,
typename T1,
typename T2,
146 require_eigen_matrix_dynamic_vt<is_stan_scalar, T1>* =
nullptr,
147 require_std_vector_vt<is_std_vector, T2>* =
nullptr,
148 require_std_vector_st<std::is_integral, T2>* =
nullptr>
151 std::ostringstream msg;
152 msg <<
"Inputs to vectorized binary function must match in"
153 <<
" size if one is not a scalar";
154 throw std::invalid_argument(msg.str());
156 using return_st =
decltype(f(x(0), y[0][0]));
157 Eigen::Matrix<return_st, Eigen::Dynamic, Eigen::Dynamic> result(x.rows(),
159 for (
size_t i = 0; i < y.size(); ++i) {
178template <
typename F,
typename T1,
typename T2,
184 std::ostringstream msg;
185 msg <<
"Inputs to vectorized binary function must match in"
186 <<
" size if one is not a scalar";
187 throw std::invalid_argument(msg.str());
189 using return_st =
decltype(f(x[0][0], y(0)));
190 Eigen::Matrix<return_st, Eigen::Dynamic, Eigen::Dynamic> result(y.rows(),
192 for (
size_t i = 0; i < x.size(); ++i) {
194 y.row(i).transpose());
214template <
typename F,
typename T1,
typename T2, require_eigen_t<T1>* =
nullptr,
215 require_stan_scalar_t<T2>* =
nullptr>
218 [](
auto&& f_inner,
auto&& x_inner,
auto&& y_inner) {
219 return std::forward<decltype(x_inner)>(x_inner).unaryExpr(
220 [f_inner_ = std::forward<
decltype(f_inner)>(f_inner),
221 y_inner](
auto&& v) {
return f_inner_(v, y_inner); });
223 std::forward<F>(f), std::forward<T1>(x), std::forward<T2>(y));
241template <
typename F,
typename T1,
typename T2,
242 require_stan_scalar_t<T1>* =
nullptr, require_eigen_t<T2>* =
nullptr>
245 [](
auto&& f_inner,
auto&& x_inner,
auto&& y_inner) {
246 return std::forward<decltype(y_inner)>(y_inner).unaryExpr(
247 [f_inner_ = std::forward<
decltype(f_inner)>(f_inner),
249 return f_inner_(x_inner, std::forward<
decltype(v)>(v));
252 std::forward<F>(f), std::forward<T1>(x), std::forward<T2>(y));
272template <
typename F,
typename T1,
typename T2,
273 require_all_std_vector_vt<is_stan_scalar, T1, T2>* =
nullptr>
276 using T_return = std::decay_t<
decltype(f(x[0], y[0]))>;
279 std::vector<T_return> result(x_vec.size());
280 Eigen::Map<Eigen::Matrix<T_return, -1, 1>>(result.data(), result.size())
281 = x_vec.binaryExpr(y_vec, std::forward<F>(f));
303template <
typename F,
typename T1,
typename T2,
304 require_std_vector_vt<is_stan_scalar, T1>* =
nullptr,
305 require_stan_scalar_t<T2>* =
nullptr>
308 using T_return = std::decay_t<
decltype(f(x[0], y))>;
309 std::vector<T_return> result(x_vec.size());
310 Eigen::Map<Eigen::Matrix<T_return, -1, 1>>(result.data(), result.size())
312 [f_ = std::forward<F>(f), y](
auto&& v) {
return f_(v, y); });
334template <
typename F,
typename T1,
typename T2,
335 require_stan_scalar_t<T1>* =
nullptr,
336 require_std_vector_vt<is_stan_scalar, T2>* =
nullptr>
338 using T_return = std::decay_t<
decltype(f(x, y[0]))>;
340 std::vector<T_return> result(y_vec.size());
341 Eigen::Map<Eigen::Matrix<T_return, -1, 1>>(result.data(), result.size())
343 [f_ = std::forward<F>(f), x](
auto&& v) {
return f_(x, v); });
362 typename F,
typename T1,
typename T2,
363 require_all_std_vector_vt<is_container_or_var_matrix, T1, T2>* =
nullptr>
367 size_t y_size = y.size();
368 std::vector<T_return> result(y_size);
369 for (
size_t i = 0; i < y_size; ++i) {
389template <
typename F,
typename T1,
typename T2,
390 require_std_vector_vt<is_container_or_var_matrix, T1>* =
nullptr,
391 require_stan_scalar_t<T2>* =
nullptr>
394 size_t x_size = x.size();
395 std::vector<T_return> result(x_size);
396 for (
size_t i = 0; i < x_size; ++i) {
416template <
typename F,
typename T1,
typename T2,
417 require_stan_scalar_t<T1>* =
nullptr,
418 require_std_vector_vt<is_container_or_var_matrix, T2>* =
nullptr>
421 size_t y_size = y.size();
422 std::vector<T_return> result(y_size);
423 for (
size_t i = 0; i < y_size; ++i) {
require_t< container_type_check_base< is_eigen_matrix_dynamic, value_type_t, TypeCheck, Check... > > require_eigen_matrix_dynamic_vt
Require type satisfies is_eigen_matrix_dynamic.
require_all_t< is_eigen< std::decay_t< Types > >... > require_all_eigen_t
Require all of the types satisfy is_eigen.
require_t< container_type_check_base< is_eigen_vector, value_type_t, TypeCheck, Check... > > require_eigen_vector_vt
Require type satisfies is_eigen_vector.
auto as_column_vector_or_scalar(T &&a)
as_column_vector_or_scalar of a kernel generator expression.
require_t< container_type_check_base< is_std_vector, value_type_t, TypeCheck, Check... > > require_std_vector_vt
Require type satisfies is_std_vector.
require_t< container_type_check_base< is_std_vector, scalar_type_t, TypeCheck, Check... > > require_std_vector_st
Require type satisfies is_std_vector.
typename value_type< T >::type value_type_t
Helper function for accessing underlying type.
typename promote_scalar_type< std::decay_t< T >, std::decay_t< S > >::type promote_scalar_t
auto apply_scalar_binary(F &&f, T1 &&x, T2 &&y)
Base template function for vectorization of binary scalar functions defined by applying a functor to ...
void check_matching_dims(const char *function, const char *name1, const T1 &y1, const char *name2, const T2 &y2)
Check if the two containers have the same dimensions.
auto make_holder(F &&func, Args &&... args)
Calls given function with given arguments.
void check_matching_sizes(const char *function, const char *name1, const T_y1 &y1, const char *name2, const T_y2 &y2)
Check if two structures at the same size.
int64_t num_elements(const T &m)
Returns the number of the elements of a matrix_cl or var_value<matrix_cl<T>>.
typename plain_type< std::decay_t< T > >::type plain_type_t
The lgamma implementation in stan-math is based on either the reentrant safe lgamma_r implementation ...