Sunday, December 17, 2023

Algorithms - Numerical

Overview
Numerical algorithms  operate on various types of containers such as sequence, associative and unordered to perform operations on the elements of a range to return a value or a sequence. 

Numerical Algorithm functions accepts parameters like 
  • iterators such as input, forward, output
  • binary function pointers or function objects. 
  • Unary values
The parameter type  BinaryOperation is a function that accepts two inputs of type T and returns a value of type T. For example, int adder(int i, int j) {return i + j;} or [](int i, int j) {return i + j;}

Details
NameDescription
  1. accumulate (
    InputIterator 
    first, InputIterator last, T init)
  2. accumulate (
    InputIterator 
    first, InputIterator last, T init, BinaryOperation binary_op)


Returns the result of accumulating all the values in the range [first, last] and init by performing the operation op as below. 
Here n represents number of elements in the range [first, last].
result = init  op *first op 
*(first+1)  op  *(first+2) op 
...  
*(first+n-2) op *(first+n-1)
Note that: 
  1. Uses operator+ for op
  2. Uses binary_op  for op
Example
auto il = {10,20,30};
//1
//prints 160 (100+10+20+30)
cout << accumulate (begin(il),  end(il), 100) << endl;

//2
//prints 600000 (100*10*20*30)
cout << accumulate (begin(il),  end(il), 100, multiplies<int>()) << endl;
  1. OutputIterator partial_sum (
    InputIterator first, InputIterator last, OutputIterator result)
  2. OutputIterator partial_sum (
    InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op)

Assigns to every element in the range starting at result the partial sum of the corresponding elements in the range [first,last] after performing the operation as below.
Here n represents number of elements in the range [first, last].
*result=*first
*(result+1) = *result op *(first+1)
*(result+2) = *(result+1) op *(first+2)
                ...
*(result+n-1) = *(result+n-2) op *(first+n-1)
 Note that:
  1. Uses operator+ for op
  2. Uses binary_op  for op
Returns an iterator pointing to past the last element of the destination sequence where resulting elements have been stored.
Example
auto il = {10,20,30};
vector<int> v(3);

//1
//v:{10,30,60} v[0]=10 v[1] = 10+20  v[2] = 30+30
//itr:end(v)
auto itr = partial_sum  (begin(il),  end(il), begin(v));

//2
//v:{10,200,6000} v[0]=10 v[1] = 10*20  v[2] = 200*30
//itr2:end(v)
auto itr2 = partial_sum  (begin(il),  end(il), begin(v),multiplies<int>());
  1. inner_product (
    InputIterator first, InputIterator last, 
    InputIterator 
    first2, init)
  2. inner_product (
    InputIterator first, InputIterator last, 
    InputIterator 
    first2, init, BinaryOperation binary_op, BinaryOperation binary_op2)
Compute cumulative inner product of range.
Returns the result of accumulating init with the inner products of the pairs formed by the elements of two ranges starting at first and first2.
Here n represents number of elements in the range [first, last].
result = init op
(*first op2 *first2) op
(*(first+1) op2 *(first2+1)) op
...
(*(first+n-1) op2 *(first2+n-1)) 
Note that 
  1. Uses operator+ for op and operator* for op2
  2. Uses binary_op  for op and binary_op2 for op2
Example
auto il = {10,20,30};
//1
//prints 1500 (100+(10*10)+(20*20)+(30*30))
cout << inner_product (begin(il), end(il), begin(il), 100) << endl;

//2
//prints 4800000 (100*(10+10)*(20+20)*(30+30))
cout << inner_product (begin(il), end(il), begin(il), 100, multiplies<int>(), plus<int>()) << endl;

void iota (ForwardIterator first, ForwardIterator last, T val)
Store increasing sequence. Assigns to every element in the range [first,last] successive values of val, as if incremented with ++val after each element is written as below.
Here n represents number of elements in the range [first, last].
*first =  val
*(first+1) =  val +1
*(first+2) =  val +2
            ...
*(first+n-1) =  val +n-1
Example:
vector<int> v(3);
//v:{100,101,102}  v[0]=100  v[1]=100+1 v[2]=100+2
iota(begin(v),end(v),100);
  1. OutputIterator adjacent_difference (
    InputIterator first, InputIterator last, OutputIterator result)
  2. OutputIterator adjacent_difference (
    InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op)


Compute adjacent difference of range. Assigns to every element in the range starting at result the difference between its corresponding element in the range [first,last] and the one preceding it as below.
Here n represents number of elements in the range [first, last].
*result=*first
*(result+1) = *(first+1) op *first
...
*(result+2) = *(first+2) op *(first+1)
*(result+n-1) = *(first+n-1) op *(first+n-2)
Note that
  1. Uses operator- for op
  2. Uses binary_op  for op
Returns an iterator pointing to past the last element of the destination sequence where resulting elements have been stored.
Example
auto il = {10,20,30};
vector<int> v(3);

//1
//v:{10,10,10} v[0]=10 v[1] = 20-10  v[2] = 30-20
//itr:end(v)
auto itr = adjacent_difference  (begin(il),  end(il), begin(v));
    
//2
//v:{10,200,600} v[0]=10 v[1] = 20*10  v[2] = 30*20
//itr2:end(v)
auto itr2 = adjacent_difference  (begin(il),  end(il), begin(v),multiplies<int>());

The example depicts the usage.

Summary of Examples
NameDescriptiongithubwandbox
  Example       Usage   source    output      source + output   





No comments:

Post a Comment