tensor

tensor_element_access

Implementation of tensor class element access methods.

This file contains the implementations of various element access methods for the tensor class, including methods to access individual elements using indices, operator(), and operator[]. It provides both const and non-const access and handles multidimensional access.

namespace squint

tensor_op_compatibility

Helper functions for checking tensor compatibility.

This file contains helper functions for checking tensor compatibility for various tensor operations, including element-wise operations and matrix multiplication.

namespace squint

Typedefs

template<scalar S>
using blas_type_t = typename blas_type<S>::type
template<typename Sequence1, typename Sequence2>
using matrix_multiply_sequence_t = typename matrix_multiply_sequence<Sequence1, Sequence2>::type
template<typename SequenceB, typename SequenceA>
using matrix_division_sequence_t = typename matrix_division_sequence<SequenceB, SequenceA>::type

Functions

inline auto implicit_convertible_shapes_vector(std::vector<std::size_t> shape1, std::vector<std::size_t> shape2) -> bool

Helper function to check if two shapes are implicitly convertible.

Template Parameters:
  • Shape1 – The first shape type.

  • Shape2 – The second shape type.

Returns:

True if the shapes are implicitly convertible, false otherwise.

template<fixed_tensor T, typename SubviewShape>
constexpr auto subview_compatible() -> bool

Helper function to check if a tensor is compatible with a subview shape.

Template Parameters:
  • T – The tensor type.

  • SubviewShape – The subview shape type.

Returns:

True if the tensor is compatible with the subview shape, false otherwise.

template<tensorial T>
auto constexpr check_blas_layout(const T &t) -> void
template<tensorial Tensor1, tensorial Tensor2>
constexpr void blas_compatible(const Tensor1 &t1, const Tensor2 &t2)

Checks if tensors are BLAS compatible (same underlying arithmetic type).

Template Parameters:
  • Tensor1 – First tensor type.

  • Tensor2 – Second tensor type.

Parameters:
  • t1 – First tensor.

  • t2 – Second tensor.

template<tensorial Tensor1, tensorial Tensor2>
constexpr void element_wise_compatible(const Tensor1 &t1, const Tensor2 &t2)

Checks if two tensors are compatible for element-wise operations.

Template Parameters:
  • Tensor1 – First tensor type.

  • Tensor2 – Second tensor type.

Parameters:
  • t1 – First tensor.

  • t2 – Second tensor.

Throws:

std::runtime_error – if tensors are incompatible (when error checking is enabled).

template<tensorial T1, tensorial T2>
constexpr void layouts_compatible(const T1 &t1, const T2 &t2)
template<tensorial Tensor1, tensorial Tensor2>
void matrix_multiply_compatible(const Tensor1 &t1, const Tensor2 &t2)

Checks if two tensors are compatible for matrix multiplication.

Template Parameters:
  • Tensor1 – First tensor type.

  • Tensor2 – Second tensor type.

Parameters:
  • t1 – First tensor.

  • t2 – Second tensor.

Throws:

std::runtime_error – if tensors are incompatible (when error checking is enabled).

template<tensorial Tensor1>
auto compute_leading_dimension_blas(CBLAS_TRANSPOSE op, const Tensor1 &t) -> BLAS_INT

Computes the leading dimension for BLAS operations.

Template Parameters:

Tensor1 – Tensor type.

Parameters:
  • op – Transpose operation.

  • t – Tensor.

Returns:

Leading dimension for BLAS operations.

template<tensorial Tensor1>
auto compute_leading_dimension_lapack(int layout, const Tensor1 &t) -> BLAS_INT

Computes the leading dimension for LAPACK operations.

Template Parameters:

Tensor1 – Tensor type.

Parameters:
  • layout – Matrix layout (row-major or column-major).

  • t – Tensor.

Returns:

Leading dimension for LAPACK operations.

template<tensorial T1>
void check_contiguous(const T1 &t1)
template<host_tensor T>
constexpr void cross_compatible(const T &a)

Checks if two tensors are compatible for cross product operations.

Template Parameters:

T – The tensor type.

Parameters:

a – The tensor to check.

Throws:

std::invalid_argument – if the tensor is not 3D (when error checking is enabled).

template<tensorial T1, tensorial T2>
auto solve_compatible(const T1 &A, const T2 &B)

Checks if two tensors are compatible for solve operations.

Template Parameters:
  • T1 – First tensor type.

  • T2 – Second tensor type.

Parameters:
  • A – First tensor.

  • B – Second tensor.

Throws:

std::runtime_error – if tensors are incompatible (when error checking is enabled).

template<tensorial T1, tensorial T2>
auto solve_general_compatible(const T1 &A, const T2 &B)

Checks if two tensors are compatible for general solve operations.

Template Parameters:
  • T1 – First tensor type.

  • T2 – Second tensor type.

Parameters:
  • A – First tensor.

  • B – Second tensor.

Throws:

std::runtime_error – if tensors are incompatible (when error checking is enabled).

template<tensorial T>
constexpr void inversion_compatible(const T &t)

Checks if a tensor is compatible for inversion.

Template Parameters:

T – The tensor type.

Parameters:

t – The tensor to check.

Throws:

std::runtime_error – if the tensor is not square or not 2D (when error checking is enabled).

template<scalar S>
struct blas_type
#include <squint/tensor/tensor_op_compatibility.hpp>

Helper struct to get the underlying arithmetic type of a scalar.

Template Parameters:

S – The scalar type.

Public Types

using type = decltype(helper())

Public Static Functions

static inline auto helper()
template<typename SequenceB, typename SequenceA>
struct matrix_division_sequence
#include <squint/tensor/tensor_op_compatibility.hpp>

Public Types

using type = decltype(helper<SequenceB, SequenceA>())

Public Static Functions

template<typename B, typename A>
static inline auto helper()
template<typename Sequence1, typename Sequence2>
struct matrix_multiply_sequence
#include <squint/tensor/tensor_op_compatibility.hpp>

Helper struct to determine the resulting shape of matrix multiplication.

Template Parameters:
  • Sequence1 – Shape of the first tensor.

  • Sequence2 – Shape of the second tensor.

Public Types

using type = decltype(helper<Sequence1, Sequence2>())

Public Static Functions

template<typename S1, typename S2>
static inline auto helper()

tensor_shape_manipulation

namespace squint

Functions

inline auto all_less_than(const std::vector<size_t> &vec, size_t value) -> bool

Checks if all elements of a std::vector are less than a given value.

Parameters:
  • vec – The vector to check.

  • value – The value to compare against.

Returns:

True if all elements are less than the value, false otherwise.

inline auto apply_permutation_vector(const std::vector<size_t> &vec, const std::vector<size_t> &permutation, std::size_t pad_value) -> std::vector<size_t>

Applies an index permutation to a std::vector.

Parameters:
  • vec – The vector to permute.

  • permutation – The index permutation.

  • pad_value – The value to use for padding.

Returns:

The permuted vector.

tensor_math

Mathematical operations for tensor objects.

This file contains implementations of mathematical operations on tensors, including solving linear systems of equations.

namespace squint

Functions

template<host_tensor T1, host_tensor T2>
auto solve(T1 &A, T2 &B)

Solves a system of linear equations.

Parameters:
  • A – The matrix of coefficients.

  • B – The right-hand side of the equations.

Throws:

std::runtime_error – if the system is singular or an error occurs during the solution.

Returns:

The pivot indices.

template<host_tensor T1, host_tensor T2>
auto solve_general(T1 &A, T2 &B)

Solves a general system of linear equations (overdetermined or underdetermined).

Parameters:
  • A – The matrix of coefficients.

  • B – The right-hand side of the equations.

Throws:

std::runtime_error – if an error occurs during the solution.

Returns:

The pivot indices.

template<host_tensor T>
auto inv(const T &A)

Computes the inverse of a square matrix.

Parameters:

A – The matrix to invert.

Throws:

std::runtime_error – if the matrix is singular or an error occurs during inversion.

Returns:

The inverted matrix.

template<fixed_tensor T>
auto pinv(const T &A)

Computes the Moore-Penrose pseudoinverse of a matrix.

This function calculates the pseudoinverse of a matrix using the following formulas:

  • For overdetermined or square systems (m >= n): pinv(A) = (A^T * A)^-1 * A^T

  • For underdetermined systems (m < n): pinv(A) = A^T * (A * A^T)^-1

The pseudoinverse is a generalization of the inverse matrix and can be used for matrices that are not square or not of full rank.

Template Parameters:

T – The tensor type of the input matrix.

Parameters:

A – The input matrix as a tensor.

Returns:

The pseudoinverse of A as a tensor of the same type as the input.

template<host_tensor T>
auto det(const T &A)

Computes the determinant of a square matrix.

Template Parameters:

T – The tensor type.

Parameters:

A – The input matrix.

Throws:

std::runtime_error – if the matrix is not square or if an error occurs during computation.

Returns:

The determinant of the matrix.

template<host_tensor T1, host_tensor T2, host_tensor T3>
void cross(const T1 &a, const T2 &b, T3 &result)

Compute the cross product of two 3D vectors.

Parameters:
  • a – The first input vector

  • b – The second input vector

  • result – The output vector to store the cross product result

template<host_tensor T1, host_tensor T2>
auto cross(const T1 &a, const T2 &b)

