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 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
       order 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
       order 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
       satisfied, 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 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  ob-
       jects 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  ob-
       jects 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.

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,
       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 <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
       cannot modify the
									ranges
       involved
	  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)

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.1.quarterly>

home | help