MADNESS  0.10.1
Files | Classes | Functions | Friends
Tensor

Files

file  slice.h
 Declares and implements Slice.
 
file  tensor.cc
 Completes the implementation of Tensor and instantiates all specializations for fast compiles.
 
file  tensor.h
 Defines and implements most of Tensor.
 
file  tensor_macros.h
 Macros for easy and efficient iteration over tensors.
 
file  tensortrain.h
 Defines and implements the tensor train decomposition as described in I.V. Oseledets, Siam J. Sci. Comput. 33, 2295 (2011).
 

Classes

class  madness::BaseTensor
 The base class for tensors defines generic capabilities. More...
 
class  madness::Slice
 A slice defines a sub-range or patch of a dimension. More...
 
class  madness::SliceTensor< T >
 Indexing a non-constant tensor with slices returns a SliceTensor. More...
 
class  madness::Tensor< T >
 A tensor is a multidimension array. More...
 
class  madness::TensorIterator< T, Q, R >
 

Functions

 madness::TensorIterator< T, Q, R >::TensorIterator (const Tensor< T > *t0, const Tensor< Q > *t1=0, const Tensor< R > *t2=0, long iterlevel=0, bool optimize=true, bool fusedim=true, long jdim=default_jdim)
 Constructor for general iterator to compose operations over up to three tensors. More...
 
template<class T >
Tensor< typename Tensor< T >::scalar_type > madness::abs (const Tensor< T > &t)
 Return a new tensor holding the absolute value of each element of t. More...
 
template<class T >
Tensor< typename Tensor< T >::scalar_type > madness::arg (const Tensor< T > &t)
 Return a new tensor holding the argument of each element of t (complex types only) More...
 
template<class T >
Tensor< Tmadness::conj (const Tensor< T > &t)
 Returns a new deep copy of the complex conjugate of the input tensor (complex types only) More...
 
template<class T >
Tensor< Tmadness::conj_transpose (const Tensor< T > &t)
 Returns a new deep copy of the complex conjugate transpose of the input tensor. More...
 
template<class Q , class T >
Tensor< Qmadness::convert (const Tensor< T > &t)
 Returns a new contiguous tensor of type Q that is a deep copy of the input. More...
 
template<class T >
Tensor< Tmadness::copy (const Tensor< T > &t)
 Returns a new contiguous tensor that is a deep copy of the input. More...
 
template<class T , class Q >
Tensor< TENSOR_RESULT_TYPE(T, Q) > & madness::fast_transform (const Tensor< T > &t, const Tensor< Q > &c, Tensor< TENSOR_RESULT_TYPE(T, Q) > &result, Tensor< TENSOR_RESULT_TYPE(T, Q) > &workspace)
 Restricted but heavily optimized form of transform() More...
 
template<class T , class Q >
Tensor< TENSOR_RESULT_TYPE(T, Q)> madness::general_transform (const Tensor< T > &t, const Tensor< Q > c[])
 Transform all dimensions of the tensor t by distinct matrices c. More...
 
template<class T , class Q >
TensorTrain< TENSOR_RESULT_TYPE(T, Q)> madness::general_transform (const TensorTrain< T > &t, const Tensor< Q > c[])
 Transform all dimensions of the tensor t by distinct matrices c. More...
 
template<class T >
Tensor< typename Tensor< T >::scalar_type > madness::imag (const Tensor< T > &t)
 Return a new tensor holding the imaginary part of each element of t (complex types only) More...
 
template<class T , class Q >
Tensor< TENSOR_RESULT_TYPE(T, Q)> madness::inner (const Tensor< T > &left, const Tensor< Q > &right, long k0=-1, long k1=0)
 Inner product ... result(i,j,...,p,q,...) = sum(z) left(i,j,...,z)*right(z,p,q,...) More...
 
template<class T , class Q >
void madness::inner_result (const Tensor< T > &left, const Tensor< Q > &right, long k0, long k1, Tensor< TENSOR_RESULT_TYPE(T, Q) > &result)
 Accumulate inner product into user provided, contiguous, correctly sized result tensor. More...
 
template<typename T , typename Q >
IsSupported< TensorTypeData< Q >, Tensor< T > >::type madness::operator* (const Q &x, const Tensor< T > &t)
 The class defines tensor op scalar ... here define scalar op tensor. More...
 