Computes the cross product of two 3D vectors.

Parameters:
  • a – The first vector.

  • b – The second vector.

Throws:

std::invalid_argument – if the vectors are not 3D.

Returns:

The cross product of a and b.

template<host_tensor T1, host_tensor T2>
auto dot(const T1 &a, const T2 &b)

Computes the dot product of two vectors.

Parameters:
  • a – The first vector.

  • b – The second vector.

Throws:

std::invalid_argument – if the vectors have different sizes.

Returns:

The dot product of a and b.

template<host_tensor T>
auto trace(const T &a)

Computes the trace of a square matrix.

Parameters:

a – The input matrix.

Throws:

std::invalid_argument – if the matrix is not square.

Returns:

The trace of the matrix.

template<host_tensor T>
auto norm(const T &a)

Computes the Euclidean norm (L2 norm) of a vector.

Parameters:

a – The input vector.

Returns:

The Euclidean norm of the vector.

template<host_tensor T>
auto squared_norm(const T &a)

Computes the squared Euclidean norm of a vector.

Parameters:

a – The input vector.

Returns:

The squared Euclidean norm of the vector.

template<host_tensor T>
auto normalize(const T &a)

Normalizes a vector to have unit length.

Parameters:

a – The input vector.

Returns:

The normalized vector.

template<host_tensor T>
auto mean(const T &a)

Computes the mean of all elements in the tensor.

Parameters:

a – The input tensor.

Returns:

The mean value of all elements.

template<host_tensor T>
auto sum(const T &a)

Computes the sum of all elements in the tensor.

Parameters:

a – The input tensor.

Returns:

The sum of all elements.

template<host_tensor T>
auto min(const T &a)

Finds the minimum element in the tensor.

Parameters:

a – The input tensor.

Returns:

The minimum element.

template<host_tensor T>
auto max(const T &a)

Finds the maximum element in the tensor.

Parameters:

a – The input tensor.

Returns:

The maximum element.

template<host_tensor T1, host_tensor T2>
auto approx_equal(const T1 &a, const T2 &b, typename std::common_type_t<typename T1::value_type, typename T2::value_type> tol = std::numeric_limits<typename std::common_type_t<typename T1::value_type, typename T2::value_type>>::epsilon()) -> bool

Checks if two tensors are approximately equal within a given tolerance.

Parameters:
  • a – The first tensor.

  • b – The second tensor.

  • tol – The tolerance for comparison (default is machine epsilon).

Returns:

True if the tensors are approximately equal, false otherwise.

template<dynamic_tensor Tensor1, dynamic_tensor Tensor2>
auto contract(const Tensor1 &A, const Tensor2 &B, const std::vector<std::pair<size_t, size_t>> &contraction_pairs)

Computes the tensor product of two tensors.

Parameters:
  • A – The first tensor.

  • B – The second tensor.

  • contraction_pairs – The pairs of indices to contract.

Returns:

The tensor product of A and B.

template<fixed_tensor Tensor1, fixed_tensor Tensor2, typename Sequence1, typename Sequence2>
auto contract(const Tensor1 &A, const Tensor2 &B, const Sequence1, const Sequence2)

Computes the tensor contraction of two tensors.

Parameters:
  • A – The first tensor.

  • B – The second tensor.

  • Sequence1 – The sequence of contracted indices for the first tensor.

  • Sequence2 – The sequence of contracted indices for the second tensor.

Returns:

The result of the tensor contraction.

template<dynamic_tensor Tensor1, dynamic_tensor Tensor2>
auto einsum(const std::string &subscripts, const Tensor1 &A, const Tensor2 &B)

Computes the tensor contraction of two tensors using the Einstein summation convention.

The Einstein summation convention is a shorthand notation for tensor contraction. The subscripts string specifies the contraction pairs and the output subscripts. For example, the subscripts “ij,jk->ik” specifies the contraction of the second index of the first tensor with the first index of the second tensor, and the output subscripts are the first and third indices.

Parameters:
  • subscripts – The Einstein summation subscripts.

  • A – The first tensor.

  • B – The second tensor.

Returns:

The result of the tensor contraction.

template<dynamic_tensor Tensor>
auto einsum(const std::string &subscripts, const Tensor &tensor)

Specialization of the einsum function for a single tensor.

This function is a specialization of the einsum function for a single tensor. The subscripts string specifies the operation to perform on the tensor. For example, the subscripts “ij->ji” specifies a matrix transpose operation.

Parameters:
  • subscripts – The Einstein summation subscripts.

  • tensor – The input tensor.

Returns:

The result of the einsum operation.

template<typename ASubscripts, typename BSubscripts, typename OutputSubscripts, fixed_tensor Tensor1, fixed_tensor Tensor2>
auto einsum(const Tensor1 &A, const Tensor2 &B)

Einsum for two fixed tensors.

Template Parameters:
  • ASubscripts – The subscripts for the first tensor.

  • BSubscripts – The subscripts for the second tensor.

  • OutputSubscripts – The subscripts for the output tensor.

  • Tensor1 – The first tensor type.

  • Tensor2 – The second tensor type.

Parameters:
  • A – The first tensor.

  • B – The second tensor.

Returns:

The result of the einsum operation.

template<typename InputSubscripts, typename OutputSubscripts, typename Tensor>
auto einsum(const Tensor &tensor)

Einsum for a single fixed tensor.

Template Parameters:
  • Subscripts – The subscripts for the tensor.

  • Tensor – The tensor type.

Parameters:

tensor – The tensor.

Returns:

The result of the einsum operation.

Variables

constexpr size_t I = 0
constexpr size_t J = 1
constexpr size_t K = 2
constexpr size_t L = 3
constexpr size_t M = 4
constexpr size_t N = 5
constexpr size_t O = 6
constexpr size_t P = 7
constexpr size_t Q = 8
constexpr size_t R = 9
template<typename Tensor1, typename Tensor2, typename Sequence1, typename Sequence2>
struct contraction_types
#include <squint/tensor/tensor_math.hpp>

Helper struct to determine the types needed for tensor contraction.

Template Parameters:
  • Tensor1 – The first tensor type.

  • Tensor2 – The second tensor type.

  • Sequence1 – The sequence of contracted indices for the first tensor.

  • Sequence2 – The sequence of contracted indices for the second tensor.

Public Types

using A_shape = typename Tensor1::shape_type
using B_shape = typename Tensor2::shape_type
template<size_t I>
using is_A_contracted = is_contracted<Sequence1, Sequence2, 0, I>
template<size_t I>
using is_A_free = is_free<Sequence1, Sequence2, 0, I>
template<size_t I>
using is_B_contracted = is_contracted<Sequence1, Sequence2, 1, I>
template<size_t I>
using is_B_free = is_free<Sequence1, Sequence2, 1, I>
using A_free_indices = filter_sequence_t<std::make_index_sequence<A_rank>, is_A_free>
using A_contract_indices = filter_sequence_t<std::make_index_sequence<A_rank>, is_A_contracted>
using B_free_indices = filter_sequence_t<std::make_index_sequence<B_rank>, is_B_free>
using B_contract_indices = filter_sequence_t<std::make_index_sequence<B_rank>, is_B_contracted>
using A_permutation = concat_sequence_t<A_free_indices, A_contract_indices>
using B_permutation = concat_sequence_t<B_contract_indices, B_free_indices>
using result_shape = concat_sequence_t<select_values_t<A_shape, A_free_indices>, select_values_t<B_shape, B_free_indices>>

Public Static Attributes

static constexpr size_t A_rank = A_shape::size()
static constexpr size_t B_rank = B_shape::size()
static constexpr size_t A_rows = product(select_values_t<A_shape, A_free_indices>{})
static constexpr size_t B_cols = product(select_values_t<B_shape, B_free_indices>{})
static constexpr size_t common_dim = product(select_values_t<A_shape, A_contract_indices>{})
template<typename ASubscripts, typename BSubscripts>
struct get_contraction_indices
#include <squint/tensor/tensor_math.hpp>

Public Types

using type = decltype(to_sequence(std::make_index_sequence<indices_and_count.second>{}))

Public Static Functions

template<std::size_t... Is>
static inline constexpr auto helper(std::index_sequence<Is...>)
template<std::size_t... Is>
static inline constexpr auto to_sequence(std::index_sequence<Is...>)

Public Static Attributes

static constexpr auto indices_and_count = helper(std::make_index_sequence<ASubscripts::size()>{})
template<typename Sequence1, typename Sequence2, size_t TensorId, size_t Idx>
struct is_contracted
#include <squint/tensor/tensor_math.hpp>

Helper function to determine if an index is contracted or free.

Template Parameters:
  • Sequence1 – The sequence of contracted indices for the first tensor.

  • Sequence2 – The sequence of contracted indices for the second tensor.

  • TensorId – The tensor id (0 for the first tensor, 1 for the second tensor).

  • Idx – The index to check.

Return:

True if the index is contracted, false otherwise.

Public Static Functions

static inline constexpr auto value() -> bool
template<typename Sequence1, typename Sequence2, size_t TensorId, size_t Idx>
struct is_free
#include <squint/tensor/tensor_math.hpp>

Helper function to determine if an index is contracted or free.

