◆ transform_reduce() [2/2]

template<typename T , typename U , typename V , typename Binop1 , typename Binop2 >
V boost::simd::transform_reduce ( T const *  first1,
T const *  last1,
U const *  first2,
Binop1  transform,
init,
Binop2  gsum 
)

Applies transform binary operator to each element in the range [first1; last1) and [first2, ) and reduces the results (possibly permuted and aggregated in unspecified manner) along with the initial value init over generalized sum gsum binary operator.

Parameters
first1Beginning of the first range of elements to transform
last1End of the first range of elements to transform
first2Beginning of the second range of elements to transform
transformbinary operation function object that will be applied.
initthe initial value of the reduction
gsumbinary operation function object that will be applied.
Requirement
  • T, U and V must be types which can be used within
  • transform and gsum must be a polymorphic unary function object, i.e callable on generic types, at least
    • transform must be able to be called on couples (T, U) and (boost::simd::pack<T>, boost::simd::pack<U>) to produce respectively V and boost::simd::pack<V> types
    • gsum must be able to be called on V and boost::simd::pack<V> types to produce the same output type.
  • returns the generalized sum of init and transform(*first1, *first2), transform(*(first+1), *(first2+1)), ., transform(*(last1-1), *(first2-(last1-first1)-1)) over binary_op,

where generalized sum GSUM(op, a1, ., aN) is defined as follows:

if N=1, a1 if N > 1, op(GSUM(op, b1, ., bK), GSUM(op, bM, ., bN)) where

  • b1, ., bN may be any permutation of a1, ., aN and
  • 1 < K+1 = M <= N

in other words, the results of transform may be grouped and arranged in arbitrary order. a pointer to the element past the last element transformed.

Note:
  • If the range is empty, init is returned, unmodified
Example:

The following code uses simd::transform to compute the dot-product of the values stored in two std::vector.

#include <boost/simd/algorithm/transform_reduce.hpp>
#include <boost/simd/function/sqr.hpp>
#include <iostream>
#include <vector>
int main()
{
namespace bs = boost::simd;
std::vector<float> d{1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f} ;
std::vector<float> e{1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f} ;
auto s1 = bs::transform_reduce( d.data(), d.data()+10, e.data(), bs::multiplies, 0.0f, bs::plus);
std::cout << "s1 = " << s1 << std::endl;
auto s2 = bs::transform_reduce( d.data()+1, d.data()+10, e.data()+1, bs::multiplies, 1.0f, bs::plus);
std::cout << "s2 = " << s2 << std::endl;
auto s3 = bs::transform_reduce( d.data()+1, d.data()+10, e.data(), bs::multiplies, 0.0f, bs::plus);
std::cout << "s3 = " << s3 << std::endl;
auto s4 = bs::transform_reduce( d.data(), d.data()+10, e.data(), bs::multiplies, 1.0f, bs::multiplies);
std::cout << "s4 = " << s4 << std::endl;
return 0;
}
possible output:
s1 = 385
s2 = 385
s3 = 330
s4 = 1.31682e+13