template<typename T , typename Q >
IsSupported< TensorTypeData< Q >, Tensor< T > >::type madness::operator+ (Q x, const Tensor< T > &t)
 The class defines tensor op scalar ... here define scalar op tensor. More...
 
template<typename T , typename Q >
IsSupported< TensorTypeData< Q >, Tensor< T > >::type madness::operator- (Q x, const Tensor< T > &t)
 The class defines tensor op scalar ... here define scalar op tensor. More...
 
template<class T >
std::ostream & madness::operator<< (std::ostream &s, const Tensor< T > &t)
 Print (for human consumption) a tensor to the stream. More...
 
template<class T >
GenTensor< Tmadness::outer (const GenTensor< T > &left, const GenTensor< T > &right, const TensorArgs final_tensor_args)
 Outer product ... result(i,j,...,p,q,...) = left(i,k,...)*right(p,q,...) More...
 
template<class T >
Tensor< Tmadness::outer (const Tensor< T > &left, const Tensor< T > &right)
 Outer product ... result(i,j,...,p,q,...) = left(i,k,...)*right(p,q,...) More...
 
template<class T >
GenTensor< Tmadness::outer (const Tensor< T > &left, const Tensor< T > &right, const TensorArgs final_tensor_args)
 Outer product ... result(i,j,...,p,q,...) = left(i,k,...)*right(p,q,...) More...
 
template<class T >
Tensor< typename Tensor< T >::scalar_type > madness::real (const Tensor< T > &t)
 Return a new tensor holding the real part of each element of t (complex types only) More...
 
template<class T , class Q >
Tensor< TENSOR_RESULT_TYPE(T, Q)> madness::transform (const Tensor< T > &t, const Tensor< Q > &c)
 Transform all dimensions of the tensor t by the matrix c. More...
 
template<class T , class Q >
Tensor< TENSOR_RESULT_TYPE(T, Q)> madness::transform_dir (const Tensor< T > &t, const Tensor< Q > &c, int axis)
 Transforms one dimension of the tensor t by the matrix c, returns new contiguous tensor. More...
 
template<class T , class Q >
TensorTrain< TENSOR_RESULT_TYPE(T, Q)> madness::transform_dir (const TensorTrain< T > &t, const Tensor< Q > &c, const int axis)
 Transforms one dimension of the tensor t by the matrix c, returns new contiguous tensor. More...
 
template<class T >
Tensor< Tmadness::transpose (const Tensor< T > &t)
 Returns a new deep copy of the transpose of the input tensor. More...
 

Friends

template<typename R , typename Q >
GenTensor< TENSOR_RESULT_TYPE(R, Q)> madness::GenTensor< T >::general_transform (const GenTensor< R > &t, const Tensor< Q > c[])
 Transform all dimensions of the tensor t by distinct matrices c. More...
 
template<typename R , typename Q >
GenTensor< TENSOR_RESULT_TYPE(R, Q)> madness::GenTensor< T >::transform (const GenTensor< R > &t, const Tensor< Q > &c)
 Transform all dimensions of the tensor t by the matrix c. More...
 
template<typename R , typename Q >
GenTensor< TENSOR_RESULT_TYPE(R, Q)> madness::GenTensor< T >::transform_dir (const GenTensor< R > &t, const Tensor< Q > &c, const int axis)
 Transforms one dimension of the tensor t by the matrix c, returns new contiguous tensor. More...
 

Detailed Description

Introduction

A tensor is a multi-dimensional array and does not incorporate any concepts of covariance and contravariance.

When a new tensor is created, the underlying data is also allocated. E.g.,

Tensor<double> a(3,4,5)
static const double a
Definition: nonlinschro.cc:118

creates a new 3-dimensional tensor and allocates a contiguous block of 60 doubles which are initialized to zero. The dimensions (numbered from the left starting at 0) are in C or row-major order. Thus, for the tensor a , the stride between successive elements of the right-most dimension is 1. For the middle dimension it is 5. For the left-most dimension it is 20. Thus, the loops

for (i=0; i<3; ++i)
for (j=0; j<4; ++j)
for (k=0; k<5; ++k)
a(i,j,k) = ...
static const long k
Definition: rk.cc:44

will go sequentially (and thus efficiently) through memory. If the dimensions have been reordered (e.g., with swapdim() or map() ), or if the tensor is actually a slice of another tensor, then the layout in memory may be more complex and may not reflect a contiguous block of memory.