Template Parameters:
  • Sequence1 – The sequence of contracted indices for the first tensor.

  • Sequence2 – The sequence of contracted indices for the second tensor.

  • TensorId – The tensor id (0 for the first tensor, 1 for the second tensor).

  • Idx – The index to check.

Return:

True if the index is free, false otherwise.

Public Static Functions

static inline constexpr auto value() -> bool
template<std::size_t Val, std::size_t... Seq>
struct is_in_sequence<Val, std::index_sequence<Seq...>> : public std::bool_constant<((Val == Seq) || ...)>
#include <squint/tensor/tensor_math.hpp>

tensor_io

Input/output operations for tensor objects.

This file contains implementations of output operations for tensors, including streaming output from streams.

namespace squint

Functions

template<typename TensorType>
void print_2d_slice(std::ostream &os, const TensorType &t)

Prints a 2D slice of a tensor to an output stream.

Parameters:
  • os – The output stream to write to.

  • t – The tensor to print.

template<typename TensorType>
void print_1d_slice(std::ostream &os, const TensorType &t)

Prints a 1D slice of a tensor as a column vector to an output stream.

Parameters:
  • os – The output stream to write to.

  • t – The tensor to print.

template<typename T, typename Shape, typename Strides, error_checking ErrorChecking, ownership_type OwnershipType, memory_space MemorySpace>
auto operator<<(std::ostream &os, const tensor<T, Shape, Strides, ErrorChecking, OwnershipType, MemorySpace> &t) -> std::ostream&

Outputs a tensor to an output stream.

Parameters:
  • os – The output stream to write to.

  • t – The tensor to output.

Returns:

Reference to the output stream.

Variables

constexpr int SCALAR_WIDTH = 6
constexpr int SCALAR_PRECISION = 4

blas_backend

Defines the backend for BLAS and LAPACK operations.

This file provides the backend for BLAS and LAPACK operations in the Squint library. The backend is selected at compile time by defining one of the following macros:

  • SQUINT_BLAS_BACKEND_MKL: Use Intel MKL as the backend.

  • SQUINT_BLAS_BACKEND_OPENBLAS: Use OpenBLAS as the backend.

  • SQUINT_BLAS_BACKEND_NONE: Use a fallback backend that provides basic implementations.

blas_backend_none

Fallback implementations for BLAS and LAPACK functions.

This file provides basic implementations of key BLAS and LAPACK functions for use when no hardware-specific BLAS library is available. These implementations are not optimized for performance but provide the necessary functionality.

NOTE: this file is very lightweight, but I decided to use the reference LAPACK and CBLAS implementations to ensure correctness. Therefore, the code is not used anywhere in the project anymore and could be removed.

namespace squint

Enums

enum class CBLAS_ORDER

Values:

enumerator CblasRowMajor
enumerator CblasColMajor
enum class CBLAS_TRANSPOSE

Values:

enumerator CblasNoTrans
enumerator CblasTrans
enumerator CblasConjTrans

Functions

template<typename T>
void swap_row(T *matrix, int row1, int row2, int n, int lda)

Swaps two rows in a matrix.

Parameters:
  • matrix – Pointer to the matrix.

  • row1 – Index of the first row to swap.

  • row2 – Index of the second row to swap.

  • n – Number of columns in the matrix.

  • lda – Leading dimension of the matrix.

template<typename T>
auto matrix_element(T *matrix, int i, int j, int lda, int matrix_layout) -> T&

Accesses an element in a matrix, considering its layout.

Parameters:
  • matrix – Pointer to the matrix.

  • i – Row index.

  • j – Column index.

  • lda – Leading dimension of the matrix.

  • matrix_layout – Layout of the matrix (row-major or column-major).

Returns:

Reference to the matrix element.

template<typename T>
void gemm(CBLAS_ORDER order, CBLAS_TRANSPOSE trans_a, CBLAS_TRANSPOSE trans_b, int m, int n, int k, T alpha, const T *a, int lda, const T *b, int ldb, T beta, T *c, int ldc)

General matrix multiplication (GEMM) implementation.

Computes C = alpha * op(A) * op(B) + beta * C, where op(X) is either X or X^T.

template<typename T>
auto getrf(int matrix_layout, int m, int n, T *a, int lda, int *ipiv) -> int

LU factorization of a general M-by-N matrix (GETRF).

Computes an LU factorization of a general M-by-N matrix A using partial pivoting with row interchanges.

template<typename T>
int getri(int matrix_layout, int n, T *a, int lda, const int *ipiv)

Compute the inverse of a matrix using the LU factorization (GETRI).

Computes the inverse of a matrix using the LU factorization computed by GETRF.

template<typename T>
auto gesv(int matrix_layout, int n, int nrhs, T *a, int lda, int *ipiv, T *b, int ldb) -> int

Solve a system of linear equations (GESV).

Computes the solution to a real system of linear equations A * X = B.

template<typename T>
auto gels(int matrix_layout, char trans, int m, int n, int nrhs, T *a, int lda, T *b, int ldb) -> int

Solve overdetermined or underdetermined linear systems (GELS).

Solves overdetermined or underdetermined real linear systems involving an M-by-N matrix A, or its transpose, using a QR or LQ factorization of A.

Variables

constexpr int LAPACK_ROW_MAJOR = 101
constexpr int LAPACK_COL_MAJOR = 102

flat_iterator

Defines the flat_iterator class for linear traversal of multi-dimensional tensors.

This file contains the implementation of the flat_iterator class, which provides a way to iterate over all elements of a tensor in a linear fashion, regardless of its dimensionality. The iterator supports both fixed and dynamic tensor types and satisfies the requirements of a random access iterator.

Key features:

  • Linear traversal of multi-dimensional tensors

  • Support for both fixed and dynamic tensor types

  • Random access iterator capabilities

  • Arithmetic operations for iterator manipulation

  • Comparison operations between iterators

namespace squint
template<typename TensorType>
class flat_iterator
#include <squint/tensor/flat_iterator.hpp>

A flat iterator for linear traversal of tensor elements.

This class provides a way to iterate over all elements of a tensor in a linear fashion, regardless of its dimensionality. It satisfies the requirements of a random access iterator.

Template Parameters:

TensorType – The type of the tensor being iterated.

Public Types

using index_type = typename TensorType::index_type

Type used for indexing.

using value_type = typename TensorType::value_type

Type of the tensor elements.

using iterator_category = std::random_access_iterator_tag

Iterator category (random access iterator).

using difference_type = std::ptrdiff_t

Difference type for the iterator.

using pointer = std::conditional_t<const_tensor<TensorType>, const value_type*, value_type*>

Pointer type, const-qualified for const tensors.

using reference = std::conditional_t<const_tensor<TensorType>, const value_type&, value_type&>

Reference type, const-qualified for const tensors.

Public Functions

inline flat_iterator(TensorType *tensor, const index_type &indices)

Construct a new flat iterator object.

Parameters:
  • tensor – Pointer to the tensor being iterated.

  • indices – Starting indices of the iterator.

inline auto operator*() const -> reference

Dereference operator.

Returns:

reference A reference to the current element.

inline auto operator->() const -> pointer

Arrow operator.

Returns:

pointer A pointer to the current element.

inline auto operator++() -> flat_iterator&

Pre-increment operator.

Returns:

flat_iterator& Reference to the incremented iterator.

inline auto operator++(int) -> flat_iterator

Post-increment operator.

Returns:

flat_iterator Copy of the iterator before incrementing.

inline auto operator--() -> flat_iterator&

Pre-decrement operator.

Returns:

flat_iterator& Reference to the decremented iterator.

inline auto operator--(int) -> flat_iterator

Post-decrement operator.

Returns:

flat_iterator Copy of the iterator before decrementing.

inline auto operator+=(difference_type n) -> flat_iterator&

Compound addition assignment operator.

Parameters:

n – Number of positions to advance the iterator.

Returns:

flat_iterator& Reference to the advanced iterator.

inline auto operator-=(difference_type n) -> flat_iterator&

Compound subtraction assignment operator.

Parameters:

n – Number of positions to move the iterator backwards.

Returns:

flat_iterator& Reference to the moved iterator.

inline auto operator+(difference_type n) const -> flat_iterator

Addition operator.

Parameters:

n – Number of positions to advance the iterator.

Returns:

flat_iterator New iterator advanced by n positions.

inline auto operator-(difference_type n) const -> flat_iterator

Subtraction operator.

Parameters:

n – Number of positions to move the iterator backwards.

Returns:

flat_iterator New iterator moved backwards by n positions.

inline auto operator-(const flat_iterator &other) const -> difference_type

Difference operator between two iterators.

Parameters:

other – Another iterator to compute the difference with.

Returns:

difference_type The number of elements between the two iterators.

inline auto operator[](difference_type n) const -> reference

Subscript operator.

Parameters:

n – Offset from the current position.

Returns:

reference Reference to the element at the offset position.

inline auto operator==(const flat_iterator &other) const -> bool

Equality comparison operator.

Parameters:

other – Another iterator to compare with.

Returns:

true if the iterators are equal, false otherwise.

inline auto operator!=(const flat_iterator &other) const -> bool

Inequality comparison operator.

Parameters:

other – Another iterator to compare with.

Returns:

true if the iterators are not equal, false otherwise.

inline auto operator<(const flat_iterator &other) const -> bool

Less than comparison operator.

Parameters:

other – Another iterator to compare with.

Returns:

true if this iterator is less than the other, false otherwise.

inline auto operator>(const flat_iterator &other) const -> bool

Greater than comparison operator.

Parameters:

other – Another iterator to compare with.

Returns:

true if this iterator is greater than the other, false otherwise.

inline auto operator<=(const flat_iterator &other) const -> bool

Less than or equal to comparison operator.

Parameters:

other – Another iterator to compare with.

Returns:

true if this iterator is less than or equal to the other, false otherwise.

inline auto operator>=(const flat_iterator &other) const -> bool

Greater than or equal to comparison operator.

Parameters:

other – Another iterator to compare with.

Returns:

true if this iterator is greater than or equal to the other, false otherwise.

Private Members

TensorType *tensor_

Pointer to the tensor being iterated.

index_type current_indices_

Current position of the iterator.

index_type shape_

Shape of the tensor.

index_type strides_

Strides of the tensor.

Friends

inline friend auto operator+(difference_type n, const flat_iterator &it) -> flat_iterator

Friend function for addition of an integer and an iterator.

Parameters:
  • n – Number of positions to advance the iterator.

  • it – The iterator to advance.

Returns:

flat_iterator New iterator advanced by n positions.

tensor_types

Type aliases for creating tensors with specific types and dimensions.

This file contains type aliases for creating tensors with specific types and dimensions. These aliases simplify the creation of tensor objects with specific data types and shapes.

namespace squint

Typedefs

template<typename T>
using vec2_t = tensor<T, shape<2>>
template<typename T>
using vec3_t = tensor<T, shape<3>>
template<typename T>
using vec4_t = tensor<T, shape<4>>
using ivec2 = vec2_t<int>
using ivec3 = vec3_t<int>
using ivec4 = vec4_t<int>
using uvec2 = vec2_t<unsigned char>
using uvec3 = vec3_t<unsigned char>
using uvec4 = vec4_t<unsigned char>
using vec2 = vec2_t<float>
using vec3 = vec3_t<float>
using vec4 = vec4_t<float>
using dvec2 = vec2_t<double>
using dvec3 = vec3_t<double>
using dvec4 = vec4_t<double>
using bvec2 = vec2_t<uint8_t>
using bvec3 = vec3_t<uint8_t>
using bvec4 = vec4_t<uint8_t>
template<typename T>
using mat2_t = tensor<T, shape<2, 2>>
template<typename T>
using mat3_t = tensor<T, shape<3, 3>>
template<typename T>
using mat4_t = tensor<T, shape<4, 4>>
using imat2 = mat2_t<int>
using imat3 = mat3_t<int>
using imat4 = mat4_t<int>
using umat2 = mat2_t<unsigned char>
using umat3 = mat3_t<unsigned char>
using umat4 = mat4_t<unsigned char>
using mat2 = mat2_t<float>
using mat3 = mat3_t<float>
using mat4 = mat4_t<float>
using dmat2 = mat2_t<double>
using dmat3 = mat3_t<double>
using dmat4 = mat4_t<double>
using bmat2 = mat2_t<uint8_t>
using bmat3 = mat3_t<uint8_t>
using bmat4 = mat4_t<uint8_t>
template<typename T>
using mat2x3_t = tensor<T, shape<2, 3>>
template<typename T>
using mat2x4_t = tensor<T, shape<2, 4>>
template<typename T>
using mat3x2_t = tensor<T, shape<3, 2>>
template<typename T>
using mat3x4_t = tensor<T, shape<3, 4>>
template<typename T>
using mat4x2_t = tensor<T, shape<4, 2>>
template<typename T>
using mat4x3_t = tensor<T, shape<4, 3>>
using imat2x3 = mat2x3_t<int>
using imat2x4 = mat2x4_t<int>
using imat3x2 = mat3x2_t<int>
using imat3x4 = mat3x4_t<int>
using imat4x2 = mat4x2_t<int>
using imat4x3 = mat4x3_t<int>
using umat2x3 = mat2x3_t<unsigned char>
using umat2x4 = mat2x4_t<unsigned char>
using umat3x2 = mat3x2_t<unsigned char>
using umat3x4 = mat3x4_t<unsigned char>
using umat4x2 = mat4x2_t<unsigned char>
using umat4x3 = mat4x3_t<unsigned char>
using mat2x3 = mat2x3_t<float>
using mat2x4 = mat2x4_t<float>
using mat3x2 = mat3x2_t<float>
using mat3x4 = mat3x4_t<float>
using mat4x2 = mat4x2_t<float>
using mat4x3 = mat4x3_t<float>
using dmat2x3 = mat2x3_t<double>
using dmat2x4 = mat2x4_t<double>
using dmat3x2 = mat3x2_t<double>
using dmat3x4 = mat3x4_t<double>
using dmat4x2 = mat4x2_t<double>
using dmat4x3 = mat4x3_t<double>
using bmat2x3 = mat2x3_t<uint8_t>
using bmat2x4 = mat2x4_t<uint8_t>
using bmat3x2 = mat3x2_t<uint8_t>
using bmat3x4 = mat3x4_t<uint8_t>
using bmat4x2 = mat4x2_t<uint8_t>
using bmat4x3 = mat4x3_t<uint8_t>
template<typename T, std::size_t... Dims>
using ndarr_t = tensor<T, shape<Dims...>>
template<std::size_t... Dims>
using indarr = ndarr_t<int, Dims...>
template<std::size_t... Dims>
using undarr = ndarr_t<unsigned char, Dims...>
template<std::size_t... Dims>
using ndarr = ndarr_t<float, Dims...>
template<std::size_t... Dims>
using dndarr = ndarr_t<double, Dims...>
template<std::size_t... Dims>
using bndarr = ndarr_t<uint8_t, Dims...>
template<typename T>
using tens_t = tensor<T, dynamic, dynamic>
using itens = tens_t<int>
using utens = tens_t<unsigned char>
using tens = tens_t<float>
using dtens = tens_t<double>
using btens = tens_t<uint8_t>

scalar_ops

Scalar operations for tensor objects.

This file contains implementations of scalar operations on tensors, including multiplication and division by scalars.

namespace squint

Functions

template<scalar T>
constexpr auto get_scalar_value(const T &s) -> const auto&
template<typename T, typename Shape, typename Strides, error_checking ErrorChecking, ownership_type OwnershipType, memory_space MemorySpace, scalar U>
auto operator*(const tensor<T, Shape, Strides, ErrorChecking, OwnershipType, MemorySpace> &t, const U &s)

Tensor-scalar multiplication operator.

Parameters:
  • t – The tensor to be multiplied.

  • s – The scalar to multiply by.

Returns:

A new tensor containing the result of the multiplication.

template<typename T, typename Shape, typename Strides, error_checking ErrorChecking, ownership_type OwnershipType, memory_space MemorySpace, scalar U>
auto operator*(const U &s, const tensor<T, Shape, Strides, ErrorChecking, OwnershipType, MemorySpace> &t)

Scalar-tensor multiplication operator.

Parameters:
  • s – The scalar to multiply by.

  • t – The tensor to be multiplied.

Returns:

A new tensor containing the result of the multiplication.

template<typename T, typename Shape, typename Strides, error_checking ErrorChecking, ownership_type OwnershipType, memory_space MemorySpace, scalar U>
auto operator/(const tensor<T, Shape, Strides, ErrorChecking, OwnershipType, MemorySpace> &t, const U &s)

Tensor-scalar division operator.

Parameters:
  • t – The tensor to be divided.

  • s – The scalar to divide by.

Returns:

A new tensor containing the result of the division.

tensor_accessors

Implementation of tensor class accessor methods.

This file contains the implementations of various accessor methods for the tensor class, including methods to retrieve the rank, shape, strides, size, and data pointer of the tensor. These methods provide essential information about the tensor’s structure and contents.

namespace squint

tensor_iteration

Implementation of tensor class iteration methods.

This file contains the implementations of various iteration methods for the tensor class, including methods to iterate over rows, columns, and subviews of the tensor.

namespace squint

subview_iterator

Defines the subview_iterator class for efficient iteration over tensor subviews.

This file contains the implementation of the subview_iterator class, which provides a random access iterator interface for traversing subviews of tensors. It supports both fixed and dynamic tensor types, allowing for efficient iteration over subviews without creating new tensor objects for each subview.

Key features:

  • Random access iterator capabilities

  • Support for both fixed and dynamic tensor types

  • Efficient subview traversal without creating intermediate tensor objects

  • Comprehensive operator overloads for iterator manipulation

namespace squint
template<typename Iterator>
class iterator_range
#include <squint/tensor/subview_iterator.hpp>

A custom iterator range class.

This class represents a range defined by two iterators. It provides a convenient way to use range-based for loops with custom iterators.

Template Parameters:

Iterator – The type of iterator used to define the range.

Public Functions

inline iterator_range(Iterator begin, Iterator end)

Construct a new iterator range object.

Parameters:
  • begin – The iterator pointing to the start of the range.

  • end – The iterator pointing to the end of the range.

inline auto begin() const -> Iterator

Get the iterator pointing to the start of the range.

Returns:

Iterator to the start of the range.

inline auto end() const -> Iterator

Get the iterator pointing to the end of the range.

Returns:

Iterator to the end of the range.

Private Members

Iterator begin_

Iterator pointing to the start of the range.

