Operator()

Synopsis

value_type const & operator()(size_t ...) const                            (1a)
value_type       & operator()(size_t ...)                                  (1b)

view_type          operator()() const                                      (2a)
view_type          operator()( size_t | range | ellipsis ) const           (2b)

`clef expression`  operator()( `at least a lazy argument` ) const          (3)

This is valid for both the container (e.g. array), and the view (e.g. array_view).

(1) Element access

Following the concept ImmutableCuboidArray, the form (1) is an access to the elements.

It must be called with exactly rank size_t (or it is a compile time error).

Example

#include <triqs/arrays.hpp>
using namespace triqs::arrays;
int main() {
  array<double, 2> A(2, 3);
  A()     = 0; //  assign 0 to A
  A(0, 0) = 5;
  A(1, 1) = 2 * A(0, 0);
  std::cout << "A = " << A << std::endl;
}

Another

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 !

(2) Building a view

When the arguments contains at least one range or one ellipsis, and no placeholder (see 3)), the return type is a (partial) view of the container.

The special case (2a) (no argument) returns a complete view of the object (equivalent to view_type(* this)).

The return type of the () operator is:

  • Partial views of array or array_view return a array_view.
  • Partial views of vector or vector_view return a vector_view.
  • 2d partial views of matrix or matrix_view return a matrix_view.
  • BUT: (1d) partial view of matrix or matrix_view return a vector_view.

Example

#include <triqs/arrays.hpp>
using namespace triqs::arrays;
int main() {
  array<double, 2> A(4, 4);
  for (int i = 0; i < 4; ++i)
    for (int j = 0; j < 4; ++j) A(i, j) = i + 10 * j;
  array_view<double, 2> V = A(range(0, 2), range(0, 2));
  std::cout << "V = " << V << std::endl;
  V = -V;
  std::cout << "A = " << A << std::endl;
}

(3) Interaction with clef expressions

  • The containers and their views can be used with the triqs::clef library:
  • Using the clef library offers a quick and efficient way to fill an array with multiple advantages:
    • It is simpler and more readeable than a series of for loops.
    • It is usually more optimal since the for loops are automatically written in the TraversalOrder of the array.
  • NB: the expression can be (and are) inlined by the compilers…
  • Example:
#include <triqs/arrays.hpp>
using triqs::arrays::array;
using triqs::clef::placeholder;

int main() {
  placeholder<0> i_;
  placeholder<1> j_;
  array<double, 2> A(2, 2), B(2, 2);

  A(i_, j_) << i_ + 2 * j_;
  B(i_, j_) << A(j_, i_) / 2;

  std::cout << "A = " << A << std::endl;
  std::cout << "B = " << B << std::endl;
}

Note

The syntax uses a <<, not = since the array is not assigned to an expression but filled by the evaluation thereof.