Multiple tensors may be used to provide multiple identical or distinct views of the same data. E.g., in the following

Tensor<double> a(2,3); // A new tensor initialized to zero
Tensor<double> b = a;
static const double b
Definition: nonlinschro.cc:119

a and b provide identical views of the same data, thus

b(1,2) = 99;
cout << a(1,2) << endl; // Outputs 99
cout << b(1,2) << endl; // Outputs 99
Shallow copy and assignment

It is important to appreciate that the views and the data are quite independent. In particular, the default copy constructor and assignment operations only copy the tensor (the view) and not the data — i.e., the copy constructor and assigment operations only take shallow copies. This is for both consistency and efficiency. Thus, assigning one tensor to another generates another view of the same data, replacing any previous view and not moving or copying any of the data. E.g.,

Tensor<double> a(2,3); // A new tensor initialized to zero
Tensor<double> c(3,3,3); // Another new tensor
Tensor<double> b = a; // b is a view of the same data as a
a = c; // a is now a view of c's data
b = c // b is now also a view of c's data and the
// data allocated originally for a is freed
static const double c
Definition: relops.cc:10

The above example also illustrates how reference counting is used to keep track of the underlying data. Once there are no views of the data, it is automatically freed.

There are only two ways to actually copy the underlying data. A new, complete, and contiguous copy of a tensor and its data may be generated with the copy() function. Or, to copy data from one tensor into the data viewed by another tensor, you must use a Slice.

Indexing

One dimensional tensors (i.e., vectors) may be indexed using either square brackets (e.g., v[i] ) or round brackets (e.g., v(i) ). All higher-dimensional tensors must use only round brackets (e.g., t(i,j,k) ). This is due to C++'s restriction that the indexing operator ([] ) can only have one argument. The indexing operation should generate efficient code.

For the sake of efficiency, no bounds checking is performed by default by most single element indexing operations. Checking can be enabled at compile time by defining -DTENSOR_BOUNDS_CHECKING for application files including tensor.h. The MADNESS configure script has the option –enable-tensor-bound-checking to define the macro in madness_config.h . The general indexing operation that takes a std::vector<long> index and all slicing operations always perform bounds checking. To make indexing with checking a bit easier, a factory function has been provided for vectors ... but note you need to explicitly use longs as the index.

Tensor<long> a(7,7,7);
a(3,4,5) += 1; // OK ... adds 1 to element (3,4,5)
a(3,4,9) += 1; // BAD ... undetected out-of-bounds access
a(vector_factory(3L,4L,9L)) += 1; // OK ... out-bounds access will
// be detected at runtime.
std::vector< T > vector_factory(const T &v0)
Returns a std::vector<T> initialized from the arguments.
Definition: vector_factory.h:50
Slicing

Slices generate sub-tensors — i.e., views of patches of the data. E.g., to refer to all but the first and last elements in each dimension of a matrix use

a(Slice(1,-2),Slice(1,-2))

Or to view odd elements in each dimension

a(Slice(0,-1,2),Slice(0,-1,2))

A slice or patch of a tensor behaves exactly like a tensor except for assignment. When a slice is assigned to, the data is copied with the requirement that the source and destinations agree in size and shape (i.e., they conform). Thus, to copy the all of the data from a to b,

Tensor<double> a(3,4), b(3,4);
a = 1; // Set all elements of a to 1
b = 2; // Set all elements of b to 2
a(Slice(0,-1,1),Slice(0,-1,1)) = b; // Copy all data from b to a
a(_,_) = b(_,_); // Copy all data from b to a
a(___) = b(___); // Copy all data from b to a
a(Slice(1,2),Slice(1,2)) = b; // Error, do not conform
static const std::vector< Slice > ___
Entire dimension.
Definition: slice.h:128
static const Slice _(0,-1, 1)

Special slice values _ ,_reverse, and ___ have been defined to refer to all elements in a dimension, all elements in a dimension but reversed, and all elements in all dimensions, respectively.

Iteration and algorithms

See tensor_macros.h for documentation on the easiest mechanisms for iteration over elements of tensors and tips for optimization. See TensorIterator for the most general form of iteration.

Function Documentation

◆ TensorIterator()