Iterator end_

Iterator pointing to the end of the range.

template<typename TensorType, typename SubviewShape>
class subview_iterator
#include <squint/tensor/subview_iterator.hpp>

Iterator class for tensor subviews.

This class provides a random access iterator interface for traversing subviews of a tensor. It supports both fixed and dynamic tensor types and allows efficient iteration over subviews without creating new tensor objects for each subview.

Template Parameters:
  • TensorType – The type of the tensor being iterated.

  • SubviewShape – The shape of the subview being iterated.

Public Types

using value_type = typename TensorType::value_type

Type of the tensor elements.

using index_type = typename TensorType::index_type

Type used for indexing.

using iterator_category = std::random_access_iterator_tag

Iterator category (random access iterator).

using difference_type = std::ptrdiff_t

Difference type for the iterator.

using pointer = std::conditional_t<const_tensor<TensorType>, const value_type*, value_type*>

Pointer type, const-qualified for const tensors.

using reference = std::conditional_t<const_tensor<TensorType>, const value_type&, value_type&>

Reference type, const-qualified for const tensors.

Public Functions

inline subview_iterator(TensorType *tensor, const index_type &start_indices, const index_type &subview_shape)

Constructs a new subview iterator.

Parameters:
  • tensor – Pointer to the tensor being iterated.

  • start_indices – Starting indices of the subview.

  • subview_shape – Shape of the subview.

inline auto operator++() -> subview_iterator&

Pre-increment operator.

Returns:

Reference to the incremented iterator.

inline auto operator++(int) -> subview_iterator

Post-increment operator.

Returns:

Copy of the iterator before incrementing.

inline auto operator--() -> subview_iterator&

Pre-decrement operator.

Returns:

Reference to the decremented iterator.

inline auto operator--(int) -> subview_iterator

Post-decrement operator.

Returns:

Copy of the iterator before decrementing.

inline auto operator+=(difference_type n) -> subview_iterator&

Compound addition assignment operator.

Parameters:

n – Number of positions to advance the iterator.

Returns:

Reference to the advanced iterator.

inline auto operator-=(difference_type n) -> subview_iterator&

Compound subtraction assignment operator.

Parameters:

n – Number of positions to move the iterator backwards.

Returns:

Reference to the moved iterator.

inline auto operator+(difference_type n) const -> subview_iterator

Addition operator.

Parameters:

n – Number of positions to advance the iterator.

Returns:

New iterator advanced by n positions.

inline auto operator-(difference_type n) const -> subview_iterator

Subtraction operator.

Parameters:

n – Number of positions to move the iterator backwards.

Returns:

New iterator moved backwards by n positions.

inline auto operator-(const subview_iterator &other) const -> difference_type

Difference operator between two iterators.

Parameters:

other – Another iterator to compute the difference with.

Returns:

The number of elements between the two iterators.

inline auto operator*() const

Dereference operator.

Returns:

A subview of the tensor at the current iterator position.

inline auto operator[](difference_type n) const

Subscript operator.

Parameters:

n – Offset from the current position.

Returns:

Subview at the offset position.

inline auto operator==(const subview_iterator &other) const -> bool

Equality comparison operator.

Parameters:

other – Another iterator to compare with.

Returns:

true if the iterators are equal, false otherwise.

inline auto operator!=(const subview_iterator &other) const -> bool

Inequality comparison operator.

Parameters:

other – Another iterator to compare with.

Returns:

true if the iterators are not equal, false otherwise.

inline auto operator<(const subview_iterator &other) const -> bool

Less than comparison operator.

Parameters:

other – Another iterator to compare with.

Returns:

true if this iterator is less than the other, false otherwise.

inline auto operator>(const subview_iterator &other) const -> bool

Greater than comparison operator.

Parameters:

other – Another iterator to compare with.

Returns:

true if this iterator is greater than the other, false otherwise.

inline auto operator<=(const subview_iterator &other) const -> bool

Less than or equal to comparison operator.

Parameters:

other – Another iterator to compare with.

Returns:

true if this iterator is less than or equal to the other, false otherwise.

inline auto operator>=(const subview_iterator &other) const -> bool

Greater than or equal to comparison operator.

Parameters:

other – Another iterator to compare with.

Returns:

true if this iterator is greater than or equal to the other, false otherwise.

Private Functions

inline void increment()

Increments the iterator to the next position.

inline void decrement()

Decrements the iterator to the previous position.

inline void advance(difference_type n)

Advances the iterator by n positions.

Parameters:

n – Number of positions to advance (can be negative).

inline auto linear_index() const -> difference_type

Calculates the linear index of the current position.

Returns:

The linear index.

inline auto get_offset() const -> index_type

Calculates the offset for the current subview.

Returns:

The index_type representing the offset of the current subview.

Private Members

TensorType *tensor_

Pointer to the tensor being iterated.

index_type current_indices_

Current position of the iterator.

index_type subview_shape_

Shape of the subview.

index_type tensor_shape_

Shape of the entire tensor.

Friends

inline friend auto operator+(difference_type n, const subview_iterator &it) -> subview_iterator

Addition operator for adding an integer to an iterator.

Parameters:
  • n – Number of positions to advance the iterator.

  • it – The iterator to advance.

Returns:

New iterator advanced by n positions.

tensor_assignment

Implementation of tensor class assignment operators.

This file contains the implementations of assignment operators for the tensor class, including assignment from other tensors and copy assignment.

namespace squint

element_wise_ops

Element-wise operations for tensor objects.

This file contains implementations of element-wise operations on tensors, including addition, subtraction, equality comparison, and negation.

namespace squint

Functions

template<typename T, typename Shape, typename Strides, error_checking ErrorChecking, ownership_type OwnershipType, memory_space MemorySpace, typename U, typename OtherShape, typename OtherStrides, enum error_checking OtherErrorChecking, enum ownership_type OtherOwnershipType>
auto operator+(const tensor<T, Shape, Strides, ErrorChecking, OwnershipType, MemorySpace> &lhs, const tensor<U, OtherShape, OtherStrides, OtherErrorChecking, OtherOwnershipType, MemorySpace> &rhs)

Element-wise addition operator.

Parameters:
  • lhs – The left-hand side tensor.

  • rhs – The right-hand side tensor.

Returns:

A new tensor containing the element-wise sum.

template<typename T, typename Shape, typename Strides, error_checking ErrorChecking, ownership_type OwnershipType, memory_space MemorySpace, typename U, typename OtherShape, typename OtherStrides, enum error_checking OtherErrorChecking, enum ownership_type OtherOwnershipType>
auto operator-(const tensor<T, Shape, Strides, ErrorChecking, OwnershipType, MemorySpace> &lhs, const tensor<U, OtherShape, OtherStrides, OtherErrorChecking, OtherOwnershipType, MemorySpace> &rhs)

Element-wise subtraction operator.

Parameters:
  • lhs – The left-hand side tensor.

  • rhs – The right-hand side tensor.

Returns:

A new tensor containing the element-wise difference.

tensor_constructors

Implementation of tensor class constructors.

This file contains the implementations of various constructors for the tensor class, including default construction, initialization from lists or arrays, and construction of owning and non-owning tensors with fixed or dynamic shapes.

namespace squint

tensor_creation

Implementation of static tensor creation methods.

This file contains the implementations of various static methods for creating tensors with specific initial values or patterns. These methods include creating tensors filled with zeros, ones, a specific value, random values, identity tensors, and diagonal tensors.

namespace squint

tensor_ops

Tensor operations for tensor objects.

This file contains implementations of tensor operations on tensors, including matrix-matrix multiplication.

namespace squint

Functions

template<tensorial Tensor1, tensorial Tensor2>
auto operator*(const Tensor1 &t1, const Tensor2 &t2)

General matrix-matrix multiplication operator.

Parameters:
  • t1 – The first tensor to multiply.

  • t2 – The second tensor to multiply.

Returns:

A new tensor containing the result of the multiplication.

template<host_tensor T1, host_tensor T2>
auto operator/(const T1 &B, const T2 &A)

General least squares or least norm solution operator.

This function computes the least squares solution when Ax =B is overdetermined and the least norm solution when Ax = B is underdetermined.

Parameters:
  • A – The matrix A in the equation Ax = B.

  • B – The matrix B in the equation Ax = B.

Returns:

A new tensor containing the solution x.

tensor_view_operations

Implementation of tensor class view and subview operations.

This file contains the implementations of various view and subview operations for the tensor class, including methods to create subviews with fixed and dynamic shapes, full tensor views, and diagonal views. It provides both const and non-const versions of these operations.

namespace squint

tensor

Defines the tensor class for multi-dimensional array operations.

This file contains the implementation of the tensor class, which provides a flexible and efficient representation of multi-dimensional arrays. The tensor class supports both fixed and dynamic shapes, various memory layouts, and different ownership models. It also includes functionality for creating subviews and iterating over tensor elements.

Key features:

  • Single class policy based design

  • Support for fixed and dynamic tensor shapes

  • Configurable error checking

  • Flexible memory ownership (owner or reference)

  • Support for different memory spaces (e.g., host, device)

  • Subview creation and iteration

namespace squint
template<typename T, typename Shape, typename Strides = strides::column_major<Shape>, error_checking ErrorChecking = error_checking::disabled, ownership_type OwnershipType = ownership_type::owner, memory_space MemorySpace = memory_space::host>
class tensor
#include <squint/tensor/tensor.hpp>

