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

FreeBSD Manual Pages

  
 
  

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

NAME
       std::transform_reduce - std::transform_reduce

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

	  T transform_reduce( InputIt1		     (since C++17)
	  first1, InputIt1 last1,		     (until C++20)
	  InputIt2 first2,

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

	  constexpr
	  T transform_reduce( InputIt1		     (since C++20)
	  first1, InputIt1 last1,
	  InputIt2 first2,

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

	  class	T,
	  class	BinaryReductionOp,
	  class	  BinaryTransformOp   >					(since
       C++17)
	  T  transform_reduce(	 InputIt1				(until
       C++20)
	  first1, InputIt1 last1,
	  InputIt2 first2,
	  T init,
	  BinaryReductionOp reduce,

	  BinaryTransformOp transform );
	  template< class InputIt1, class
	  InputIt2,

	  class	T,
	  class	BinaryReductionOp,
	  class	BinaryTransformOp >
	  constexpr							(since
       C++20)
	  T transform_reduce( InputIt1
	  first1, InputIt1 last1,
	  InputIt2 first2,
	  T init,
	  BinaryReductionOp reduce,

	  BinaryTransformOp transform );
	  template< class InputIt,

	  class	T,
	  class	BinaryReductionOp,
	  class			      UnaryTransformOp			     >
       (since C++17)
	  T		transform_reduce(	     InputIt		first,
       (until C++20)
	  InputIt last,
	  T init,			     (1)
	  BinaryReductionOp reduce,

	  UnaryTransformOp transform );
	  template< class InputIt, class T,

	  class	BinaryReductionOp,
	  class	UnaryTransformOp >
	  constexpr
	  T	  transform_reduce(	  InputIt	 first,		   (2)
       (since C++20)
	  InputIt last,
	  T init,
	  BinaryReductionOp reduce,

	  UnaryTransformOp transform );
	  template< class ExecutionPolicy,

	  class	ForwardIt1, class
	  ForwardIt2, class T >
	  T transform_reduce(
	  ExecutionPolicy&&	policy,					   (4)
       (since C++17)
	  ForwardIt1 first1, ForwardIt1
	  last1,				     (3)
	  ForwardIt2 first2,

	  T init );
	  template< class ExecutionPolicy,

	  class	ForwardIt1, class
	  ForwardIt2, class T,
	  class	BinaryReductionOp,
	  class	BinaryTransformOp >
	  T transform_reduce(
	  ExecutionPolicy&&	policy,					   (5)
       (since C++17)
	  ForwardIt1 first1, ForwardIt1
	  last1,
	  ForwardIt2 first2,
	  T init,
	  BinaryReductionOp reduce,

	  BinaryTransformOp transform );
	  template< class ExecutionPolicy,

	  class	ForwardIt, class T,
	  class	BinaryReductionOp,
	  class	UnaryTransformOp >
	  T	transform_reduce(					   (6)
       (since C++17)
	  ExecutionPolicy&& policy,
	  ForwardIt first, ForwardIt last,
	  T init,
	  BinaryReductionOp reduce,

	  UnaryTransformOp transform );

	  1) Equivalent	to std::transform_reduce(first1, last1,	first2,	 init,
       std::plus<>(),
	  std::multiplies<>());,  effectively  parallelized version of the de-
       fault
	  std::inner_product
	  2) Applies transform to  each	 pair  of  elements  from  the	ranges
       [first; last) and the
	  range	 starting at first2 and	reduces	the results (possibly permuted
       and aggregated
	  in unspecified manner) along with the	initial	value init over	reduce
	  3) Applies transform to each element in the range [first; last)  and
       reduces the
	  results  (possibly  permuted	and  aggregated	in unspecified manner)
       along with the
	  initial value	init over reduce.
	  4-6) Same as (1-3), but executed according to	 policy.  These	 over-
       loads do	not
	  participate in overload resolution unless
	  std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>
	  (until C++20)
	  std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>
	  (since C++20)	is true.

	  The  behavior	 is  non-deterministic if reduce is not	associative or
       not commutative.

	  The behavior is undefined if reduce, or transform modifies any  ele-
       ment or
	  invalidates  any  iterator  in the input ranges, including their end
       iterators.

Parameters
	  first, last		-	    the	range of elements to apply the
       algorithm to
	  init			-	    the	initial	value of the  general-
       ized sum
	  policy		 -	      the execution policy to use. See
       execution policy
					    for	details.
					    binary FunctionObject that will be
       applied in
	  reduce		-	    unspecified	order to  the  results
       of transform, the
					    results of other reduce and	init.
					    unary   or	binary	FunctionObject
       that will be
	  transform		-	    applied to each element of the in-
       put range(s). The
					    return type	must be	acceptable  as
       input to	reduce

