1 #ifndef STAN_MATH_REV_MAT_FUN_DOT_PRODUCT_HPP 2 #define STAN_MATH_REV_MAT_FUN_DOT_PRODUCT_HPP 12 #include <boost/utility/enable_if.hpp> 13 #include <boost/type_traits.hpp> 21 struct dot_product_store_type;
24 struct dot_product_store_type<var> {
29 struct dot_product_store_type<double> {
33 template<
typename T1,
typename T2>
34 class dot_product_vari :
public vari {
36 typename dot_product_store_type<T1>::type
v1_;
37 typename dot_product_store_type<T2>::type
v2_;
40 inline static double var_dot(vari** v1, vari** v2,
42 Eigen::VectorXd vd1(length), vd2(length);
43 for (
size_t i = 0; i <
length; i++) {
50 inline static double var_dot(
const T1* v1,
const T2* v2,
52 Eigen::VectorXd vd1(length), vd2(length);
53 for (
size_t i = 0; i <
length; i++) {
60 template<
typename Derived1,
typename Derived2>
61 inline static double var_dot(
const Eigen::DenseBase<Derived1> &v1,
62 const Eigen::DenseBase<Derived2> &v2) {
63 Eigen::VectorXd vd1(v1.size()), vd2(v1.size());
64 for (
int i = 0; i < v1.size(); i++) {
70 inline void chain(vari** v1, vari** v2) {
71 for (
size_t i = 0; i <
length_; i++) {
72 v1[i]->adj_ += adj_ * v2_[i]->val_;
73 v2[i]->adj_ += adj_ * v1_[i]->val_;
76 inline void chain(
double* v1, vari** v2) {
77 for (
size_t i = 0; i <
length_; i++) {
78 v2[i]->adj_ += adj_ * v1_[i];
81 inline void chain(vari** v1,
double* v2) {
82 for (
size_t i = 0; i <
length_; i++) {
83 v1[i]->adj_ += adj_ * v2_[i];
87 vari **shared = NULL) {
90 .
alloc(length_*
sizeof(vari*)));
91 for (
size_t i = 0; i <
length_; i++)
92 mem_v[i] = inv[i].vi_;
97 template<
typename Derived>
99 const Eigen::DenseBase<Derived> &inv,
100 vari **shared = NULL) {
101 if (shared == NULL) {
103 .
alloc(length_*
sizeof(vari*)));
104 for (
size_t i = 0; i <
length_; i++)
105 mem_v[i] =
inv(i).vi_;
111 inline void initialize(
double* &mem_d,
const double *ind,
112 double *shared = NULL) {
113 if (shared == NULL) {
115 .
alloc(length_*
sizeof(
double)));
116 for (
size_t i = 0; i <
length_; i++)
122 template<
typename Derived>
124 const Eigen::DenseBase<Derived> &ind,
125 double *shared = NULL) {
126 if (shared == NULL) {
127 mem_d =
reinterpret_cast<double*
> 129 for (
size_t i = 0; i <
length_; i++)
137 dot_product_vari(
typename dot_product_store_type<T1>::type v1,
138 typename dot_product_store_type<T2>::type v2,
140 : vari(var_dot(v1, v2, length)),
v1_(v1),
v2_(v2),
length_(length) {}
142 dot_product_vari(
const T1* v1,
const T2* v2,
size_t length,
143 dot_product_vari<T1, T2>* shared_v1 = NULL,
144 dot_product_vari<T1, T2>* shared_v2 = NULL) :
145 vari(var_dot(v1, v2, length)),
length_(length) {
146 if (shared_v1 == NULL) {
151 if (shared_v2 == NULL) {
157 template<
typename Derived1,
typename Derived2>
158 dot_product_vari(
const Eigen::DenseBase<Derived1> &v1,
159 const Eigen::DenseBase<Derived2> &v2,
160 dot_product_vari<T1, T2>* shared_v1 = NULL,
161 dot_product_vari<T1, T2>* shared_v2 = NULL) :
162 vari(var_dot(v1, v2)),
length_(v1.size()) {
163 if (shared_v1 == NULL) {
168 if (shared_v2 == NULL) {
174 template<
int R1,
int C1,
int R2,
int C2>
175 dot_product_vari(
const Eigen::Matrix<T1, R1, C1> &v1,
176 const Eigen::Matrix<T2, R2, C2> &v2,
177 dot_product_vari<T1, T2>* shared_v1 = NULL,
178 dot_product_vari<T1, T2>* shared_v2 = NULL) :
179 vari(var_dot(v1, v2)),
length_(v1.size()) {
180 if (shared_v1 == NULL) {
185 if (shared_v2 == NULL) {
191 virtual void chain() {
205 template<
typename T1,
int R1,
int C1,
typename T2,
int R2,
int C2>
207 typename boost::enable_if_c<boost::is_same<T1, var>::value ||
208 boost::is_same<T2, var>::value, var>::type
210 const Eigen::Matrix<T2, R2, C2>& v2) {
216 return var(
new dot_product_vari<T1, T2>(v1, v2));
226 template<
typename T1,
typename T2>
228 typename boost::enable_if_c<boost::is_same<T1, var>::value ||
229 boost::is_same<T2, var>::value,
var>::type
231 return var(
new dot_product_vari<T1, T2>(v1, v2, length));
242 template<
typename T1,
typename T2>
244 typename boost::enable_if_c<boost::is_same<T1, var>::value ||
245 boost::is_same<T2, var>::value,
var>::type
247 const std::vector<T2>& v2) {
251 return var(
new dot_product_vari<T1, T2>(&v1[0], &v2[0], v1.size()));
T value_of(const fvar< T > &v)
Return the value of the specified variable.
dot_product_store_type< T1 >::type v1_
static stack_alloc memalloc_
void check_vector(const char *function, const char *name, const Eigen::Matrix< T, R, C > &x)
Check if the matrix is either a row vector or column vector.
size_t length(const std::vector< T > &x)
Independent (input) and dependent (output) variables for gradients.
dot_product_store_type< T2 >::type v2_
void initialize(T &x, const T &v)
fvar< T > dot_product(const Eigen::Matrix< fvar< T >, R1, C1 > &v1, const Eigen::Matrix< fvar< T >, R2, C2 > &v2)
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.
void * alloc(size_t len)
Return a newly allocated block of memory of the appropriate size managed by the stack allocator...
fvar< T > inv(const fvar< T > &x)