Skip to content

Cheatsheet

Import

Recommended import statements
import funfact as ff
from funfact import active_backend as ab  # use it like numpy!

Choose backend

Syntax Description
ff.use('jax') Use JAX as backend
ff.use('jax', enable_x64=True) JAX with 64-bit floating points as default
ff.use('torch') Use PyTorch as backend
ff.use('torch', device='cuda') Use PyTorch on CUDA devices
ff.use('numpy') Use NumPy as backend, forward calculations only

Declare abstract indices

Syntax Description
ff.index() Create an anonymous index
ff.index('i') Create an index named \(i\)
ff.index('j_1') Create an index named \(j_1\)
ff.indices('i j k') Creates a tuple of 3 indices named \(i\), \(j\), and \(k\)
ff.indices('i, j, k') Same as above
ff.indices(5) Create a tuple of 5 anonymous indices

Declare abstract tensors

Syntax Description
ff.tensor('T', 2, 3, 4) A \(2 \times 3 \times 4\) random tensor \(T\) with normally initialized values
ff.tensor('T', np.array([[1, 2], [3, 4]])) A concrete matrix \(T = \begin{bmatrix}1&2\\3&4\end{bmatrix}\)
ff.tensor(2, 3, 4) A \(2 \times 3 \times 4\) nameless random tensor with normally initialized values
ff.tensor(np.array([[1, 2], [3, 4]])) A concrete nameless matrix \(\begin{bmatrix}1&2\\3&4\end{bmatrix}\)
Optimizability
ff.tensor('T', 2, 3, 4) Pure abstract tensors are optimizable by default
ff.tensor('T', 2, 3, 4, optimizable=False) No optimization after random initialization
ff.tensor('T', np.random.randn(2, 3, 4)) Concrete data are not optimizable by default
ff.tensor('T', np.random.randn(2, 3, 4), optimizable=True) Force optimizable to be on
Initializers
ff.tensor('T', 2, 3, 4, initializer=ff.initializers.Zeros) Initialize all elements as 0
ff.tensor('T', 2, 3, 4, initializer=ff.initializers.Ones) Initialize all elements as 1
ff.tensor('T', 4, 5, initializer=ff.initializers.Eye) Initialize as the identity matrix (2-way tensors only)
ff.tensor('T', 2, 3, 4, initializer=ff.initializers.Normal) Initialize all elements as i.i.d. samples from the normal distribution
ff.tensor('T', 2, 3, 4, initializer=ff.initializers.Uniform) Initialize all elements as i.i.d. samples from the uniform distribution
Conditions
ff.tensor('T', 2, 3, 4, prefer=ff.conditions.Unitary) Penalize the tensor if not orthonormal/unitary
ff.tensor('T', 2, 3, 4, prefer=ff.conditions.UpperTriangular) Penalize lower triangular elements from being nonzero
ff.tensor('T', 2, 3, 4, prefer=ff.conditions.NonNegative) Penalize tensor elements for being negative
Special Tensors
ff.zeros(2, 3, 4) Shortcut for ff.tensor(2, 3, 4, initializer=ff.initializers.Zeros)
ff.ones(2, 3, 4) Shortcut for ff.tensor(2, 3, 4, initializer=ff.initializers.Ones)
ff.eye(2, 3) Shortcut for ff.tensor(2, 3, initializer=ff.initializers.Eye)

Arithmetics

Syntax Description
a[i] + b[j] \(\boldsymbol{\lambda}_{ij} = \boldsymbol{a}_{i} + \boldsymbol{b}_{j}\), pairwise addition between two vectors
a[i] - b[j] \(\boldsymbol{\lambda}_{ij} = \boldsymbol{a}_{i} - \boldsymbol{b}_{j}\), pairwise subtraction between two vectors
a[i] * b[j] \(\boldsymbol{a} \boldsymbol{b}^\mathsf{T}\), pairwise multiplication, i.e. outer product between two vectors
a[i] / b[j] \(\boldsymbol{\lambda}_{ij} = \boldsymbol{a}_{i} / \boldsymbol{b}_{j}\), pairwise division between two vectors
a[i] * b[i] \(\boldsymbol{a} \cdot \boldsymbol{b}\), inner product between two vectors
A[i, j] * B[j, k] \(A \cdot B\), inner product between two matrices
A[i, j] * B[k, j] \(A \cdot B^\mathsf{T}\), inner product with transposition
a[i, j, k] * b[r, k, s] Contraction between the 3rd dimension of \(a\) and the 2nd dimension of \(b\)
Contraction suppression
A[i, ~j] * B[~j, k] \(\boldsymbol{\lambda}_{ijk} = \boldsymbol{A}_{ij} \boldsymbol{B}_{jk}\), no contraction along \(j\)
A[i, ~j] * B[ j, k] same as above
A[i, j] * B[ ~j, k] same as above
Output order
A[i, j, k] >> [k, i, j] Transposition/axis permutation
A[i, j] * B[j, k] >> [k, i] \((A B)^\mathsf{T}\), reorder output axes
Kronecker product
a[[*i]] * b[[*i]] \(\boldsymbol{\lambda}_{i \times n'+i'} = \boldsymbol{a}_{i} \boldsymbol{b}_{i'}\), Kronecker product between vectors
a[[i, *j]] * b[[*j, k]] \(\boldsymbol{\lambda}_{i, j \times n'+j', k} = \boldsymbol{a}_{ij} \boldsymbol{b}_{j'k}\), Kronecker product within the \(j\) axis
Indexless
a+b, a-b, a*b, a/b, a**b elementwise addition, subtraction, multiplication, division, exponentiation
a @ b matrix multiplication
a & b Kronecker product

Math functions

Syntax Description
ff.sin(a) \(\sin \boldsymbol{a}\)
ff.sin(a[i, j]) Equivalent to ff.sin(a)[i, j]

Factorization objects

context
T = ff.tensor('T', n1, n2, n3)
U_1 = ff.tensor('U_1', n1, m1, optimizable=False)
U_2 = ff.tensor('U_2', n2, m2)
U_3 = ff.tensor('U_3', n3 ,m3)
i, j, k, l, m, n = ff.indices('i, j, k, p, q, r')
tsrex = T[i, j, k] * U_1[i, p] * U_2[j, q] * U_3[k, r]
target = ab.normal(0.0, 1.0, (m1, m2, m3))
Syntax Description
fac = ff.Factorization.from_tsrex(tsrex) Initialize a factorization model without optimization
fac = ff.factorize(tsrex, target, **kwargs) Factorize target using tsrex
fac() Obtain the approximate tensor from a factorization model
fac[2, 4, 5] Access a single element at [2, 4, 5] from the approximation
fac[2, :] Access the slice at [2, :] from the approximation
fac['U_1'] Read-only access of factor \(U_1\)
fac.factors A list of all optimizable factors, i.e. \(T\), \(U_2\), and \(U_3\)
fac.all_factors A list of all factors, i.e. \(T\), \(U_1\), \(U_2\), and \(U_3\)
Back to top