A multi-dimensional tensor class with flexible shape, strides, and memory management.

Template Parameters:
  • T – The data type of the tensor elements.

  • Shape – The shape type of the tensor, can be fixed or dynamic.

  • Strides – The strides type of the tensor, defaults to column-major strides.

  • ErrorChecking – Enum to enable or disable bounds checking.

  • OwnershipType – Enum to specify whether the tensor owns its data or is a view.

  • MemorySpace – Enum to specify the memory space of the tensor data.

Public Types

using value_type = T

The type of the tensor elements.

using shape_type = Shape

The type used to represent the tensor shape.

using strides_type = Strides

The type used to represent the tensor strides.

using index_type = std::conditional_t<fixed_shape<Shape>, std::array<std::size_t, _rank()>, std::vector<std::size_t>>

The type used for indexing, std::array for fixed shapes, std::vector for dynamic shapes.

Public Functions

~tensor() = default
tensor() = default
tensor(const tensor &other) = default
tensor(tensor &&other) noexcept = default
inline tensor(tensor &&other) noexcept
inline tensor()
inline tensor(const std::vector<size_t> &shape)
tensor(std::initializer_list<T> init)

Constructs a tensor from an initializer list.

Parameters:

init – The initializer list containing the tensor elements.

Throws:

std::invalid_argument – if the initializer list size doesn’t match the tensor size (when error checking is enabled).

explicit tensor(const T &value)

Constructs a tensor filled with a single value.

Parameters:

value – The value to fill the tensor with.

tensor(const std::array<T, _size()> &elements)

Constructs a tensor from a std::array.

Parameters:

elements – The array containing the tensor elements.

Throws:

std::invalid_argument – if the array size doesn’t match the tensor size (when error checking is enabled).

template<fixed_tensor... OtherTensor>
tensor(const OtherTensor&... ts)

Constructs a tensor from other fixed tensors.

Parameters:

ts – The tensors to construct from.

tensor(Shape shape, Strides strides)

Constructs a dynamic shape tensor with given shape and strides.

Parameters:
  • shape – The shape of the tensor.

  • strides – The strides of the tensor.

tensor(Shape shape, layout l = layout::column_major)

Constructs a dynamic shape tensor with given shape and layout.

Parameters:
  • shape – The shape of the tensor.

  • l – The layout of the tensor.

tensor(std::vector<size_t> shape, const std::vector<T> &elements, layout l = layout::column_major)

Constructs a dynamic shape tensor with given shape, elements, and layout.

Parameters:
  • shape – The shape of the tensor.

  • elements – The elements of the tensor.

  • l – The layout of the tensor.

Throws:

std::invalid_argument – if the elements size doesn’t match the tensor size (when error checking is enabled).

tensor(std::vector<size_t> shape, const T &value, layout l = layout::column_major)

Constructs a dynamic shape tensor filled with a single value.

Parameters:
  • shape – The shape of the tensor.

  • value – The value to fill the tensor with.

  • l – The layout of the tensor.

template<typename U, typename OtherShape, typename OtherStrides>
tensor(const tensor<U, OtherShape, OtherStrides, ErrorChecking, OwnershipType, MemorySpace> &other)

Constructs a tensor from another tensor of a different shape.

This constructor allows for implicit conversion to a tensor of the same shape with trailing 1’s removed.

Parameters:

other – The tensor to construct from.

template<typename U, typename OtherShape, typename OtherStrides>
tensor(const tensor<U, OtherShape, OtherStrides, ErrorChecking, ownership_type::reference, MemorySpace> &other)

Constructs a tensor from another tensor of a different shape.

This constructor allows implicit conversion for compatible tensors of various shape from reference ownership type to owner ownership type

Parameters:

other – The tensor to construct from.

tensor(T *data, Shape shape, Strides strides)

Constructs a tensor from another tensor of a different shape.

This constructor constructs a tensor with reference ownership type from a pointer to data and a shape and strides.

Parameters:
  • data – The pointer to the data.

  • shape – The shape of the tensor.

  • strides – The strides of the tensor.

tensor(T *data)

Constructs a tensor from a pointer to data.

This constructor constructs a tensor with reference ownership type from a pointer to data.

Parameters:

data – The pointer to the data.

inline ~tensor()
template<typename U, typename OtherShape, typename OtherStrides, ownership_type OtherOwnershipType>
auto operator=(const tensor<U, OtherShape, OtherStrides, ErrorChecking, OtherOwnershipType, MemorySpace> &other) -> tensor&

Assigns the contents of another tensor to this tensor.

Parameters:

other – The tensor to assign from.

Throws:

std::runtime_error – if tensors have different sizes (when error checking is enabled).

Returns:

Reference to the modified tensor.

auto operator=(const tensor &other) -> tensor&

Copies the contents of another tensor of the same type to this tensor.

Parameters:

other – The tensor to copy from.

Throws:

std::runtime_error – if tensors have different sizes (when error checking is enabled).

Returns:

Reference to the modified tensor.

auto operator=(tensor &&other) noexcept -> tensor& = default
constexpr auto rank() const -> std::size_t

Returns the rank (number of dimensions) of the tensor.

Returns:

The rank of the tensor.

constexpr auto shape() const -> const index_type&

Returns the shape of the tensor.

Returns:

A reference to the tensor’s shape.

constexpr auto strides() const -> const index_type&

Returns the strides of the tensor.

Returns:

A reference to the tensor’s strides.

constexpr auto size() const -> std::size_t

Returns the total number of elements in the tensor.

Returns:

The total number of elements.

constexpr auto data() const -> const T*

Returns a const pointer to the underlying data of the tensor.

Returns:

A const pointer to the tensor’s data.

constexpr auto data() -> T*

Returns a non-const pointer to the underlying data of the tensor.

Returns:

A pointer to the tensor’s data.

inline auto device_shape() const -> device_shape_storage
requires (MemorySpace == memory_space::device)
inline auto device_strides() const -> device_strides_storage
requires (MemorySpace == memory_space::device)
auto access_element(const index_type &indices) const -> const T&
requires (MemorySpace == memory_space::host)

Accesses an element using an index_type.

Parameters:

indices – The indices of the element to access.

Throws:

std::out_of_range – if indices are out of bounds (when error checking is enabled).

Returns:

A const reference to the element at the specified indices.

template<typename ...Indices>
auto operator()(Indices... indices) const -> const T&
requires (MemorySpace == memory_space::host)

Accesses an element using variadic indices.

Parameters:

indices – The indices of the element to access.

Returns:

A const reference to the element at the specified indices.

template<typename ...Indices>
auto operator()(Indices... indices) -> T&
requires (MemorySpace == memory_space::host)

Accesses an element using variadic indices.

Parameters:

indices – The indices of the element to access.

Returns:

A reference to the element at the specified indices.

auto operator[](const index_type &indices) const -> const T&
requires (MemorySpace == memory_space::host)

Accesses an element using index_type and operator[].

Parameters:

indices – The indices of the element to access.

Returns:

A const reference to the element at the specified indices.

auto operator[](const index_type &indices) -> T&
requires (MemorySpace == memory_space::host)

Accesses an element using index_type and operator[].

Parameters:

indices – The indices of the element to access.

Returns:

A reference to the element at the specified indices.

template<typename ...Indices>
auto operator[](Indices... indices) const -> const T&
requires (MemorySpace == memory_space::host)

Accesses an element using variadic indices and operator[].

Parameters:

indices – The indices of the element to access.

Returns:

A const reference to the element at the specified indices.

template<typename ...Indices>
auto operator[](Indices... indices) -> T&
requires (MemorySpace == memory_space::host)

Accesses an element using variadic indices and operator[].

Parameters:

indices – The indices of the element to access.

Returns:

A reference to the element at the specified indices.

inline auto copy() const -> auto
requires (MemorySpace == memory_space::host)

Create an owning copy of the tensor.

This method creates an owning copy of the tensor. If the tensor is already an owner, it will return a copy of itself. If the tensor is a reference, it will create a new tensor that owns its data. The resulting tensor will have the same shape and values as the original tensor, but will own its data, use the host memory space, and have column-major strides.

template<typename SubviewShape, typename StepSizes>
auto subview(const index_type &start_indices)

Creates a subview of the tensor with fixed shape.

Template Parameters:
  • SubviewShape – The shape of the subview.

  • StepSizes – The step sizes for each dimension.

Parameters:

start_indices – The starting indices for the subview.

Returns:

A tensor representing the subview.

template<typename SubviewShape, typename StepSizes>
auto subview(const index_type &start_indices) const

Creates a const subview of the tensor with fixed shape.

Template Parameters:
  • SubviewShape – The shape of the subview.

  • StepSizes – The step sizes for each dimension.

Parameters:

start_indices – The starting indices for the subview.

Returns:

A const tensor representing the subview.

template<std::size_t... Dims, typename ...Indices>
auto subview(Indices... start_indices)

Creates a subview of the tensor with fixed shape using variadic indices.

Template Parameters:
  • Dims – The dimensions of the subview.

  • Indices – The types of the indices.

Parameters:

start_indices – The starting indices for the subview.

Returns:

A tensor representing the subview.

