Skip to content
fevangelista edited this page May 22, 2015 · 9 revisions

Introduction

Tensor objects can be used to store and manipulate tensors of any rank.

Using the Tensor class

Building Tensors

Tensors can be build using the Tensor::build() function. For example,

Tensor A = Tensor::build(kCore, "A", {1000, 1000});

builds an in-core tensor labeled "A" of rank 2 and dimensions (1000,1000). The build function requires to specify the type of tensor. The available options are

  • kCore, an in-core tensor
  • kDisk, a disk cachable tensor
  • kDistributed, a tensor suitable for parallel distributed computing

The last argument passed to the Tensor::build() function is a std::vector<size_t> vector with the dimensions of each tensor index. For example,

Tensor A = Tensor::build(kDisk, "A", {10, 20, 30, 40});

builds a four-dimensional tensor stored on disk. Notice that all dimensions must be greater than zero.

Filling up and accessing elements of a Tensor

One of the strengths of the ambit library is that it provides a unified interface to various tensor libraries. In order to maintain generality, the preferred way to access or modify the elements of a tensor is by iterators. Ambit provides two type of iterator functions for the Tensor class, iterate and citerate. The latter is a constant iterator and is not allowed to change the values of the tensor elements. These iterators take a functor or a lambda with three arguments: 1) the indices of the current element, and 2) a reference to the current element. For example, to fill up a tensor with elements of a matrix double** D it is convenient to pass a lambda:

Tensor Gamma_1 = Tensor::build(kCore, "Gamma_1", {nmo,nmo});

Gamma_1.iterate([](const std::vector<size_t>& indices,double& value){
    value = D[indices[0]][indices[1]];
});
Gamma_1.print(stdout);

Tensor contractions

Ambit greatly simplifies tensor contraction operations. In tensor contractions we distinguish two types of indices: 1) Einstein indices, repeated only twice on the right-hand-side of a tensor equation, and 2) Hadamard indices, repeated more than twice. Einstein indices appear, for example, when building the Fock matrix:

//  Fill the Fock matrix with one-electron integrals
F("m,n") = H("m,n");
//  Add the contribution from the two-electron integrals
F("m,n") += D("r,s") * (2.0 * g("m,n,r,s") - g("m,r,n,s"));

Notice that all tensor indices are separated by a comma. Ambit also accepts the shortened version:

//  Add the contribution from the two-electron integrals
F("mn") += D("rs") * (2.0 * g("mnrs") - g("mrns"));

In this case each string like "mnrs" is converted automatically to "m,n,r,s". Notice that it is possible to use any string of characters to represent tensor indices. For example, the previous example can be also written as:

//  Fill the Fock matrix with one-electron integrals
F("mu,nu") = H("mu,nu");
//  Add the contribution from the two-electron integrals
F("mu,nu") += D("rho,sigma") * (2.0 * g("mu,nu,rho,sigma") - g("mu,rho,nu,sigma"));

Clone this wiki locally