Automatic Differentiation
 
Loading...
Searching...
No Matches
multiply.hpp
Go to the documentation of this file.
1#ifndef STAN_MATH_PRIM_FUN_MULTIPLY_HPP
2#define STAN_MATH_PRIM_FUN_MULTIPLY_HPP
3
9#include <type_traits>
10
11namespace stan {
12namespace math {
13
24template <typename Mat, typename Scal, require_stan_scalar_t<Scal>* = nullptr,
25 require_eigen_t<Mat>* = nullptr,
26 require_all_not_st_var<Scal, Mat>* = nullptr,
27 require_all_not_complex_t<Scal, value_type_t<Mat>>* = nullptr>
28inline auto multiply(Mat&& m, Scal c) {
29 auto&& m_ref = to_ref(std::forward<Mat>(m));
30 return make_holder(
31 [c](auto&& m_) { return c * std::forward<decltype(m_)>(m_); },
32 std::forward<decltype(m_ref)>(m_ref));
33}
34
47template <typename Mat, typename Scal,
50inline auto multiply(Mat&& m, Scal c) {
51 auto&& m_ref = to_ref(std::forward<Mat>(m));
52 return make_holder(
53 [c](auto&& m_) { return c * std::forward<decltype(m_)>(m_); },
54 std::forward<decltype(m_ref)>(m_ref));
55}
56
69template <typename Mat, typename Scal,
72inline auto multiply(const Scal& m, Mat&& c) {
73 auto&& c_ref = to_ref(std::forward<Mat>(c));
74 return make_holder(
75 [m](auto&& c_) { return m * std::forward<decltype(c_)>(c_); },
76 std::forward<decltype(c_ref)>(c_ref));
77}
78
89template <typename Scal, typename Mat, require_stan_scalar_t<Scal>* = nullptr,
90 require_eigen_t<Mat>* = nullptr,
91 require_all_not_st_var<Scal, Mat>* = nullptr,
92 require_all_not_complex_t<Scal, value_type_t<Mat>>* = nullptr>
93inline auto multiply(Scal c, Mat&& m) {
94 auto&& m_ref = to_ref(std::forward<Mat>(m));
95 return make_holder(
96 [c](auto&& m_) { return c * std::forward<decltype(m_)>(m_); },
97 std::forward<decltype(m_ref)>(m_ref));
98}
99
114template <typename Mat1, typename Mat2,
117inline auto multiply(Mat1&& m1, Mat2&& m2) {
118 auto&& m1_ref = to_ref(std::forward<Mat1>(m1));
119 auto&& m2_ref = to_ref(std::forward<Mat2>(m2));
120 check_size_match("multiply", "Columns of m1", m1_ref.cols(), "Rows of m2",
121 m2_ref.rows());
122 return make_holder(
123 [](auto&& m1_, auto&& m2_) {
124 return std::forward<decltype(m1_)>(m1_)
125 * std::forward<decltype(m2_)>(m2_);
126 },
127 std::forward<decltype(m1_ref)>(m1_ref),
128 std::forward<decltype(m2_ref)>(m2_ref));
129}
130
145template <typename Mat1, typename Mat2,
149inline auto multiply(Mat1&& m1, Mat2&& m2) {
150 auto&& m1_ref = to_ref(std::forward<Mat1>(m1));
151 auto&& m2_ref = to_ref(std::forward<Mat2>(m2));
152 check_size_match("multiply", "Columns of m1", m1_ref.cols(), "Rows of m2",
153 m2_ref.rows());
154 return make_holder(
155 [](auto&& m1_, auto&& m2_) {
156 return std::forward<decltype(m1_)>(m1_).lazyProduct(
157 std::forward<decltype(m2_)>(m2_));
158 },
159 std::forward<decltype(m1_ref)>(m1_ref),
160 std::forward<decltype(m2_ref)>(m2_ref));
161}
162
176template <typename RowVec, typename ColVec,
177 require_not_var_t<return_type_t<RowVec, ColVec>>* = nullptr,
178 require_eigen_row_and_col_t<RowVec, ColVec>* = nullptr>
179inline auto multiply(RowVec&& rv, ColVec&& v) {
180 check_multiplicable("multiply", "rv", rv, "v", v);
181 return dot_product(std::forward<RowVec>(rv), std::forward<ColVec>(v));
182}
183
193template <typename Scalar1, typename Scalar2,
195inline return_type_t<Scalar1, Scalar2> multiply(Scalar1 m, Scalar2 c) {
196 return c * m;
197}
198
199} // namespace math
200} // namespace stan
201
202#endif
require_any_t< is_complex< std::decay_t< Types > >... > require_any_complex_t
Require any of the types satisfy is_complex.
require_all_t< container_type_check_base< is_eigen, value_type_t, TypeCheck, Check >... > require_all_eigen_vt
Require all of the types satisfy is_eigen.
Definition is_eigen.hpp:191
require_all_t< is_eigen< std::decay_t< Types > >... > require_all_eigen_t
Require all of the types satisfy is_eigen.
Definition is_eigen.hpp:123
require_t< is_eigen< std::decay_t< T > > > require_eigen_t
Require type satisfies is_eigen.
Definition is_eigen.hpp:113
require_not_t< is_eigen< std::decay_t< T > > > require_not_eigen_t
Require type does not satisfy is_eigen.
Definition is_eigen.hpp:118
require_all_t< is_stan_scalar< std::decay_t< Types > >... > require_all_stan_scalar_t
Require all of the types satisfy is_stan_scalar.
typename return_type< Ts... >::type return_type_t
Convenience type for the return type of the specified template parameters.
auto multiply(Mat1 &&m1, Mat2 &&m2)
Return the product of the specified matrices.
Definition multiply.hpp:20
void check_multiplicable(const char *function, const char *name1, const T1 &y1, const char *name2, const T2 &y2)
Check if the matrices can be multiplied.
auto make_holder(F &&func, Args &&... args)
Calls given function with given arguments.
Definition holder.hpp:481
ref_type_t< T && > to_ref(T &&a)
This evaluates expensive Eigen expressions.
Definition to_ref.hpp:18
void check_size_match(const char *function, const char *name_i, T_size1 i, const char *name_j, T_size2 j)
Check if the provided sizes match.
auto dot_product(const T_a &a, const T_b &b)
Returns the dot product of the specified vectors.
require_not_t< math::conjunction< is_eigen_row_vector< Row >, is_eigen_col_vector< Col > > > require_not_eigen_row_and_col_t
Require Row is not a row vector and Col is not a column vector.
std::enable_if_t< Check::value > require_t
If condition is true, template is enabled.
The lgamma implementation in stan-math is based on either the reentrant safe lgamma_r implementation ...