1#ifndef STAN_MATH_PRIM_FUNCTOR_APPLY_SCALAR_BINARY_HPP
2#define STAN_MATH_PRIM_FUNCTOR_APPLY_SCALAR_BINARY_HPP
35template <
typename T1,
typename T2,
typename F,
36 require_all_stan_scalar_t<T1, T2>* =
nullptr>
54template <
typename T1,
typename T2,
typename F,
59 [](
auto& f_inner,
auto& x_inner,
auto& y_inner) {
60 return x_inner.binaryExpr(y_inner, f_inner);
62 std::forward<F>(f), std::forward<T1>(x), std::forward<T2>(y));
77template <
typename T1,
typename T2,
typename F,
83 [](
auto& f_inner,
auto& x_inner,
auto& y_inner) {
86 Eigen::Map<const int_vec_t> y_map(y_inner.data(), y_inner.size());
87 return x_inner.binaryExpr(y_map, f_inner);
89 std::forward<F>(f), std::forward<T1>(x), std::forward<T2>(y));
104template <
typename T1,
typename T2,
typename F,
110 [](
auto& f_inner,
auto& x_inner,
auto& y_inner) {
113 Eigen::Map<const int_vec_t> x_map(x_inner.data(), x_inner.size());
114 return x_map.binaryExpr(y_inner, f_inner);
116 std::forward<F>(f), std::forward<T1>(x), std::forward<T2>(y));
131template <
typename T1,
typename T2,
typename F,
132 require_eigen_matrix_dynamic_vt<is_stan_scalar, T1>* =
nullptr,
133 require_std_vector_vt<is_std_vector, T2>* =
nullptr,
134 require_std_vector_st<std::is_integral, T2>* =
nullptr>
137 std::ostringstream msg;
138 msg <<
"Inputs to vectorized binary function must match in"
139 <<
" size if one is not a scalar";
140 throw std::invalid_argument(msg.str());
142 using return_st =
decltype(f(x(0), y[0][0]));
143 Eigen::Matrix<return_st, Eigen::Dynamic, Eigen::Dynamic> result(x.rows(),
145 for (
size_t i = 0; i < y.size(); ++i) {
164template <
typename T1,
typename T2,
typename F,
170 std::ostringstream msg;
171 msg <<
"Inputs to vectorized binary function must match in"
172 <<
" size if one is not a scalar";
173 throw std::invalid_argument(msg.str());
175 using return_st =
decltype(f(x[0][0], y(0)));
176 Eigen::Matrix<return_st, Eigen::Dynamic, Eigen::Dynamic> result(y.rows(),
178 for (
size_t i = 0; i < x.size(); ++i) {
180 y.row(i).transpose(), f);
200template <
typename T1,
typename T2,
typename F, require_eigen_t<T1>* =
nullptr,
201 require_stan_scalar_t<T2>* =
nullptr>
204 [](
auto& f_inner,
auto& x_inner,
auto& y_inner) {
205 return x_inner.unaryExpr(
206 [f_inner, y_inner](
const auto& v) {
return f_inner(v, y_inner); });
208 std::forward<F>(f), std::forward<T1>(x), std::forward<T2>(y));
226template <
typename T1,
typename T2,
typename F,
227 require_stan_scalar_t<T1>* =
nullptr, require_eigen_t<T2>* =
nullptr>
230 [](
auto& f_inner,
auto& x_inner,
auto& y_inner) {
231 return y_inner.unaryExpr(
232 [f_inner, x_inner](
const auto& v) {
return f_inner(x_inner, v); });
234 std::forward<F>(f), std::forward<T1>(x), std::forward<T2>(y));
254template <
typename T1,
typename T2,
typename F,
255 require_all_std_vector_vt<is_stan_scalar, T1, T2>* =
nullptr>
260 using T_return = std::decay_t<
decltype(f(x[0], y[0]))>;
261 std::vector<T_return> result(x.size());
262 Eigen::Map<Eigen::Matrix<T_return, -1, 1>>(result.data(), result.size())
263 = x_vec.binaryExpr(y_vec, f);
285template <
typename T1,
typename T2,
typename F,
286 require_std_vector_vt<is_stan_scalar, T1>* =
nullptr,
287 require_stan_scalar_t<T2>* =
nullptr>
290 using T_return = std::decay_t<
decltype(f(x[0], y))>;
291 std::vector<T_return> result(x.size());
292 Eigen::Map<Eigen::Matrix<T_return, -1, 1>>(result.data(), result.size())
293 = x_vec.unaryExpr([f, y](
const auto& v) {
return f(v, y); });
315template <
typename T1,
typename T2,
typename F,
320 using T_return = std::decay_t<
decltype(f(x, y[0]))>;
321 std::vector<T_return> result(y.size());
322 Eigen::Map<Eigen::Matrix<T_return, -1, 1>>(result.data(), result.size())
323 = y_vec.unaryExpr([f, x](
const auto& v) {
return f(x, v); });
342 typename T1,
typename T2,
typename F,
343 require_all_std_vector_vt<is_container_or_var_matrix, T1, T2>* =
nullptr>
347 size_t y_size = y.size();
348 std::vector<T_return> result(y_size);
349 for (
size_t i = 0; i < y_size; ++i) {
369template <
typename T1,
typename T2,
typename F,
370 require_std_vector_vt<is_container_or_var_matrix, T1>* =
nullptr,
371 require_stan_scalar_t<T2>* =
nullptr>
374 size_t x_size = x.size();
375 std::vector<T_return> result(x_size);
376 for (
size_t i = 0; i < x_size; ++i) {
396template <
typename T1,
typename T2,
typename F,
397 require_stan_scalar_t<T1>* =
nullptr,
398 require_std_vector_vt<is_container_or_var_matrix, T2>* =
nullptr>
401 size_t y_size = y.size();
402 std::vector<T_return> result(y_size);
403 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< is_stan_scalar< std::decay_t< T > > > require_stan_scalar_t
Require type satisfies is_stan_scalar.
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.
auto make_holder(const F &func, Args &&... args)
Constructs an expression from given arguments using given functor.
typename promote_scalar_type< std::decay_t< T >, std::decay_t< S > >::type promote_scalar_t
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.
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.
auto apply_scalar_binary(const T1 &x, const T2 &y, const F &f)
Base template function for vectorization of binary scalar functions defined by applying a functor to ...
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< T >::type plain_type_t
The lgamma implementation in stan-math is based on either the reentrant safe lgamma_r implementation ...