File tensor.hpp

Defines the interface of a Tensor object.

namespace nuTens
class NoGrad

Public Functions

inline NoGrad()

Disable autograd calculations within some scope, improving performance where you are not interested in calculating gradients Instantiate at the start of the scope where you want to disable gradient calculations like so.

 #include <nuTens/tensors/tensor.hpp>
...
  {
      auto noGrad = nuTens::NoGrad();
      ...
      < speedy non differentiated code >
      ...
  }
class Tensor

Subclassed by nuTens::BaseMatterSolver::EigenvalTensor, nuTens::BaseMatterSolver::EigenvecTensor

Constructors

Use these methods to construct tensors

inline Tensor()

Default constructor with no initialisation.

Tensor(const std::vector<float> &values, dtypes::scalarType type = dtypes::kFloat, dtypes::deviceType device = dtypes::kCPU, bool requiresGrad = false)

Construct a 1-d array with specified values.

  • values The values to include in the tensor

virtual ~Tensor() = default

Destructor.

Tensor(Tensor const&) = default

copy constructor

Tensor &operator=(Tensor const&) = default

copy assignment operator

Tensor(Tensor&&) = default

move constructor

Tensor &operator=(Tensor&&) = default

move assignment operator

static Tensor TensorComplex(const std::vector<std::complex<float>> &values, dtypes::scalarType type = dtypes::kComplexFloat, dtypes::deviceType device = dtypes::kCPU, bool requiresGrad = false)

Construct a 1-d array with specified complex values.

  • values The values to include in the tensor

Warning

This can be quite slow due to internal conversions between complex types. Avoid using it for anything performance critical!!!

static Tensor eye(int n, dtypes::scalarType type = dtypes::kFloat, dtypes::deviceType device = dtypes::kCPU, bool requiresGrad = false)

Construct an identity tensor (has to be a 2d square tensor)

  • n The size of one of the sides of the tensor

  • type The data type of the tensor

static Tensor rand(const std::vector<long int> &shape, dtypes::scalarType type = dtypes::kFloat, dtypes::deviceType device = dtypes::kCPU, bool requiresGrad = false)

Construct a tensor with entries randomly initialised in the range [0, 1].

  • shape The desired shape of the intitalised tensor

  • type The data type of the tensor

static Tensor diag(const Tensor &diag)

Construct a tensor diag values along the diagonal, and zero elsewhere.

  • diag A 1-d tensor which represents the desired diagonal values

static Tensor ones(const std::vector<long int> &shape, dtypes::scalarType type = dtypes::kFloat, dtypes::deviceType device = dtypes::kCPU, bool requiresGrad = false)

Construct a tensor with ones.

  • shape The desired shape of the intitalised tensor

  • type The data type of the tensor

static Tensor zeros(const std::vector<long int> &shape, dtypes::scalarType type = dtypes::kFloat, dtypes::deviceType device = dtypes::kCPU, bool requiresGrad = false)

Construct a tensor with zeros.

  • shape The desired shape of the intitalised tensor

  • type The data type of the tensor

Setters

Set the underlying data type of this tensor

Tensor &dType(dtypes::scalarType type)
Tensor &device(dtypes::deviceType device)

Set the device that this tensor lives on.

Tensor &requiresGrad(bool reqGrad)

Set whether the tensor requires a gradient.

inline Tensor &hasBatchDim(bool hasBatchDim)

Set whether or not the first dimension should be interpreted as a batch dimension.

Getters

The underlying data type of this tensor

inline dtypes::scalarType getDType() const
inline dtypes::deviceType getDevice() const

The device that this tensor lives on.

inline bool getRequiresGrad() const

Whether the tensor requires a gradient.

inline bool isInitialised() const

Check if tensor has been initialised.

Matrix Arithmetic

Generally there are static functions with the pattern <function>(Mat1, Mat2) which will return a new matrix and inline equivalents with the pattern <function>_(Mat2) which will affect the object they are called by

void matmul_(const Tensor &tensor2)

Inplace matrix multiplication.

  • tensor2 Right hand matrix to multiply with this one

void mul_(const Tensor &tensor2)

Inplace element-wise multiplication.

  • tensor2 Right hand tensor

void div_(const Tensor &tensor2)

Inplace element-wise division.

  • tensor2 Denominator

void scale_(float scalar)

Inplace matrix scaling.

  • scalar The scalar

void scale_(std::complex<float> scalar)

Inplace complex matrix scaling.

  • scalar The scalar

void pow_(float scalar)

Inplace raise to scalar power.

  • scalar The scalar

void pow_(std::complex<float> scalar)