template<class T , class Q , class R >
madness::TensorIterator< T, Q, R >::TensorIterator ( const Tensor< T > *  t0,
const Tensor< Q > *  t1 = 0,
const Tensor< R > *  t2 = 0,
long  iterlevel = 0,
bool  optimize = true,
bool  fusedim = true,
long  jdim = default_jdim 
)

Constructor for general iterator to compose operations over up to three tensors.

Macros have been defined in tensor_macros.h to take the pain out of using iterators. The options have the following effects

  • optimize reorders dimensions for optimal strides (only applies if iterlevel=1). If jdim==default_jdim, all dimensions are reordered for optimal stride. If jdim is not the default value, then dimension jdim is excluded from the set of dimensions being optimized.
  • fusedim concatenates contiguous dimensions into the inner loop (only applies if iterlevel=1 and jdim=default_jdim).
  • iterlevel can have two values 0=elementwise, 1=vectorwise. Elementwise implies that the iterator returns successive elements, and explicitly in the expected order for the tensor (i.e., with the last index varying fastest). Vectorwise implies that the user is responsible for iterating over dimension jdim.
  • jdim — if iterlevel=1, then jdim determines which dimension is left for iteration with an explicit for loop. Negative values implies jdim+=ndim following the convention of Slice (and Python). If (optimize) the default is the fastest varying dimension. If (!optimize) the default is the last dimension (jdim=-1). If (fusedim) contiguous dimensions are fused into this inner loop. Specifying a non-default value for jdim disables fusedim and restricts optimization to reordering only the exterior loops (so that the loop the user is iterating over corresponds exactly to those in dimension jdim).
During iteration:
  • ind[] will contain the current iteration indices .. BUT if optimize=true , they will not necessarily be in the order of those of the tensor. if fusedim is true, then there may be fewer dimensions than the input tensor.
  • _p0, _p1, _p2 will point to the current elements of t0,t1,t2 noting that if iterlevel>0, the user must provide additional for loops to iterate over the additional dimensions
  • stride0[], stride1[], stride2[] will contain the strides for each (possibly reordered) dimension. If iterlevel=1, _s0,_s1,s2 contain the stride info for the dimension that the user is responsible for iterating over.
  • dimj -> the size of the j'th dimension

References std::abs(), madness::Tensor< T >::conforms(), madness::default_jdim, madness::BaseTensor::dim(), madness::BaseTensor::ndim(), madness::Tensor< T >::ptr(), Q(), R, madness::BaseTensor::stride(), madness::swap(), T(), TENSOR_ASSERT, and TENSOR_MAXDIM.

◆ abs()

template<class T >
Tensor< typename Tensor<T>::scalar_type > madness::abs ( const Tensor< T > &  t)

Return a new tensor holding the absolute value of each element of t.

References std::abs(), BINARY_OPTIMIZED_ITERATOR, madness::BaseTensor::dims(), madness::BaseTensor::ndim(), and T().

◆ arg()

template<class T >
Tensor< typename Tensor<T>::scalar_type > madness::arg ( const Tensor< T > &  t)

Return a new tensor holding the argument of each element of t (complex types only)

References BINARY_OPTIMIZED_ITERATOR, madness::BaseTensor::dims(), madness::BaseTensor::ndim(), and T().

