2013-07-17 19:24:07 +02:00
|
|
|
.. highlight:: c
|
|
|
|
|
2013-08-27 19:17:17 +02:00
|
|
|
.. _arr_map_fold:
|
|
|
|
|
2014-10-17 18:15:19 +02:00
|
|
|
Functional constructs: map & fold
|
2013-07-17 19:24:07 +02:00
|
|
|
###########################################
|
|
|
|
|
2014-10-17 18:15:19 +02:00
|
|
|
Two standard functional constructs are provided:
|
2013-07-17 19:24:07 +02:00
|
|
|
|
2013-09-09 15:46:58 +02:00
|
|
|
* *map* that promotes a function acting on the array element to an array function, acting
|
2013-07-17 19:24:07 +02:00
|
|
|
element by element.
|
|
|
|
|
|
|
|
* *fold* is the reduction of a function on the array.
|
|
|
|
|
2013-08-22 16:55:51 +02:00
|
|
|
.. _map:
|
|
|
|
|
2013-07-17 19:24:07 +02:00
|
|
|
map
|
|
|
|
========================================================
|
|
|
|
* **Purpose** :
|
|
|
|
|
|
|
|
map promotes any function into an `array function`, acting term by term.
|
|
|
|
|
|
|
|
* **Synopsis** ::
|
|
|
|
|
|
|
|
template<class F> auto map (F f);
|
|
|
|
|
|
|
|
If `f` is a function, or a function object ::
|
|
|
|
|
2013-09-09 15:46:58 +02:00
|
|
|
T2 f(T1)
|
2013-07-17 19:24:07 +02:00
|
|
|
|
|
|
|
Then map(f) is a function::
|
2013-08-27 19:17:17 +02:00
|
|
|
|
|
|
|
template<ImmutableCuboidArray A> auto map(f) (A const &)
|
2013-07-17 19:24:07 +02:00
|
|
|
|
2014-10-17 18:15:19 +02:00
|
|
|
with:
|
2013-09-09 15:46:58 +02:00
|
|
|
* A::value_type == T1
|
2013-08-27 19:17:17 +02:00
|
|
|
* The returned type of map(f) models the :ref:`ImmutableCuboidArray` concept
|
2013-07-17 19:24:07 +02:00
|
|
|
|
2013-08-27 19:17:17 +02:00
|
|
|
* with the same domain as A
|
2013-09-09 15:46:58 +02:00
|
|
|
* with value_type == T2
|
2013-07-17 19:24:07 +02:00
|
|
|
|
2014-10-17 18:15:19 +02:00
|
|
|
* **Example**:
|
2013-07-17 19:24:07 +02:00
|
|
|
|
2014-05-31 19:12:21 +02:00
|
|
|
.. triqs_example:: ./map_0.cpp
|
2013-07-17 19:24:07 +02:00
|
|
|
fold
|
|
|
|
========================================================
|
|
|
|
|
|
|
|
* **Purpose** :
|
|
|
|
fold implements the folding (or reduction) on the array.
|
|
|
|
|
|
|
|
* **Syntax** :
|
|
|
|
|
|
|
|
If `f` is a function, or a function object of synopsis (T, R being 2 types) ::
|
|
|
|
|
2014-04-09 21:24:03 +02:00
|
|
|
R f (R , T)
|
2013-07-17 19:24:07 +02:00
|
|
|
|
|
|
|
then ::
|
|
|
|
|
|
|
|
auto F = fold(f);
|
|
|
|
|
|
|
|
is a callable object which can fold any array of value_type T.
|
|
|
|
|
|
|
|
So, if
|
|
|
|
|
2013-08-22 16:55:51 +02:00
|
|
|
* A is a type which models the :ref:`ImmutableCuboidArray` concept
|
2013-07-17 19:24:07 +02:00
|
|
|
(e.g. an array , a matrix, a vector, an expression, ...)
|
|
|
|
|
|
|
|
* A::value_type is T
|
|
|
|
|
|
|
|
then ::
|
|
|
|
|
2014-04-09 21:24:03 +02:00
|
|
|
fold (f) ( A, R init = R() ) = f(f(f(f(init, a(0,0)), a(0,1)),a(0,2)),a(0,3), ....)
|
2013-07-17 19:24:07 +02:00
|
|
|
|
2014-10-17 18:15:19 +02:00
|
|
|
Note that:
|
2013-07-17 19:24:07 +02:00
|
|
|
|
|
|
|
* The order of traversal is the same as foreach.
|
|
|
|
* The precise return type of fold is an implementation detail, depending on the precise type of f,
|
|
|
|
use auto to keep it.
|
|
|
|
* The function f will be inlined if possible, leading to efficient algorithms.
|
|
|
|
* fold is implemented using a foreach loop, hence it is efficient.
|
|
|
|
|
2014-10-17 18:15:19 +02:00
|
|
|
* **Example**:
|
2013-07-17 19:24:07 +02:00
|
|
|
|
|
|
|
Many algorithms can be written in form of map/fold.
|
|
|
|
|
2013-08-27 19:17:17 +02:00
|
|
|
The function :ref:`arr_fnt_sum` which returns the sum of all the elements of the array is implemented as ::
|
2014-04-09 21:24:03 +02:00
|
|
|
|
2013-07-17 19:24:07 +02:00
|
|
|
template <class A>
|
2014-04-09 21:24:03 +02:00
|
|
|
typename A::value_type sum(A const & a) { return fold ( std::plus<>()) (a); }
|
|
|
|
|
|
|
|
or the Frobenius norm of a matrix,
|
|
|
|
|
|
|
|
.. math::
|
|
|
|
\sum_{i=0}^{N-1} \sum_{j=0}^{N-1} | a_{ij} | ^2
|
|
|
|
|
|
|
|
reads :
|
|
|
|
|
2014-05-31 19:12:21 +02:00
|
|
|
.. triqs_example:: ./map_1.cpp
|
2014-10-17 18:15:19 +02:00
|
|
|
Note in this example:
|
2013-07-17 19:24:07 +02:00
|
|
|
|
|
|
|
* the simplicity of the code
|
2014-10-17 18:15:19 +02:00
|
|
|
* the genericity: it is valid for any dimension of array.
|
2013-07-17 19:24:07 +02:00
|
|
|
* internally, the library will rewrite it as a series of for loop, ordered in the TraversalOrder of the array
|
2014-04-09 21:24:03 +02:00
|
|
|
and inline the lambda.
|
2013-07-17 19:24:07 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-08-22 16:55:51 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|