Résumé

Linear Algebra


Linear Algebra

This module implements tensors and the core linear algebra operations used throughout SicLib.

Implementation Notes

Tensor operations are not optimized. Use an established library such as PyTorch for production workloads.


Theoretical Motivation

Given the standard ring (R,+,)(\R, +, *), we can represent its operations operations as a composition of binary operators f(x,y)=xyf(x, y) = x * y or f(x,y)=x+yf(x, y) = x + y where x,yRx, y \in R. Given a vector space of Rn\R^n we can represent a vector as x={(x0,...,xn):xiR}\textbf{x} = \{(x_0, ..., x_n): x_i \in \R\}, where f(x,y)f(\textbf{x}, \textbf{y}) is some combination of f(xi,yj)f(x_i, y_j). Given a collection of pp vectors of size nn, we define a matrix X=(x1,...,xp)Rn×p\textbf{X} = (\textbf{x}_1, ..., \textbf{x}_p) \in \R^{n \times p} . We describe a tensor space T\mathfrak{T} of order mm on R\R as

TRm=i=1mRk,kN+\Large \mathfrak{T_\R^m} =\normalsize\prod_{i=1}^m \R^k,\enspace k \in \N^+

Given the usual ring (R,+,)(\R, +, *), we can extend many results from linear algebra by allowing the following rule.

Given the tensors T1=(X1,...,Xk)\textbf{T}_1 = (\textbf{X}_1, ..., \textbf{X}_k), T2=(Y1,...,Yp)\textbf{T}_2 = (\textbf{Y}_1, ..., \textbf{Y}_p), and T3=(Z1,...,Zq)\textbf{T}_3 = (\textbf{Z}_1, ..., \textbf{Z}_q) a necessary (but not sufficient) condition for the operation f(T1,T2)=T3f(\textbf{T}_1, \textbf{T}_2) = \textbf{T}_3 to be well defined is 0<imax(p,k),dim(Xi)=dim(Yi)0 < i \leq max(p, k), \enspace dim(X_i) = dim(Y_i), dim(Xi)=1dim(X_i) = 1, or dim(Yi)=1dim(Y_i) = 1 and dim(Zi)=max(p,k)dim(Z_i) = max(p, k). Without loss of generality, dim(Xi)=1dim(X_i) = 1 if k<pk < p.


Documentation

# pysiclib.linalg.Tensor class Tensor: @overload def __init__(self, numpy_array: numpy.ndarray[numpy.float64]) -> None: ... @overload def __init__(self, input_data: List[float], input_shape: List[int] = ..., input_stride: List[int] = ..., offset: int = ...) -> None: ... @overload def __init__(self, other_view: Tensor) -> None: ... def binary_element_wise_op(self, arg0: Tensor, arg1: Callable[[float,float],float]) -> Tensor: ... def deep_copy(self) -> Tensor: ... def fold_op(self, arg0: Callable[[float,float],float], arg1: float, arg2: int, arg3: bool) -> Tensor: ... def get_buffer(self) -> List[float]: ... def get_offset(self) -> int: ... def get_shape(self) -> List[int]: ... def get_stride(self) -> List[int]: ... def matmul(self, arg0: Tensor) -> Tensor: ... def slice_view(self, arg0: List[int]) -> Tensor: ... def squeeze(self, target_dim: int = ...) -> Tensor: ... def to_numpy(self) -> numpy.ndarray[numpy.float64]: ... def transpose(self, dim_1: int = ..., dim_2: int = ...) -> Tensor: ... def unitary_op(self, arg0: Callable[[float],float]) -> Tensor: ... def unsqueeze(self, arg0: int) -> Tensor: ...