Inplace raise to scalar power.

  • scalar The scalar

void exp_()

Inplace element-wise exponential.

void transpose_(int dim0, int dim1)

Inplace transpose.

  • dim0 The first dimension to swap

  • dim1 The second dimension to swap

static Tensor matmul(const Tensor &tensor1, const Tensor &tensor2)

Multiply two matrices together.

  • tensor1 Left hand tensor

  • tensor2 Right hand tensor

static Tensor outer(const Tensor &tensor1, const Tensor &tensor2)

Outer product of two 1D tensors.

  • tensor1 Left hand tensor

  • tensor2 Right hand tensor

static Tensor mul(const Tensor &tensor1, const Tensor &tensor2)

Element-wise multiplication of two tensors.

  • tensor1 Left hand tensor

  • tensor2 Right hand tensor

static Tensor add(const Tensor &tensor1, const Tensor &tensor2)

Element-wise addition of two tensors.

  • tensor1 Left hand tensor

  • tensor2 Right hand tensor

static Tensor div(const Tensor &tensor1, const Tensor &tensor2)

Element-wise division of two tensors.

  • tensor1 Numerator

  • tensor2 Denominator

static Tensor pow(const Tensor &tensor, float scalar)

Raise a matrix to a scalar power.

  • tensor The tensor

  • scalar The scalar

static Tensor pow(const Tensor &tensor, double scalar)

Raise a matrix to a scalar power.

  • tensor The tensor

  • scalar The scalar

static Tensor pow(const Tensor &tensor, std::complex<float> scalar)

Raise a matrix to a scalar power.

  • tensor The tensor

  • scalar The scalar

static Tensor pow(const Tensor &tensor, std::complex<double> scalar)

Raise a matrix to a scalar power.

  • tensor The tensor

  • scalar The scalar

static inline Tensor square(const Tensor &tensor)

Element wise square, slightly faster than pow(tensor, 2.0)

  • tensor The tensor

static Tensor sqrt(const Tensor &tensor)

Get element-wise square root of tensor.

  • tensor The tensor

static Tensor exp(const Tensor &tensor)

Element-wise exponential.

  • tensor The tensor

static Tensor transpose(const Tensor &tensor, int dim0, int dim1)

Get the transpose of a tensor.

  • tensor The tensor

  • dim0 The first dimension to swap

  • dim1 The second dimension to swap

static Tensor scale(const Tensor &tensor, float scalar)

Scale a matrix by some scalar.

  • scalar The scalar

  • tensor The tensor

static Tensor scale(const Tensor &tensor, double scalar)

Scale a matrix by some scalar.

  • scalar The scalar

  • tensor The tensor

static Tensor scale(const Tensor &tensor, std::complex<float> scalar)

Scale a matrix by some complex scalar.

  • scalar The scalar

  • tensor The tensor

static Tensor scale(const Tensor &tensor, std::complex<double> scalar)

Scale a matrix by some complex scalar.

  • scalar The scalar

  • tensor The tensor

Mathematical

mathematical function overrides, generally work as expected, unless otherwise noted

bool operator==(const Tensor &rhs) const
bool operator!=(const Tensor &rhs) const
Tensor operator+(const Tensor &rhs) const
Tensor operator-(const Tensor &rhs) const
Tensor operator+(double rhs) const
Tensor operator-(double rhs) const
Tensor operator*(const Tensor &rhs) const
Tensor operator*(double rhs) const
Tensor operator/(const Tensor &rhs) const
Tensor operator/(double rhs) const
Tensor operator-() const
inline friend Tensor operator*(double lhs, const Tensor &tensor)
inline friend Tensor operator+(double lhs, const Tensor &tensor)
inline friend Tensor operator-(double lhs, const Tensor &tensor)

Gradients

void backward() const

Compute gradients of this tensor with respect to leaves Those can then be accessed using gradient()

void zeroGrad()

Set the accumulated gradient for this tensor to zero.

Warning

This should be done any time you reuse a leaf tensor to calculate another gradient. Otherwise you will get the sum of all accumulated gradients

Tensor grad() const

Return a tensor containing the accumulated gradients calculated for this tensor after calling backward()

Linear Algebra

static void eig(const Tensor &tensor, Tensor &eVals, Tensor &eVecs)

Get eigenvalues and vectors of a tensor ordering of the eigenvalues is not guarenteed for eigh!!! AAARRRGGHHH.

Todo:

: figure out a way to deal with that!

  • tensor The tensor

Parameters:
  • eVals – [out] The eigenvalues

  • eVecs – [out] The eigenvectors

static void eigh(const Tensor &tensor, Tensor &eVals, Tensor &eVecs)

