Class nuTens::Tensor

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.

Friends

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

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