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 last1,   (1) (constexpr since
     C++20)

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

		  class BinaryOp1, class BinaryOp2 >
	T inner_product( InputIt1 first1, InputIt1 last1,   (2) (constexpr since
     C++20)
			 InputIt2 first2, T init,

			 BinaryOp1 op1, BinaryOp2 op2 );

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

	1)  Initializes  the  accumulator acc (of type T) with the initial value
     init and then
	modifies it with the expression
	acc = acc + (*i1) * (*i2)
	(until C++11)
	acc = std::move(acc) + (*i1) * (*i2)
	(since C++11) for every iterator i1 in the range [first1, last1) in  or-
     der and its
	corresponding iterator i2 in the range beginning at first2. For built-in
     meaning of
	+ and *, this computes inner product of the two ranges.
	2)  Initializes  the  accumulator acc (of type T) with the initial value
     init and then
	modifies it with the expression
	acc = op1(acc, op2(*i1, *i2))
	(until C++11)
	acc = op1(std::move(acc), op2(*i1, *i2))
	(since C++11) for every iterator i1 in the range [first1, last1) in  or-
     der and its
	corresponding iterator i2 in the range beginning at first2.

	Given last2 as the std::distance(first1, last1)
	th next iterator of first2, if any of the following conditions is satis-
     fied, the
	behavior is undefined:

	  * T is not CopyConstructible.
	  * T is not CopyAssignable.
	  *  op1  or  op2  modifies  any  element of [first1, last1) or [first2,
     last2).
	  * op1 or op2 invalidates any iterator or subrange in	[first1,  last1]
     or
	    [first2, last2].

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 applied.
     This "sum"
			function takes a value returned by op2 and  the  current
     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	applied.
     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 im-
     plicitly
			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 LegacyInputIterator.
	-
	ForwardIt1, ForwardIt2 must meet the requirements of LegacyForwardItera-
     tor.

Return value
	acc after all modifications.

Possible implementation
					 inner_product (1)
	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++11
		++first1;
		++first2;
	    }

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

	    return init;
	}

Notes
	The parallelizable version of this algorithm, std::transform_reduce, re-
     quires 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 <functional>
      #include <iostream>
      #include <numeric>
      #include <vector>

      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

	Defect reports

	The  following	behavior-changing  defect  reports were applied retroac-
     tively to
	previously published C++ standards.

	   DR	  Applied to	      Behavior as published		 Correct
     behavior
	LWG 242   C++98      op1 and op2 could not have side effects  they  can-
     not modify the
								      ranges in-
     volved
	LWG  2055   C++11	acc  was  not moved while being 	   it is
     moved
	(P0616R0)	     accumulated

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

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

home | help