1 #ifndef STAN_MATH_PRIM_FUN_DOT_PRODUCT_HPP
2 #define STAN_MATH_PRIM_FUN_DOT_PRODUCT_HPP
3 
4 #include <stan/math/prim/meta.hpp>
5 #include <stan/math/prim/err.hpp>
6 #include <stan/math/prim/fun/Eigen.hpp>
7 #include <vector>
8 
9 namespace stan {
10 namespace math {
11 
12 /**
13  * Returns the dot product of the specified vectors.
14  *
15  * @param v1 First vector.
16  * @param v2 Second vector.
17  * @return Dot product of the vectors.
18  * @throw std::invalid_argument If the vectors are not the same
19  * size or if they are both not vector dimensioned.
20  */
21 template <typename Vec1, typename Vec2,
22           require_all_eigen_vector_t<Vec1, Vec2> * = nullptr,
23           require_not_var_t<return_type_t<Vec1, Vec2>> * = nullptr>
dot_product(const Vec1 & v1,const Vec2 & v2)24 inline auto dot_product(const Vec1 &v1, const Vec2 &v2) {
25   check_matching_sizes("dot_product", "v1", v1, "v2", v2);
26   return v1.dot(v2);
27 }
28 
29 /**
30  * Returns the dot product of the specified arrays.
31  *
32  * @param v1 First array.
33  * @param v2 Second array.
34  * @param length Length of both arrays.
35  */
36 template <typename Scalar1, typename Scalar2,
37           require_all_stan_scalar_t<Scalar1, Scalar2> * = nullptr,
38           require_all_not_var_t<Scalar1, Scalar2> * = nullptr>
dot_product(const Scalar1 * v1,const Scalar2 * v2,size_t length)39 inline auto dot_product(const Scalar1 *v1, const Scalar2 *v2, size_t length) {
40   return_type_t<Scalar1, Scalar2> result = 0;
41   for (size_t i = 0; i < length; i++) {
42     result += v1[i] * v2[i];
43   }
44   return result;
45 }
46 
47 /**
48  * Returns the dot product of the specified arrays.
49  *
50  * @param v1 First array.
51  * @param v2 Second array.
52  * @throw std::domain_error if the vectors are not the same size.
53  */
54 template <typename Scalar1, typename Scalar2, typename Alloc1, typename Alloc2,
55           require_all_stan_scalar_t<Scalar1, Scalar2> * = nullptr>
dot_product(const std::vector<Scalar1,Alloc1> & v1,const std::vector<Scalar2,Alloc2> & v2)56 inline return_type_t<Scalar1, Scalar2> dot_product(
57     const std::vector<Scalar1, Alloc1> &v1,
58     const std::vector<Scalar2, Alloc2> &v2) {
59   check_matching_sizes("dot_product", "v1", v1, "v2", v2);
60 
61   if (v1.size() == 0) {
62     return 0.0;
63   }
64 
65   return dot_product(as_column_vector_or_scalar(v1),
66                      as_column_vector_or_scalar(v2));
67 }
68 
69 }  // namespace math
70 }  // namespace stan
71 
72 #endif
73