Referenced by madness::detail::info< memfunT >::info(), refpotfunctor::refpotfunctor(), madness::QCCalculationParametersBase::add_quotes(), madness::apply(), madness::World::args(), madness::WorldGopInterface::bcast_handler(), bshrel_omega(), madness::TaskFn< fnT, arg1T, arg2T, arg3T, arg4T, arg5T, arg6T, arg7T, arg8T, arg9T >::check_dependency(), madness::check_for_inf(), madness::Recordlist< keyT >::compute_record(), madness::Pairs< T >::convert(), madness::copy_am_arg(), madness::Batch_1D::copy_batch(), madness::Batch::copy_input_batch(), madness::Diamagnetic_potential_factor::custom_factor(), madness::FunctionImpl< T, NDIM >::do_binary_op(), madness::FunctionImpl< T, NDIM >::do_mul(), madness::Solver< T, NDIM >::do_rhs(), madness::Solver< T, NDIM >::do_rhs_simple(), madness::Diamagnetic_potential_factor::factor_with_phase(), fixphases(), madness::free_am_arg(), madness::QCCalculationParametersBase::fromstring(), madness::BandlimitedPropagator::g0_filtered(), madness::WorldGopInterface::group_bcast_handler(), madness::WorldObject< Derived >::handler(), madness::WorldAmInterface::handler(), madness::WorldObject< Derived >::is_ready(), madness::LowRankFunction< T, NDIM, LDIM >::l2error(), main(), madness::Diamagnetic_potential_factor::make_fake_orbitals(), PsiExact::operator()(), FiniteNucleusPotential::operator()(), refpotfunctor::operator()(), QMtest::operator()(), Sphere::operator()(), DSphere::operator()(), GaussianGuess< NDIM >::operator()(), madness::Coulomb< T, NDIM >::MacroTaskCoulomb::operator()(), madness::BSHApply< T, NDIM >::operator()(), MatrixOperator::operator()(), Metric::operator()(), madness::FunctionImpl< T, NDIM >::do_inner_local_on_demand< R >::operator()(), madness::operator*(), operator*(), orthonormalize(), orthonormalize_fock(), madness::QCCalculationParametersBase::overwrite_if_inf(), madness::detail::peek(), psi_exact(), madness::QCCalculationParametersBase::read_quotes(), madness::WorldTaskQueue::remote_task_handler(), madness::commandlineparser::remove_blanks(), madness::commandlineparser::remove_first_equal(), madness::commandlineparser::remove_front_hyphens(), madness::RemoteReference< T >::reset_handler(), madness::Polynomial< N >::S(), madness::WorldAmInterface::send(), madness::FutureImpl< T >::set_handler(), madness::WorldObject< Derived >::spawn_remote_task_handler(), madness::startup(), madness::Cloud::store_tuple(), madness::stringify(), test_chin_chen(), test_combined_operators(), test_conversion(), test_inner(), test_trotter(), madness::QCCalculationParametersBase::tostring(), madness::FunctionImpl< T, NDIM >::traverse_tree(), madness::commandlineparser::trim_blanks(), madness::QCCalculationParametersBase::trim_blanks(), madness::QCCalculationParametersBase::trim_quotes(), and truncate().

◆ conj()

template<class T >
Tensor<T> madness::conj ( const Tensor< T > &  t)

Returns a new deep copy of the complex conjugate of the input tensor (complex types only)

References BINARY_OPTIMIZED_ITERATOR, madness::conditional_conj(), madness::BaseTensor::dims(), madness::BaseTensor::ndim(), and T().

◆ conj_transpose()

template<class T >
Tensor<T> madness::conj_transpose ( const Tensor< T > &  t)

◆ convert()

template<class Q , class T >
Tensor<Q> madness::convert ( const Tensor< T > &  t)

Returns a new contiguous tensor of type Q that is a deep copy of the input.

Returns
Returns a new contiguous tensor that is a deep copy of the input

References BINARY_OPTIMIZED_ITERATOR, madness::BaseTensor::dims(), madness::BaseTensor::ndim(), Q(), madness::BaseTensor::size(), and T().

◆ copy()

template<class T >
Tensor<T> madness::copy ( const Tensor< T > &  t)

Returns a new contiguous tensor that is a deep copy of the input.

Returns
Returns a new contiguous tensor that is a deep copy of the input

References BINARY_OPTIMIZED_ITERATOR, madness::BaseTensor::dims(), madness::BaseTensor::ndim(), madness::BaseTensor::size(), and T().

◆ fast_transform()

template<class T , class Q >
Tensor< TENSOR_RESULT_TYPE(T,Q) >& madness::fast_transform ( const Tensor< T > &  t,
const Tensor< Q > &  c,
Tensor< TENSOR_RESULT_TYPE(T, Q) > &  result,
Tensor< TENSOR_RESULT_TYPE(T, Q) > &  workspace 
)

Restricted but heavily optimized form of transform()

Both dimensions of c must be the same and match all dimensions of the input tensor t. All tensors must be contiguous.

Performs the same operation as transform but it requires that the caller pass in workspace and a preallocated result, hoping that that both can be reused. If the result and workspace are reused between calls, then no tensor constructors need be called and cache locality should be improved. By passing in the workspace, this routine is kept thread safe.

The input, result and workspace tensors must be distinct.

All input tensors must be contiguous and fastest execution will result if all dimensions are approriately aligned and multiples of the underlying vector length. The workspace and the result must be of the same size as the input t . The result tensor need not be initialized before calling fast_transform.

