3
0
mirror of https://github.com/triqs/dft_tools synced 2024-11-01 11:43:47 +01:00
dft_tools/doc/reference/c++/arrays/slicing.rst
Olivier Parcollet 0f524b26fc work on doc
2013-08-27 13:43:58 +02:00

108 lines
3.5 KiB
ReStructuredText

.. highlight:: c
Partial views
==================================
Various kind of partial views and slices can be made on arrays and matrices.
* A `partial view` is defined as a view of a restricted portion of the array while
a `slice` is strictly speaking a partial view of a lower dimension of the original array,
e.g. a column of a matrix.
* Partial views uses the ( ) operator, as the evaluation of the array::
array<T,2> A(10,10); // defines an array
A(1, range(0,2) ) // 1d slice
A(1, range()) // 1d slice taking all the second dim
A(range(0,10,2), range(0,10,2)) // a 2d slice viewing every each elements with even coordinates.
array_view<T,1> SL = A(0,range(0,3)); // naming the view. No data copied here !
array_view<T,1> SL ( A(0,range(0,3))); // same thing !
auto SL = A(0,range(0,3)); // even simpler with C++11.
// CAREFUL : this is a weak view !!!! -> to be explained.
* **Return type** :
* Partial views of array or array_view return an array_view.
* Partial views of vector or vector_view return an vector_view.
* 2d partial views of matrix or matrix_view return matrix_view.
* BUT : (1d) slices of matrix or matrix_view return vector_view.
* 0d slices of anything are converted to the `value_type` of the array.
Memory Weak view
^^^^^^^^^^^^^^^^^^^^^
The `range` type
^^^^^^^^^^^^^^^^^^^^^
`range` mimics the python `range`. It can be constructed with :
* no argument : it then takes the whole set of indices in the dimension (like `:` in python) ::
A(range(), 0) // take the first column of A
* two arguments to specify a range ::
A(range (0,3), 0) // means A(0,0), A(1,0), A(2,0)
.. warning::
the second element is excluded : range(0,3) is 0,1,2, like in Python.
* three arguments : a range with a step ::
A(range(0,4,2), 0) // means A(0,0), A(2,0)
The `ellipsis` type
^^^^^^^^^^^^^^^^^^^^^^
* Ellipsis can be provided in place of `range`, as in python. The type `ellipsis` is similar to range
except that it is implicitely repeated to as much as necessary.
* Example:
.. compileblock ::
#include <triqs/arrays.hpp>
using triqs::arrays::array; using triqs::arrays::ellipsis;
int main(){
array<long,4> B(2,3,4,5) ;
B(0,ellipsis(),3) ; // same as B(0, range(),range(), 3 )
B(0,ellipsis(),2,3); // same as B(0, range(), 2, 3 )
B(ellipsis(),2,3) ; // same as B( range(),range(), 2, 3 )
}
* NB : there can be at most one ellipsis per expression (otherwise it would be meaningless).
* Example of usage :
Ellipsis are useful to write generic algorithms. For example, imagine that you want to sum
arrays on their first index :
.. compileblock ::
#include <triqs/arrays.hpp>
using triqs::arrays::array; using triqs::arrays::ellipsis;
// a generic function that sum array, array_view or in fact anything
// with the right concept on its first dimension
template<typename ArrayType>
array<typename ArrayType::value_type, ArrayType::rank-1> sum0 (ArrayType const & A) {
array<typename ArrayType::value_type, ArrayType::rank-1> res = A(0,ellipsis());
for (size_t u =1; u< first_dim(A); ++u) res += A(u,ellipsis());
return res;
}
// test
int main(){
array<double,2> A(5,2); A()=2;
array<double,3> B(5,2,3); B() = 1;
std::cout<< sum0(A) << sum0(B) <<std::endl;
}