Type requirements
	  -
	  T  must  meet	 the requirements of MoveConstructible in order	to use
       overloads (3,6).
	  and the result of the	expressions reduce(init, transform(*first)),
	  reduce(transform(*first),  init),  reduce(init,   init),   and   re-
       duce(transform(*first),
	  transform(*first)) must be convertible to T
	  -
	  T  must  meet	 the requirements of MoveConstructible in order	to use
       overloads (2,5).
	  and the result of the	 expressions  reduce(init,  transform(*first1,
       *first2)),
	  reduce(transform(*first1, *first2), init), reduce(init, init), and
	  reduce(transform(*first1,   *first2),	 transform(*first1,  *first2))
       must be convertible
	  to T
	  -
	  InputIt must meet the	requirements of	LegacyInputIterator.
	  -
	  ForwardIt must meet the requirements of LegacyForwardIterator.

Return value
	  2) Generalized sum of	init and transform(*first,*first2),
	  transform(*(first+1),*(first2+1)), ..., over reduce
	  3)  Generalized  sum	 of   init   and   transform(*first),	trans-
       form(*(first+1)), ...
	  transform(*(last-1)) over reduce,

	  where	generalized sum	GSUM(op, a
	  1, ..., a
	  N) is	defined	as follows:

	    * if N=1, a
	      1
	    * if N > 1,	op(GSUM(op, b
	      1, ..., b
	      K), GSUM(op, b
	      M, ..., b
	      N)) where

		     * b
		       1, ..., b
		       N may be	any permutation	of a1, ..., aN and
		     * 1 < K+1 = M  N

	  in other words, the results of transform or of reduce	may be grouped
       and arranged in
	  arbitrary order.

Complexity
	  1,2,4,5)  O(last1  -	first1)	applications each of reduce and	trans-
       form.
	  3,6) O(last -	first) applications each of transform and reduce.

Exceptions
	  The overloads	with a template	parameter named	ExecutionPolicy	report
       errors as
	  follows:

	    * If execution of a	function invoked  as  part  of	the  algorithm
       throws an exception
	      and ExecutionPolicy is one of the	standard policies, std::termi-
       nate is called.
	      For  any	other ExecutionPolicy, the behavior is implementation-
       defined.
	    * If the algorithm fails to	 allocate  memory,  std::bad_alloc  is
       thrown.

Notes
	  In the unary-binary overload (3,6), transform	is not applied to init

	  If first == last or first1 ==	last1, init is returned, unmodified

Example
	  transform_reduce can be used to parallelize std::inner_product:

       // Run this code

	#include <algorithm>
	#include <execution>
	#include <iostream>
	#include <iterator>
	#include <locale>
	#include <numeric>
	#include <vector>

	//  to	parallelize non-associate accumulative operation, you'd	better
       choose
	// transform_reduce instead of reduce; e.g., a + b * b != b + a	* a
	void print_sum_squared(long const num)
	{
	    std::cout.imbue(std::locale{"en_US.UTF8"});
	    std::cout << "num =	" << num << '\n';

	    // create  an  immutable  vector  filled  with  pattern:  1,2,3,4,
       1,2,3,4 ...
	    const std::vector<long> v {	[n = num * 4] {
		std::vector<long> v;
		v.reserve(n);
		std::generate_n(std::back_inserter(v),	n,  [i=0]()  mutable {
       return 1	+ i++ %	4; });
		return v;
	    }()};

	    auto squared_sum = [](auto sum, auto val) {	return	sum  +	val  *
       val; };

	    auto    sum1    =	 std::accumulate(v.cbegin(),   v.cend(),   0L,
       squared_sum);
	    std::cout << "accumulate():	" << sum1 << '\n';

	    auto sum2 =	std::reduce(std::execution::par, v.cbegin(), v.cend(),
       0L, squared_sum);
	    std::cout << "reduce(): " << sum2 << '\n';

	    auto sum3 =	std::transform_reduce(std::execution::par, v.cbegin(),
       v.cend(), 0L,
					      std::plus{},
					      [](auto val) { return val	* val;
       });
	    std::cout << "transform_reduce(): "	<< sum3	<< '\n';

	    std::cout << '\n';
	}

	int main()
	{
	    print_sum_squared(1);
	    print_sum_squared(1'000);
	    print_sum_squared(1'000'000);
	}

Possible output:
	num = 1
	accumulate(): 30
	reduce(): 30
	transform_reduce(): 30

	num = 1,000
	accumulate(): 30,000
	reduce(): -7,025,681,278,312,630,348
	transform_reduce(): 30,000

	num = 1,000,000
	accumulate(): 30,000,000
	reduce(): -5,314,886,882,370,003,032
	transform_reduce(): 30,000,000

See also
	  accumulate sums up a range of	elements
		     (function template)
		     applies a function	to a range of  elements,  storing  re-
       sults in	a
	  transform  destination range
		     (function template)
	  reduce     similar to	std::accumulate, except	out of order
	  (C++17)    (function template)

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

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

home | help