Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
std::inner_product(3)	      C++ Standard Libary	 std::inner_product(3)

NAME
       std::inner_product - std::inner_product

Synopsis
	  Defined in header <numeric>
	  template< class InputIt1, class InputIt2, class
	  T >

	  T  inner_product(  InputIt1  first1,	InputIt1		(until
       C++20)
	  last1,

	  InputIt2 first2, T init );
	  template< class InputIt1, class InputIt2, class
	  T >

	  constexpr  T	inner_product(	InputIt1  first1,		(since
       C++20)
	  InputIt1 last1,

	  InputIt2 first2, T init );
	  template< class InputIt1, class InputIt2, class
	  T,
							   (1)
	  class	BinaryOperation1, class	BinaryOperation2 >
	  T	   inner_product(	 InputIt1	first1,	      InputIt1
       (until C++20)
	  last1,
	  InputIt2 first2, T init,
	  BinaryOperation1 op1,

	  BinaryOperation2 op2 );			       (2)
	  template< class InputIt1, class InputIt2, class
	  T,

	  class	BinaryOperation1, class	BinaryOperation2 >
	  constexpr	  T	  inner_product(       InputIt1	       first1,
       (since C++20)
	  InputIt1 last1,
	  InputIt2 first2, T init,
	  BinaryOperation1 op1,

	  BinaryOperation2 op2 );

	  Computes  inner  product  (i.e. sum of products) or performs ordered
       map/reduce
	  operation on the range [first1, last1) and the  range	 beginning  at
       first2.

	  1)  Initializes  the accumulator acc with the	initial	value init and
       then

	  modifies it with the expression acc =	acc + *first1 *	*first2, then
	  modifies again with  the  expression	acc  =	acc  +	*(first1+1)  *
       (until C++20)
	  *(first2+1), etc
	  modifies it with the expression acc =	std::move(acc) + *first1 *
	  *first2,   then   modifies   again   with   the   expression	acc  =
       std::move(acc)  (since C++20)
	  + *(first1+1)	* *(first2+1), etc

	  until	reaching last1.	For built-in meaning of	+ and *, this computes
       inner product
	  of the two ranges.
	  2) Initializes the accumulator acc with the initial value  init  and
       then

	  modifies   it	 with  the  expression	acc  =	op1(acc,  op2(*first1,
       *first2)),
	  then	modifies  again	  with	 the   expression   acc	  =   op1(acc,
       (until C++20)
	  op2(*(first1+1), *(first2+1))), etc
	  modifies   it	  with	 the   expression  acc	=  op1(std::move(acc),
       op2(*first1,
	  *first2)),  then  modifies  again  with   the	  expression   acc   =
       (since C++20)
	  op1(std::move(acc), op2(*(first1+1), *(first2+1))), etc

	  until	reaching last1.

	  op1	   or	   op2	   must	    not	    have     side     effects.
       (until C++11)
	  op1 or op2 must not invalidate  any  iterators,  including  the  end
       (since C++11)
	  iterators, or	modify any elements of the range involved.

Parameters
	  first1, last1	- the first range of elements
	  first2	- the beginning	of the second range of elements
	  init		- initial value	of the sum of the products
			  binary  operation  function  object that will	be ap-
       plied. This "sum"
			  function takes a value returned by op2 and the  cur-
       rent value of the
			  accumulator and produces a new value to be stored in
       the
			  accumulator.

			  The  signature  of the function should be equivalent
       to the following:
	  op1		-
			  Ret fun(const	Type1 &a, const	Type2 &b);

			  The signature	does not need to have const &.
			  The types Type1 and Type2 must be such that  objects
       of types	T and
			  Type3	can be implicitly converted to Type1 and Type2
       respectively.
			  The  type  Ret must be such that an object of	type T
       can be assigned a
			  value	of type	Ret.
			  binary operation function object that	 will  be  ap-
       plied. This
			  "product"  function  takes one value from each range
       and produces a
			  new value.

			  The signature	of the function	should	be  equivalent
       to the following:

	  op2		- Ret fun(const	Type1 &a, const	Type2 &b);

			  The signature	does not need to have const &.
			  The  types Type1 and Type2 must be such that objects
       of types
			  InputIt1 and InputIt2	can be dereferenced  and  then
       implicitly
			  converted  to	Type1 and Type2	respectively. The type
       Ret must	be such
			  that an object of type Type3 can be assigned a value
       of type Ret.

Type requirements
	  -
	  InputIt1, InputIt2 must meet the requirements	 of  LegacyInputItera-
       tor.
	  -
	  ForwardIt1,  ForwardIt2  must	 meet  the  requirements of LegacyFor-
       wardIterator.
	  -
	  T  must  meet	 the  requirements  of	CopyAssignable	and   CopyCon-
       structible.

Return value
	  The final value of acc as described above.

Possible implementation
First version
	  template<class InputIt1, class InputIt2, class T>
	  constexpr // since C++20
	  T inner_product(InputIt1 first1, InputIt1 last1,
			  InputIt2 first2, T init)
	  {
	      while (first1 != last1) {
		   init	 =  std::move(init)  + *first1 * *first2; // std::move
       since C++20
		   ++first1;
		   ++first2;
	      }
	      return init;
	  }

Second version
	  template<class InputIt1, class InputIt2,
		   class T,
		   class BinaryOperation1, class BinaryOperation2>
	  constexpr // since C++20
	  T inner_product(InputIt1 first1, InputIt1 last1,
			  InputIt2 first2, T init,
			  BinaryOperation1 op1
			  BinaryOperation2 op2)
	  {
	      while (first1 != last1) {
		   init	 =  op1(std::move(init),  op2(*first1,	*first2));  //
       std::move since C++20
		   ++first1;
		   ++first2;
	      }
	      return init;
	  }

Notes
	  The parallelizable version of	this algorithm,	std::transform_reduce,
       requires	op1
	  and  op2  to	be commutative and associative,	but std::inner_product
       makes no	such
	  requirement, and always performs the operations in the order given.

Example
       // Run this code

	#include <numeric>
	#include <iostream>
	#include <vector>
	#include <functional>
	int main()
	{
	    std::vector<int> a{0, 1, 2,	3, 4};
	    std::vector<int> b{5, 4, 2,	3, 1};

	    int	r1 = std::inner_product(a.begin(), a.end(), b.begin(), 0);
	    std::cout << "Inner	product	of a and b: " << r1 << '\n';

	    int	r2 = std::inner_product(a.begin(), a.end(), b.begin(), 0,
					std::plus<>(), std::equal_to<>());
	    std::cout << "Number of pairwise matches between a and b: "	<<  r2
       << '\n';
	}

Output:
	Inner product of a and b: 21
	Number of pairwise matches between a and b: 2

See also
	  transform_reduce applies an invocable, then reduces out of order
	  (C++17)	   (function template)
	  accumulate	   sums	up a range of elements
			   (function template)
	  partial_sum	   computes the	partial	sum of a range of elements
			   (function template)

http://cppreference.com		  2022.07.31		 std::inner_product(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=std::inner_product&sektion=3&manpath=FreeBSD+Ports+15.0>

home | help