template<std::size_t... Dims, typename ...Indices>
auto subview(Indices... start_indices) const

Creates a const subview of the tensor with fixed shape using variadic indices.

Template Parameters:
  • Dims – The dimensions of the subview.

  • Indices – The types of the indices.

Parameters:

start_indices – The starting indices for the subview.

Returns:

A const tensor representing the subview.

auto subview(const index_type &subview_shape, const index_type &start_indices)

Creates a subview of the tensor with dynamic shape.

Parameters:
  • subview_shape – The shape of the subview.

  • start_indices – The starting indices for the subview.

Throws:

std::invalid_argument – if the subview dimensions are invalid.

Returns:

A tensor representing the subview.

auto subview(const index_type &subview_shape, const index_type &start_indices) const

Creates a const subview of the tensor with dynamic shape.

Parameters:
  • subview_shape – The shape of the subview.

  • start_indices – The starting indices for the subview.

Throws:

std::invalid_argument – if the subview dimensions are invalid.

Returns:

A const tensor representing the subview.

auto subview(const index_type &subview_shape, const index_type &start_indices, const index_type &step_sizes)

Creates a subview of the tensor with dynamic shape and custom step sizes.

Parameters:
  • subview_shape – The shape of the subview.

  • start_indices – The starting indices for the subview.

  • step_sizes – The step sizes for each dimension.

Throws:

std::invalid_argument – if the subview dimensions are invalid.

Returns:

A tensor representing the subview.

auto subview(const index_type &subview_shape, const index_type &start_indices, const index_type &step_sizes) const

Creates a const subview of the tensor with dynamic shape and custom step sizes.

Parameters:
  • subview_shape – The shape of the subview.

  • start_indices – The starting indices for the subview.

  • step_sizes – The step sizes for each dimension.

Throws:

std::invalid_argument – if the subview dimensions are invalid.

Returns:

A const tensor representing the subview.

auto view()

Creates a view of the entire tensor.

Returns:

A tensor view of the entire tensor.

auto view() const

Creates a const view of the entire tensor.

Returns:

A const tensor view of the entire tensor.

auto diag_view()

Creates a diagonal view of the tensor.

Throws:

std::invalid_argument – if the tensor is not square (for dynamic shapes).

Returns:

A tensor view of the diagonal elements.

auto diag_view() const

Creates a const diagonal view of the tensor.

Throws:

std::invalid_argument – if the tensor is not square (for dynamic shapes).

Returns:

A const tensor view of the diagonal elements.

template<size_t... NewDims>
auto reshape()

Applies an index permutation to a std::index_sequence.

Template Parameters:
  • N – The number of elements in the index sequence.

  • IndexPermutation – The index permutation.

  • PadValue – The value to use for padding.

Returns:

The permuted index sequence.

template<size_t... NewDims>
auto reshape() const

Reshapes the tensor to a new shape.

Template Parameters:

NewDims – The new dimensions of the tensor.

Returns:

A new tensor with the new shape.

template<typename NewShape>
auto reshape()
template<typename NewShape>
auto reshape() const
auto flatten()

Flattens the tensor into a 1D tensor.

Returns:

A new tensor with the flattened shape.

auto flatten() const

Flattens the tensor into a 1D tensor.

Returns:

A new tensor with the flattened shape.

auto reshape(std::vector<size_t> new_shape, layout l = layout::column_major)

Reshapes the tensor to a new shape.

Parameters:
  • new_shape – The new shape of the tensor.

  • l – The layout of the tensor.

Returns:

A new tensor with the new shape.

auto reshape(std::vector<size_t> new_shape, layout l = layout::column_major) const

Reshapes the tensor to a new shape.

Parameters:
  • new_shape – The new shape of the tensor.

  • l – The layout of the tensor.

Returns:

A new tensor with the new shape.

auto set_shape(const std::vector<size_t> &new_shape, layout l = layout::column_major)

Sets the shape of the tensor to a new shape. The tensor is modified in place.

Parameters:
  • new_shape – The new shape of the tensor.

  • l – The layout of the tensor.

template<valid_index_permutation IndexPermutation>
auto permute()

Applies an index permutation to a tensor.

Template Parameters:

IndexPermutation – The index permutation.

Returns:

A new tensor with the permuted shape and strides.

template<valid_index_permutation IndexPermutation>
auto permute() const

Applies an index permutation to a tensor.

Template Parameters:

IndexPermutation – The index permutation.

Returns:

A new tensor with the permuted shape and strides.

template<std::size_t... Permutation>
inline auto permute()
template<std::size_t... Permutation>
inline auto permute() const
auto permute(const std::vector<std::size_t> &index_permutation)

Applies an index permutation to a tensor.

Parameters:

index_permutation – The index permutation.

Returns:

A new tensor with the permuted shape and strides.

auto permute(const std::vector<std::size_t> &index_permutation) const

Applies an index permutation to a tensor.

Parameters:

index_permutation – The index permutation.

Returns:

A new tensor with the permuted shape and strides.

auto transpose()

Transposes a 1D or 2D tensor.

Returns:

A new tensor with the transposed shape.

auto transpose() const

Transposes a 1D or 2D tensor.

Returns:

A new tensor with the transposed shape.

auto rows()

Returns an iterator range over the rows of the tensor.

Returns:

An iterator range of row subviews.

auto rows() const

Returns a const iterator range over the rows of the tensor.

Returns:

A const iterator range of row subviews.

auto cols()

Returns an iterator range over the columns of the tensor.

Returns:

An iterator range of column subviews.

auto cols() const

Returns a const iterator range over the columns of the tensor.

Returns:

A const iterator range of column subviews.

auto row(size_t index)

Returns a view of a single row of the tensor.

Parameters:

index – The index of the row to access.

Throws:

std::out_of_range – if the index is out of bounds (when error checking is enabled).

Returns:

A tensor view of the specified row.

auto row(size_t index) const

Returns a const view of a single row of the tensor.

Parameters:

index – The index of the row to access.

Throws:

std::out_of_range – if the index is out of bounds (when error checking is enabled).

Returns:

A const tensor view of the specified row.

auto col(size_t index)

Returns a view of a single column of the tensor.

Parameters:

index – The index of the column to access.

Throws:

std::out_of_range – if the index is out of bounds (when error checking is enabled).

Returns:

A tensor view of the specified column.

auto col(size_t index) const

Returns a const view of a single column of the tensor.

Parameters:

index – The index of the column to access.

Throws:

std::out_of_range – if the index is out of bounds (when error checking is enabled).

Returns:

A const tensor view of the specified column.

auto begin() -> flat_iterator<tensor>
requires (MemorySpace == memory_space::host)

Returns a flat iterator to the beginning of the tensor.

The iterator will iterate over the tensor in column-major order regarless of memory layout.

Returns:

An iterator to the beginning of the tensor.

auto end() -> flat_iterator<tensor>
requires (MemorySpace == memory_space::host)

Returns a flat iterator to the end of the tensor.

The iterator will iterate over the tensor in column-major order regarless of memory layout.

Returns:

An iterator to the end of the tensor.

auto begin() const -> flat_iterator<const tensor>
requires (MemorySpace == memory_space::host)

Returns a const flat iterator to the beginning of the tensor.

The iterator will iterate over the tensor in column-major order regarless of memory layout.

Returns:

A const iterator to the beginning of the tensor.

auto end() const -> flat_iterator<const tensor>
requires (MemorySpace == memory_space::host)

Returns a const flat iterator to the end of the tensor.

The iterator will iterate over the tensor in column-major order regarless of memory layout.

Returns:

A const iterator to the end of the tensor.

auto cbegin() const -> flat_iterator<const tensor>
requires (MemorySpace == memory_space::host)

Returns a const flat iterator to the beginning of the tensor.

The iterator will iterate over the tensor in column-major order regarless of memory layout.

Returns:

A const iterator to the beginning of the tensor.

auto cend() const -> flat_iterator<const tensor>
requires (MemorySpace == memory_space::host)

Returns a const flat iterator to the end of the tensor.

The iterator will iterate over the tensor in column-major order regarless of memory layout.

Returns:

A const iterator to the end of the tensor.

template<fixed_shape SubviewShape>
auto subviews() -> iterator_range<subview_iterator<tensor, SubviewShape>>
requires (fixed_shape<Shape> && MemorySpace == memory_space::host)

Returns a iterator of sub tensors at the beginning of the tensor.

Returns a const iterator of sub tensors at the beginning of the tensor.

The iterator will iterate over the subviews in column-major order regarless of memory layout.

The iterator will iterate over the subviews in column-major order regarless of memory layout.

Returns:

An iterator to the beginning of the subviews.

Returns:

A const iterator to the beginning of the subviews.

template<std::size_t... Dims>
auto subviews() -> iterator_range<subview_iterator<tensor, std::index_sequence<Dims...>>>
requires (fixed_shape<Shape> && MemorySpace == memory_space::host)
template<fixed_shape SubviewShape>
auto subviews() const -> iterator_range<subview_iterator<const tensor, SubviewShape>>
requires (fixed_shape<Shape> && MemorySpace == memory_space::host)

Returns a const iterator of sub tensors at the beginning of the tensor.

The iterator will iterate over the subviews in column-major order regarless of memory layout.

Returns:

A const iterator to the beginning of the subviews.