Get eigenvalues and vectors of a hermitian matrix.

  • tensor The tensor

Parameters:
  • eVals – [out] The eigenvalues

  • eVecs – [out] The eigenvectors This is in general faster and more stable than Tensor::eig and should be preferred in basically all cases where it can be used

static void eigvals(const Tensor &tensor, Tensor &eVals)

Get eigenvalues of a tensor ordering of the eigenvalues is not guarenteed for eigh!!! AAARRRGGHHH.

Todo:

: figure out a way to deal with that!

  • tensor The tensor

Parameters:

eVals – [out] The eigenvalues

static void eigvalsh(const Tensor &tensor, Tensor &eVals)

Get eigenvalues of a hermitian matrix.

  • tensor The tensor

Parameters:

eVals – [out] The eigenvalues This is in general faster and more stable than Tensor::eigvals and should be preferred in basically all cases where it can be used

Trigonometric

static Tensor sin(const Tensor &tensor)

Get element-wise sin of a tensor.

Parameters:

tensor – The tensor

static Tensor cos(const Tensor &tensor)

Get element-wise cosine of a tensor.

Parameters:

tensor – The tensor

Public Types

using indexType = std::variant<int, std::string>

Holds the possible β€œindex” types, this allows us to pass integers OR strings as index values which allows us to do some basic slicing of tensors similar to python

using variantType = std::variant<int, float, double, std::complex<float>, std::complex<double>>

Container that holds all allowed types that can be returned by a tensor.

Public Functions

Tensor &addBatchDim()

If the tensor does not already have a batch dimension (as set by hasBatchDim()) this will add one.

Tensor &unsqueeze(int index)

add new dimension to the tensor at a particular index

Tensor real() const

Get the real part of a complex tensor.

Tensor imag() const

Get the imaginary part of a complex tensor.

Tensor conj() const

Get the complex conjugate of this tensor. If the underlying tensor is not complex, this will just return the tensor.

Tensor abs() const

Get elementwise absolute magnitude of a complex tensor.

Tensor angle() const

Get elementwise phases of a complex tensor.

Tensor cumsum(int dim) const

Get the cumulative sum over some dimension.

Parameters:

dim – The dimension to sum over

Tensor sum() const

Get the result of summing this tensor over all dimensions.

Tensor sum(const std::vector<long int> &dims) const

Get the result of summing this tensor over all dimensions.

Parameters:

dims – The dimensions to sum over

std::string toString() const

Print this object to a summary string.

void setValue(const std::vector<indexType> &indices, const Tensor &value)

Set the value at a particular index of the tensor.

  • indices The indices of the value to set

  • value The value to set it to

virtual void setValue(const std::vector<int> &indices, float value)
virtual void setValue(const std::vector<int> &indices, double value)
virtual void setValue(const std::vector<int> &indices, std::complex<float> value)
virtual void setValue(const std::vector<int> &indices, std::complex<double> value)
Tensor getValues(const std::vector<indexType> &indices) const

Get the value at a certain entry in the tensor.

Parameters:

indices – The index of the entry to get

variantType getVariantValue(const std::vector<int> &indices) const

Get the value at a certain entry in the tensor as an std::variant.

This mainly exists so we can get the values of a tensor in python as pybind11 DOES NOT like templated functions If using the c++ interface it is probably easier, faster and safer to use the templated getValue() function.

size_t getNdim() const

Get the number of dimensions in the tensor.

int getBatchDim() const

Get the size of the batch dimension of the tensor.

bool getHasBatchDim() const

Check if tensor has batch dimension prepended.

std::vector<long int> getShape() const

Get the shape of the tensor.

Warning

This can be somewhat slow, you should avoid using it in any performance critical loops

Public Static Functions

static bool gpuAvailable()

Check if there is a gpu available to use.

static inline Tensor cumsum(const Tensor &tensor, int dim)

Get the cumulative sum over some dimension.

Parameters:

dim – The dimension to sum over

static inline Tensor sum(const Tensor &tensor)

Get the result of summing this tensor over all dimensions.

static inline Tensor sum(const Tensor &tensor, const std::vector<long int> &dims)

Get the result of summing this tensor over all dimensions.

Parameters:

dims – The dimensions to sum over

static std::string getTensorLibrary()

Get the name of the backend library used to deal with tensors.

Protected Attributes

bool _hasBatchDim = false
bool _requiresGrad = false
bool _initialised = false
dtypes::scalarType _dType
dtypes::deviceType _device

Friends

inline friend std::ostream &operator<<(std::ostream &stream, const Tensor &tensor)

Overwrite the << operator to print this tensor out to the command line.