result(i,j,k,...) <-- sum(i',j', k',...) t(i',j',k',...) c(i',i) c(j',j) c(k',k) ...
Function< T, NDIM > sum(World &world, const std::vector< Function< T, NDIM > > &f, bool fence=true)
Returns new function — q = sum_i f[i].
Definition: vmra.h:1421

The input dimensions of t must all be the same .

References c, IS_UNALIGNED, madness::mTxm(), madness::mTxmq(), madness::mTxmq_padding(), madness::BaseTensor::ndim(), madness::Tensor< T >::ptr(), Q(), madness::swap(), T(), and madness::TENSOR_RESULT_TYPE().

Referenced by madness::FunctionImpl< T, NDIM >::err_box(), madness::FunctionImpl< T, NDIM >::filter(), main(), madness::FunctionImpl< T, NDIM >::project(), Test7(), madness::time_transform(), madness::transform(), and madness::FunctionImpl< T, NDIM >::unfilter().

◆ general_transform() [1/2]

template<class T , class Q >
Tensor<TENSOR_RESULT_TYPE(T,Q)> madness::general_transform ( const Tensor< T > &  t,
const Tensor< Q c[] 
)

Transform all dimensions of the tensor t by distinct matrices c.

Similar to transform but each dimension is transformed with a distinct matrix.

result(i,j,k...) <-- sum(i',j', k',...) t(i',j',k',...) c[0](i',i) c[1](j',j) c[2](k',k) ...

The first dimension of the matrices c must match the corresponding dimension of t.

References c, madness::inner(), madness::BaseTensor::ndim(), Q(), T(), and madness::TENSOR_RESULT_TYPE().

◆ general_transform() [2/2]

template<class T , class Q >
TensorTrain<TENSOR_RESULT_TYPE(T,Q)> madness::general_transform ( const TensorTrain< T > &  t,
const Tensor< Q c[] 
)

Transform all dimensions of the tensor t by distinct matrices c.

Similar to transform but each dimension is transformed with a distinct matrix.

result(i,j,k...) <-- sum(i',j', k',...) t(i',j',k',...) c[0](i',i) c[1](j',j) c[2](k',k) ...

The first dimension of the matrices c must match the corresponding dimension of t.

References c, madness::copy(), madness::TensorTrain< T >::core, d(), madness::BaseTensor::dims(), madness::inner(), madness::inner_result(), max, madness::BaseTensor::ndim(), Q(), madness::r2(), T(), madness::TENSOR_RESULT_TYPE(), and madness::TensorTrain< T >::zero_rank.

◆ imag()

template<class T >
Tensor< typename Tensor<T>::scalar_type > madness::imag ( const Tensor< T > &  t)

Return a new tensor holding the imaginary part of each element of t (complex types only)

References BINARY_OPTIMIZED_ITERATOR, madness::BaseTensor::dims(), madness::BaseTensor::ndim(), and T().

◆ inner()

template<class T , class Q >
Tensor<TENSOR_RESULT_TYPE(T,Q)> madness::inner ( const Tensor< T > &  left,
const Tensor< Q > &  right,
long  k0 = -1,
long  k1 = 0 
)

Inner product ... result(i,j,...,p,q,...) = sum(z) left(i,j,...,z)*right(z,p,q,...)

By default it contracts the last dimension of the left tensor and the first dimension of the right tensor. These defaults can be changed by specifying k0 and k1 , the index to contract in the left and right side tensors, respectively. The defaults correspond to (k0=-1 and k1=0 ).

References d(), madness::BaseTensor::dim(), madness::inner_result(), k0, k1, madness::BaseTensor::ndim(), Q(), T(), TENSOR_ASSERT, TENSOR_MAXDIM, and madness::TENSOR_RESULT_TYPE().

◆ inner_result()

template<class T , class Q >
void madness::inner_result ( const Tensor< T > &  left,
const Tensor< Q > &  right,
long  k0,
long  k1,
Tensor< TENSOR_RESULT_TYPE(T, Q) > &  result 
)

Accumulate inner product into user provided, contiguous, correctly sized result tensor.

This routine may be used to optimize away the tensor constructor of the result tensor in inner loops when the result tensor may be reused or accumulated into. If the user calls this routine directly very little checking is done since it is intended as an optimization for small tensors. As far as the result goes, the caller is completely responsible for providing a contiguous tensor that has the correct dimensions and is appropriately initialized. The inner product is accumulated into result.

References madness::TensorIterator< T, Q, R >::_p0, madness::TensorIterator< T, Q, R >::_s0, madness::BaseTensor::dim(), madness::BaseTensor::iscontiguous(), k0, k1, madness::mTxm(), madness::mTxmT(), madness::mxm(), madness::mxmT(), madness::BaseTensor::ndim(), madness::Tensor< T >::ptr(), Q(), madness::TensorIterator< T, Q, R >::reset(), s0, madness::BaseTensor::size(), madness::BaseTensor::stride(), madness::sum(), T(), madness::TENSOR_RESULT_TYPE(), and madness::Tensor< T >::unary_iterator().

Referenced by madness::apply(), madness::general_transform(), madness::inner(), madness::SRConf< T >::normf(), madness::ortho5(), madness::SRConf< T >::trace(), madness::TensorTrain< T >::trace(), and madness::transform().

◆ operator*()

template<typename T , typename Q >
IsSupported< TensorTypeData<Q>, Tensor<T> >::type madness::operator* ( const Q x,
const Tensor< T > &  t 
)

The class defines tensor op scalar ... here define scalar op tensor.

◆ operator+()

template<typename T , typename Q >
IsSupported< TensorTypeData<Q>, Tensor<T> >::type madness::operator+ ( Q  x,
const Tensor< T > &  t 
)

The class defines tensor op scalar ... here define scalar op tensor.

◆ operator-()

template<typename T , typename Q >
IsSupported< TensorTypeData<Q>, Tensor<T> >::type madness::operator- ( Q  x,
const Tensor< T > &  t 
)

The class defines tensor op scalar ... here define scalar op tensor.

◆ operator<<()

template<class T >
std::ostream& madness::operator<< ( std::ostream &  out,
const Tensor< T > &  t 
)

◆ outer() [1/3]

template<class T >
GenTensor<T> madness::outer ( const GenTensor< T > &  left,
const GenTensor< T > &  right,
const TensorArgs  final_tensor_args 
)

Outer product ... result(i,j,...,p,q,...) = left(i,k,...)*right(p,q,...)

References madness::outer().

◆ outer() [2/3]

template<class T >
Tensor<T> madness::outer ( const Tensor< T > &  left,
const Tensor< T > &  right 
)

Outer product ... result(i,j,...,p,q,...) = left(i,k,...)*right(p,q,...)

References d(), madness::BaseTensor::dim(), madness::BaseTensor::ndim(), madness::outer_result(), TENSOR_ASSERT, and TENSOR_MAXDIM.

◆ outer() [3/3]

template<class T >
GenTensor<T> madness::outer ( const Tensor< T > &  left,
const Tensor< T > &  right,
const TensorArgs  final_tensor_args 
)

Outer product ... result(i,j,...,p,q,...) = left(i,k,...)*right(p,q,...)

References madness::outer().

◆ real()

template<class T >
Tensor< typename Tensor<T>::scalar_type > madness::real ( const Tensor< T > &  t)

Return a new tensor holding the real part of each element of t (complex types only)

References BINARY_OPTIMIZED_ITERATOR, madness::BaseTensor::dims(), madness::BaseTensor::ndim(), and T().

◆ transform()

template<class T , class Q >
Tensor<TENSOR_RESULT_TYPE(T,Q)> madness::transform ( const Tensor< T > &  t,
const Tensor< Q > &  c 
)

Transform all dimensions of the tensor t by the matrix c.

Often used to transform all dimensions from one basis to another

result(i,j,k...) <-- sum(i',j', k',...) t(i',j',k',...) c(i',i) c(j',j) c(k',k) ...

The input dimensions of t must all be the same and agree with the first dimension of c . The dimensions of c may differ in size. If the dimensions of c are the same, and the operation is being performed repeatedly, then you might consider calling fast_transform instead which enables additional optimizations and can eliminate all constructor overhead and improve cache locality.

References c, madness::BaseTensor::dims(), madness::fast_transform(), madness::inner(), madness::BaseTensor::iscontiguous(), madness::BaseTensor::ndim(), Q(), T(), TENSOR_ASSERT, and madness::TENSOR_RESULT_TYPE().

◆ transform_dir() [1/2]

template<class T , class Q >
Tensor<TENSOR_RESULT_TYPE(T,Q)> madness::transform_dir ( const Tensor< T > &  t,
const Tensor< Q > &  c,
int  axis 
)

Transforms one dimension of the tensor t by the matrix c, returns new contiguous tensor.

transform_dir(t,c,1) = r(i,j,k,...) = sum(j') t(i,j',k,...) * c(j',j)
GenTensor< TENSOR_RESULT_TYPE(R, Q)> transform_dir(const GenTensor< R > &t, const Tensor< Q > &c, const int axis)
Definition: lowranktensor.h:1099
Parameters
[in]tTensor to transform (size of dimension to be transformed must match size of first dimension of c )
[in]cMatrix used for the transformation
[in]axisDimension (or axis) to be transformed
Returns
Returns a new, contiguous tensor

References axis, c, madness::copy(), madness::inner(), and madness::BaseTensor::ndim().

◆ transform_dir() [2/2]

template<class T , class Q >
TensorTrain<TENSOR_RESULT_TYPE(T,Q)> madness::transform_dir ( const TensorTrain< T > &  t,
const Tensor< Q > &  c,
const int  axis 
)

Transforms one dimension of the tensor t by the matrix c, returns new contiguous tensor.

transform_dir(t,c,1) = r(i,j,k,...) = sum(j') t(i,j',k,...) * c(j',j)
Parameters
[in]tTensor to transform (size of dimension to be transformed must match size of first dimension of c )
[in]cMatrix used for the transformation
[in]axisDimension (or axis) to be transformed
Returns
Returns a new tensor train

References axis, c, madness::copy(), madness::TensorTrain< T >::core, madness::BaseTensor::dims(), madness::inner(), MADNESS_ASSERT, madness::BaseTensor::ndim(), Q(), madness::Tensor< T >::swapdim(), T(), madness::TENSOR_RESULT_TYPE(), and madness::TensorTrain< T >::zero_rank.

◆ transpose()

template<class T >
Tensor<T> madness::transpose ( const Tensor< T > &  t)

Returns a new deep copy of the transpose of the input tensor.

References madness::copy(), madness::BaseTensor::ndim(), madness::Tensor< T >::swapdim(), and TENSOR_ASSERT.

Friends

◆ general_transform

template<typename T >
template<typename R , typename Q >
GenTensor<TENSOR_RESULT_TYPE(R,Q)> general_transform ( const GenTensor< R > &  t,
const Tensor< Q c[] 
)
friend

Transform all dimensions of the tensor t by distinct matrices c.

Similar to transform but each dimension is transformed with a distinct matrix.

result(i,j,k...) <-- sum(i',j', k',...) t(i',j',k',...) c[0](i',i) c[1](j',j) c[2](k',k) ...
T sum() const
Returns the sum of all elements of the tensor.
Definition: tensor.h:1662

The first dimension of the matrices c must match the corresponding dimension of t. template <typename R, typename Q>

◆ transform

template<typename T >
template<typename R , typename Q >
GenTensor<TENSOR_RESULT_TYPE(R,Q)> transform ( const GenTensor< R > &  t,
const Tensor< Q > &  c 
)
friend

Transform all dimensions of the tensor t by the matrix c.

Often used to transform all dimensions from one basis to another

result(i,j,k...) <-- sum(i',j', k',...) t(i',j',k',...) c(i',i) c(j',j) c(k',k) ...

The input dimensions of t must all be the same and agree with the first dimension of c . The dimensions of c may differ in size.

◆ transform_dir

template<typename T >
template<typename R , typename Q >
GenTensor<TENSOR_RESULT_TYPE(R,Q)> transform_dir ( const GenTensor< R > &  t,
const Tensor< Q > &  c,
const int  axis 
)
friend

Transforms one dimension of the tensor t by the matrix c, returns new contiguous tensor.

transform_dir(t,c,1) = r(i,j,k,...) = sum(j') t(i,j',k,...) * c(j',j)
friend GenTensor< TENSOR_RESULT_TYPE(R, Q)> transform_dir(const GenTensor< R > &t, const Tensor< Q > &c, const int axis)
Transforms one dimension of the tensor t by the matrix c, returns new contiguous tensor.
Definition: lowranktensor.h:1099
Parameters
[in]tTensor to transform (size of dim to be transformed must match size of first dim of c )
[in]cMatrix used for the transformation
[in]axisDimension (or axis) to be transformed
Returns
Returns a new, contiguous tensor template <typename R, typename Q>