template<std::size_t... Dims>
auto subviews() const -> iterator_range<subview_iterator<const tensor, std::index_sequence<Dims...>>>
requires (fixed_shape<Shape> && MemorySpace == memory_space::host)
auto subviews(const std::vector<std::size_t> &subview_shape) -> iterator_range<subview_iterator<tensor, std::vector<std::size_t>>>
requires (dynamic_shape<Shape> && MemorySpace == memory_space::host)

Returns an iterator range over the subviews of the tensor.

Parameters:

subview_shape – The shape of the subviews.

Throws:

std::invalid_argument – if the subview dimensions are greater than the tensor rank or do not evenly divide the tensor dimensions (when error checking is enabled).

Returns:

An iterator range of subviews.

auto subviews(const std::vector<std::size_t> &subview_shape) const -> iterator_range<subview_iterator<const tensor, std::vector<std::size_t>>>
requires (dynamic_shape<Shape> && MemorySpace == memory_space::host)

Returns a const iterator range over the subviews of the tensor.

Parameters:

subview_shape – The shape of the subviews.

Throws:

std::invalid_argument – if the subview dimensions are greater than the tensor rank or do not evenly divide the tensor dimensions (when error checking is enabled).

Returns:

A const iterator range of subviews.

template<typename U, typename OtherShape, typename OtherStrides, enum error_checking OtherErrorChecking, enum ownership_type OtherOwnershipType>
auto operator+=(const tensor<U, OtherShape, OtherStrides, OtherErrorChecking, OtherOwnershipType, MemorySpace> &other) -> tensor&

Element-wise addition assignment operator.

Parameters:

other – The tensor to add to this tensor.

Returns:

Reference to the modified tensor.

template<typename U, typename OtherShape, typename OtherStrides, enum error_checking OtherErrorChecking, enum ownership_type OtherOwnershipType>
auto operator-=(const tensor<U, OtherShape, OtherStrides, OtherErrorChecking, OtherOwnershipType, MemorySpace> &other) -> tensor&

Element-wise subtraction assignment operator.

Parameters:

other – The tensor to subtract from this tensor.

Returns:

Reference to the modified tensor.

template<typename U, typename OtherShape, typename OtherStrides, enum error_checking OtherErrorChecking, enum ownership_type OtherOwnershipType>
auto operator==(const tensor<U, OtherShape, OtherStrides, OtherErrorChecking, OtherOwnershipType, MemorySpace> &other) const -> tensor<std::uint8_t, Shape, Strides, ErrorChecking, ownership_type::owner, MemorySpace>

Element-wise equality comparison operator.

Parameters:

other – The tensor to compare with this tensor.

Returns:

True if all elements are equal, false otherwise.

template<typename U, typename OtherShape, typename OtherStrides, enum error_checking OtherErrorChecking, enum ownership_type OtherOwnershipType>
auto operator!=(const tensor<U, OtherShape, OtherStrides, OtherErrorChecking, OtherOwnershipType, MemorySpace> &other) const -> tensor<std::uint8_t, Shape, Strides, ErrorChecking, ownership_type::owner, MemorySpace>

Element-wise inequality comparison operator.

Parameters:

other – The tensor to compare with this tensor.

Returns:

True if any elements are not equal, false otherwise.

auto operator-() const -> tensor

Unary negation operator.

Returns:

A new tensor with all elements negated.

template<dimensionless_scalar U>
auto operator*=(const U &s) -> tensor&

Scalar multiplication assignment operator.

Parameters:

s – The scalar to multiply the tensor by.

Returns:

Reference to the modified tensor.

template<dimensionless_scalar U>
auto operator/=(const U &s) -> tensor&

Scalar division assignment operator.

Parameters:

s – The scalar to divide the tensor by.

Returns:

Reference to the modified tensor.

inline auto is_contiguous() const -> bool
inline auto values() -> tensor<blas_type_t<T>, Shape, Strides, ErrorChecking, ownership_type::reference, MemorySpace>
inline auto values() const -> tensor<const blas_type_t<T>, Shape, Strides, ErrorChecking, ownership_type::reference, MemorySpace>
template<quantitative Q>
inline auto as() -> tensor<Q, Shape, Strides, ErrorChecking, ownership_type::reference, MemorySpace>

Public Static Functions

static inline constexpr auto error_checking() -> error_checking
static inline constexpr auto ownership() -> ownership_type
static inline constexpr auto get_memory_space() -> memory_space
static auto zeros(const std::vector<size_t> &shape = {}, layout l = layout::column_major)

Creates a tensor filled with zeros.

Parameters:
  • shape – The shape of the tensor (for dynamic shape tensors).

  • l – The layout of the tensor (for dynamic shape tensors).

Returns:

A tensor filled with zeros.

static auto ones(const std::vector<size_t> &shape = {}, layout l = layout::column_major)

Creates a tensor filled with ones.

Parameters:
  • shape – The shape of the tensor (for dynamic shape tensors).

  • l – The layout of the tensor (for dynamic shape tensors).

Returns:

A tensor filled with ones.

static auto full(const T &value, const std::vector<size_t> &shape = {}, layout l = layout::column_major)

Creates a tensor filled with a specific value.

Parameters:
  • value – The value to fill the tensor with.

  • shape – The shape of the tensor (for dynamic shape tensors).

  • l – The layout of the tensor (for dynamic shape tensors).

Returns:

A tensor filled with the specified value.

static auto random(T min, T max, const std::vector<size_t> &shape = {}, layout l = layout::column_major)

Creates a tensor filled with random values.

Parameters:
  • min – The minimum value for the random distribution.

  • max – The maximum value for the random distribution.

  • shape – The shape of the tensor (for dynamic shape tensors).

  • l – The layout of the tensor (for dynamic shape tensors).

Returns:

A tensor filled with random values.

static auto eye(const std::vector<size_t> &shape = {}, layout l = layout::column_major)

Creates an identity tensor (2D square tensor with ones on the main diagonal).

Parameters:
  • shape – The shape of the tensor (for dynamic shape tensors).

  • l – The layout of the tensor (for dynamic shape tensors).

Throws:

std::invalid_argument – if the tensor is not square (when error checking is enabled).

Returns:

An identity tensor.

static auto diag(const T &value, const std::vector<size_t> &shape = {}, layout l = layout::column_major)

Creates a diagonal tensor with a specific value on the main diagonal.

Parameters:
  • value – The value to put on the main diagonal.

  • shape – The shape of the tensor (for dynamic shape tensors).

  • l – The layout of the tensor (for dynamic shape tensors).

Throws:

std::invalid_argument – if the tensor is not square (when error checking is enabled).

Returns:

A diagonal tensor.

static auto arange(T start, T step = T(1), const std::vector<size_t> &shape = {}, layout l = layout::column_major)

Creates a tensor with evenly spaced values.

Parameters:
  • start – The starting value.

  • step – The step between values.

  • shape – The shape of the tensor (for dynamic shape tensors).

  • l – The layout of the tensor (for dynamic shape tensors).

Returns:

A tensor with evenly spaced values.

Private Types

using shape_storage = std::conditional_t<fixed_shape<Shape>, std::integral_constant<std::monostate, std::monostate{}>, Shape>

Type alias for shape storage, using std::integral_constant for fixed shapes.

using device_shape_storage = std::conditional_t<MemorySpace == memory_space::device, std::size_t*, std::integral_constant<std::monostate, std::monostate{}>>
using strides_storage = std::conditional_t<fixed_shape<Strides>, std::integral_constant<std::monostate, std::monostate{}>, Strides>

Type alias for strides storage, using std::integral_constant for fixed strides.

using device_strides_storage = std::conditional_t<MemorySpace == memory_space::device, std::size_t*, std::integral_constant<std::monostate, std::monostate{}>>
using data_storage = std::conditional_t<OwnershipType == ownership_type::owner, std::conditional_t<fixed_shape<Shape>, std::array<T, _size()>, std::vector<T>>, T*>

Type alias for data storage, using std::array for fixed shapes and std::vector for dynamic shapes.

Private Functions

template<std::size_t... Is>
constexpr auto compute_offset_impl(const index_type &indices, std::index_sequence<Is...>) const -> std::size_t

Computes the offset for fixed shape tensors.

Parameters:

indices – The indices to compute the offset for.

Returns:

The computed offset.

constexpr auto compute_offset(const index_type &indices) const -> std::size_t

Computes the offset for both fixed and dynamic shape tensors.

Parameters:

indices – The indices to compute the offset for.

Returns:

The computed offset.

constexpr auto check_bounds(const index_type &indices) const -> void

Checks if the given indices are within bounds.

Parameters:

indices – The indices to check.

Throws:

std::out_of_range – if indices are invalid or out of bounds.

inline auto compute_strides(layout l) const -> std::vector<std::size_t>

Private Members

NO_UNIQUE_ADDRESS shape_storage shape_

Storage for tensor shape.

NO_UNIQUE_ADDRESS strides_storage strides_

Storage for tensor strides.

NO_UNIQUE_ADDRESS device_shape_storage device_shape_
NO_UNIQUE_ADDRESS device_strides_storage device_strides_
data_storage data_

Private Static Functions

static inline constexpr auto _size() -> std::size_t
static inline constexpr auto _rank() -> std::size_t
static inline auto compute_strides(layout l, const std::vector<std::size_t> &shape)