1 /*
2  *  Copyright 2008-2013 NVIDIA Corporation
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License.
15  */
16 
17 
18 /*! \file inner_product.h
19  *  \brief Mathematical inner product between ranges
20  */
21 
22 #pragma once
23 
24 #include <thrust/detail/config.h>
25 #include <thrust/detail/execution_policy.h>
26 
27 namespace thrust
28 {
29 
30 
31 /*! \addtogroup reductions
32  *  \{
33  *  \addtogroup transformed_reductions Transformed Reductions
34  *  \ingroup reductions
35  *  \{
36  */
37 
38 
39 /*! \p inner_product calculates an inner product of the ranges
40  *  <tt>[first1, last1)</tt> and <tt>[first2, first2 + (last1 - first1))</tt>.
41  *
42  *  Specifically, this version of \p inner_product computes the sum
43  *  <tt>init + (*first1 * *first2) + (*(first1+1) * *(first2+1)) + ... </tt>
44  *
45  *  The algorithm's execution is parallelized as determined by \p exec.
46  *
47  *  \param exec The execution policy to use for parallelization.
48  *  \param first1 The beginning of the first sequence.
49  *  \param last1 The end of the first sequence.
50  *  \param first2 The beginning of the second sequence.
51  *  \param init Initial value of the result.
52  *  \return The inner product of sequences <tt>[first1, last1)</tt>
53  *          and <tt>[first2, last2)</tt> plus \p init.
54  *
55  *  \tparam DerivedPolicy The name of the derived execution policy.
56  *  \tparam InputIterator1 is a model of <a href="http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a>,
57  *  \tparam InputIterator2 is a model of <a href="http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a>,
58  *  \tparam OutputType is a model of <a href="http://www.sgi.com/tech/stl/Assignable.html">Assignable</a>,
59  *          and if \c x is an object of type \p OutputType, and \c y is an object of \p InputIterator1's \c value_type,
60  *          and \c z is an object of \p InputIterator2's \c value_type, then <tt>x + y * z</tt> is defined
61  *          and is convertible to \p OutputType.
62  *
63  *  The following code demonstrates how to use \p inner_product to
64  *  compute the dot product of two vectors using the \p thrust::host execution policy for parallelization.
65  *
66  *  \code
67  *  #include <thrust/inner_product.h>
68  *  #include <thrust/execution_policy.h>
69  *  ...
70  *  float vec1[3] = {1.0f, 2.0f, 5.0f};
71  *  float vec2[3] = {4.0f, 1.0f, 5.0f};
72  *
73  *  float result = thrust::inner_product(thrust::host, vec1, vec1 + 3, vec2, 0.0f);
74  *
75  *  // result == 31.0f
76  *  \endcode
77  *
78  *  \see http://www.sgi.com/tech/stl/inner_product.html
79  */
80 template<typename DerivedPolicy,
81          typename InputIterator1,
82          typename InputIterator2,
83          typename OutputType>
84 __host__ __device__
85 OutputType inner_product(const thrust::detail::execution_policy_base<DerivedPolicy> &exec,
86                          InputIterator1 first1,
87                          InputIterator1 last1,
88                          InputIterator2 first2,
89                          OutputType init);
90 
91 
92 /*! \p inner_product calculates an inner product of the ranges
93  *  <tt>[first1, last1)</tt> and <tt>[first2, first2 + (last1 - first1))</tt>.
94  *
95  *  Specifically, this version of \p inner_product computes the sum
96  *  <tt>init + (*first1 * *first2) + (*(first1+1) * *(first2+1)) + ... </tt>
97  *
98  *  Unlike the C++ Standard Template Library function <tt>std::inner_product</tt>,
99  *  this version offers no guarantee on order of execution.
100  *
101  *  \param first1 The beginning of the first sequence.
102  *  \param last1 The end of the first sequence.
103  *  \param first2 The beginning of the second sequence.
104  *  \param init Initial value of the result.
105  *  \return The inner product of sequences <tt>[first1, last1)</tt>
106  *          and <tt>[first2, last2)</tt> plus \p init.
107  *
108  *  \tparam InputIterator1 is a model of <a href="http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a>,
109  *  \tparam InputIterator2 is a model of <a href="http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a>,
110  *  \tparam OutputType is a model of <a href="http://www.sgi.com/tech/stl/Assignable.html">Assignable</a>,
111  *          and if \c x is an object of type \p OutputType, and \c y is an object of \p InputIterator1's \c value_type,
112  *          and \c z is an object of \p InputIterator2's \c value_type, then <tt>x + y * z</tt> is defined
113  *          and is convertible to \p OutputType.
114  *
115  *  The following code demonstrates how to use \p inner_product to
116  *  compute the dot product of two vectors.
117  *
118  *  \code
119  *  #include <thrust/inner_product.h>
120  *  ...
121  *  float vec1[3] = {1.0f, 2.0f, 5.0f};
122  *  float vec2[3] = {4.0f, 1.0f, 5.0f};
123  *
124  *  float result = thrust::inner_product(vec1, vec1 + 3, vec2, 0.0f);
125  *
126  *  // result == 31.0f
127  *  \endcode
128  *
129  *  \see http://www.sgi.com/tech/stl/inner_product.html
130  */
131 template<typename InputIterator1, typename InputIterator2, typename OutputType>
132 OutputType inner_product(InputIterator1 first1, InputIterator1 last1,
133                          InputIterator2 first2, OutputType init);
134 
135 
136 /*! \p inner_product calculates an inner product of the ranges
137  *  <tt>[first1, last1)</tt> and <tt>[first2, first2 + (last1 - first1))</tt>.
138  *
139  *  This version of \p inner_product is identical to the first, except that is uses
140  *  two user-supplied function objects instead of \c operator+ and \c operator*.
141  *
142  *  Specifically, this version of \p inner_product computes the sum
143  *  <tt>binary_op1( init, binary_op2(*first1, *first2) ), ... </tt>
144  *
145  *  The algorithm's execution is parallelized as determined by \p exec.
146  *
147  *  \param exec The execution policy to use for parallelization.
148  *  \param first1 The beginning of the first sequence.
149  *  \param last1 The end of the first sequence.
150  *  \param first2 The beginning of the second sequence.
151  *  \param init Initial value of the result.
152  *  \param binary_op1 Generalized addition operation.
153  *  \param binary_op2 Generalized multiplication operation.
154  *  \return The inner product of sequences <tt>[first1, last1)</tt> and <tt>[first2, last2)</tt>.
155  *
156  *  \tparam DerivedPolicy The name of the derived execution policy.
157  *  \tparam InputIterator1 is a model of <a href="http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a>,
158  *          and \p InputIterator1's \c value_type is convertible to \p BinaryFunction2's \c first_argument_type.
159  *  \tparam InputIterator2 is a model of <a href="http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a>.
160  *          and \p InputIterator2's \c value_type is convertible to \p BinaryFunction2's \c second_argument_type.
161  *  \tparam OutputType is a model of <a href="http://www.sgi.com/tech/stl/Assignable.html">Assignable</a>,
162  *          and \p OutputType is convertible to \p BinaryFunction1's \c first_argument_type.
163  *  \tparam BinaryFunction1 is a model of <a href="http://www.sgi.com/tech/stl/BinaryFunction.html">Binary Function</a>,
164  *          and \p BinaryFunction1's \c return_type is convertible to \p OutputType.
165  *  \tparam BinaryFunction2 is a model of <a href="http://www.sgi.com/tech/stl/BinaryFunction.html">Binary Function</a>,
166  *          and \p BinaryFunction2's \c return_type is convertible to \p BinaryFunction1's \c second_argument_type.
167  *
168  *  \code
169  *  #include <thrust/inner_product.h>
170  *  #include <thrust/execution_policy.h>
171  *  ...
172  *  float vec1[3] = {1.0f, 2.0f, 5.0f};
173  *  float vec2[3] = {4.0f, 1.0f, 5.0f};
174  *
175  *  float init = 0.0f;
176  *  thrust::plus<float>       binary_op1;
177  *  thrust::multiplies<float> binary_op2;
178  *
179  *  float result = thrust::inner_product(thrust::host, vec1, vec1 + 3, vec2, init, binary_op1, binary_op2);
180  *
181  *  // result == 31.0f
182  *  \endcode
183  *
184  *  \see http://www.sgi.com/tech/stl/inner_product.html
185  */
186 template<typename DerivedPolicy,
187          typename InputIterator1,
188          typename InputIterator2,
189          typename OutputType,
190          typename BinaryFunction1,
191          typename BinaryFunction2>
192 __host__ __device__
193 OutputType inner_product(const thrust::detail::execution_policy_base<DerivedPolicy> &exec,
194                          InputIterator1 first1,
195                          InputIterator1 last1,
196                          InputIterator2 first2,
197                          OutputType init,
198                          BinaryFunction1 binary_op1,
199                          BinaryFunction2 binary_op2);
200 
201 
202 /*! \p inner_product calculates an inner product of the ranges
203  *  <tt>[first1, last1)</tt> and <tt>[first2, first2 + (last1 - first1))</tt>.
204  *
205  *  This version of \p inner_product is identical to the first, except that is uses
206  *  two user-supplied function objects instead of \c operator+ and \c operator*.
207  *
208  *  Specifically, this version of \p inner_product computes the sum
209  *  <tt>binary_op1( init, binary_op2(*first1, *first2) ), ... </tt>
210  *
211  *  Unlike the C++ Standard Template Library function <tt>std::inner_product</tt>,
212  *  this version offers no guarantee on order of execution.
213  *
214  *  \param first1 The beginning of the first sequence.
215  *  \param last1 The end of the first sequence.
216  *  \param first2 The beginning of the second sequence.
217  *  \param init Initial value of the result.
218  *  \param binary_op1 Generalized addition operation.
219  *  \param binary_op2 Generalized multiplication operation.
220  *  \return The inner product of sequences <tt>[first1, last1)</tt> and <tt>[first2, last2)</tt>.
221  *
222  *  \tparam InputIterator1 is a model of <a href="http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a>,
223  *          and \p InputIterator1's \c value_type is convertible to \p BinaryFunction2's \c first_argument_type.
224  *  \tparam InputIterator2 is a model of <a href="http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a>.
225  *          and \p InputIterator2's \c value_type is convertible to \p BinaryFunction2's \c second_argument_type.
226  *  \tparam OutputType is a model of <a href="http://www.sgi.com/tech/stl/Assignable.html">Assignable</a>,
227  *          and \p OutputType is convertible to \p BinaryFunction1's \c first_argument_type.
228  *  \tparam BinaryFunction1 is a model of <a href="http://www.sgi.com/tech/stl/BinaryFunction.html">Binary Function</a>,
229  *          and \p BinaryFunction1's \c return_type is convertible to \p OutputType.
230  *  \tparam BinaryFunction2 is a model of <a href="http://www.sgi.com/tech/stl/BinaryFunction.html">Binary Function</a>,
231  *          and \p BinaryFunction2's \c return_type is convertible to \p BinaryFunction1's \c second_argument_type.
232  *
233  *  \code
234  *  #include <thrust/inner_product.h>
235  *  ...
236  *  float vec1[3] = {1.0f, 2.0f, 5.0f};
237  *  float vec2[3] = {4.0f, 1.0f, 5.0f};
238  *
239  *  float init = 0.0f;
240  *  thrust::plus<float>       binary_op1;
241  *  thrust::multiplies<float> binary_op2;
242  *
243  *  float result = thrust::inner_product(vec1, vec1 + 3, vec2, init, binary_op1, binary_op2);
244  *
245  *  // result == 31.0f
246  *  \endcode
247  *
248  *  \see http://www.sgi.com/tech/stl/inner_product.html
249  */
250 template<typename InputIterator1, typename InputIterator2, typename OutputType,
251          typename BinaryFunction1, typename BinaryFunction2>
252 OutputType inner_product(InputIterator1 first1, InputIterator1 last1,
253                          InputIterator2 first2, OutputType init,
254                          BinaryFunction1 binary_op1, BinaryFunction2 binary_op2);
255 
256 
257 /*! \} // end transformed_reductions
258  *  \} // end reductions
259  */
260 
261 } // end namespace thrust
262 
263 #include <thrust/detail/inner_product.inl>
264 
265