Linear Algebra Functions#

These are the linear algebra functions that have been made available to Python.

class einsums.core.Norm#

Enumeration of different types of matrix norms.

MAXABS = 'M'#

Finds the largest absolute value of the elements in a matrix.

ONE = '1'#

Finds the one-norm of a matrix. This is equivalent to finding the maximum column sum of the matrix.

INFINITY = 'I'#

Finds the infinity-norm of a matrix. This is equivalent to finding the maximum row sum of the matrix.

FROBENIUS = 'F'#

Finds the Frobenius norm of a matrix. This is the square root of the sum of the squares of the elements. Similar to the vector norm, but applied to matrices.

class einsums.core.Vectors#

Enumerations of different operations for einsums.core.svd_dd.

ALL = 'A'#

Gets all of the vectors from the singular value decomposition.

SOME = 'S'#

Only some of the vectors are returned. The number of vectors is the minimum of the dimensions of the input matrix.

OVERWRITE = 'O'#

Overwrite some of the singular vectors into the input matrix. See the LAPACK documentation for gesdd for more details.

NONE = 'N'#

Do not compute the vectors for the singular value decomposition.

einsums.core.sum_square(A) float, float#

Computes the sum of the squares of the values in a vector without overflow. To use the return from this function, use the following.

>>> A = ein.core.create_random_tensor("A", dims, dtype)
>>> sum_sq, scale = ein.core.sum_square(A)
>>> actual = sum_sq * scale ** 2
Parameters:

A – The vector to analyze.

Returns:

The square of the sum of the vector and the scale factor to apply to it to avoid overflow.

Raises:
  • einsums.core.rank_error – if the tensor passed in is not rank-1.

  • ValueError – if the data stored by the vector is not real or complex floating point.

einsums.core.gemm(transA: str, transB: str, alpha, A, B, beta, C)#

Performs a matrix multiplication.

\[\mathbf{C} := \beta \mathbf{C} + \alpha \mathbf{A B}\]
Parameters:
  • transA – Whether to transpose the A matrix. 'T' transposes, 'N' does not.

  • transB – Whether to transpose the B matrix. 'T' transposes, 'N' does not.

  • alpha – The scale factor for the matrix product.

  • A – The left matrix.

  • B – The right matrix.

  • beta – The scale factor on the accumulation matrix. If zero, then the output matrix will not be

mixed into the matrix product. :param C: The output matrix. :raises einsums.core.rank_error: if any of the tensors is not rank-2. :raises einsums.core.tensor_compat_error: if the rows and columns of the matrices are incompatible. :raises ValueError: if the storage types of the matrices are not compatible.

einsums.core.gemv(transA: str, alpha, A, X, beta, Y)#

Performs a matrix-vector multiplication.

\[\mathbf{Y} := \beta \mathbf{Y} + \alpha \mathbf{A X}\]
Parameters:
  • transA – Whether to transpose the A matrix. 'T' transposes, 'N' does not.

  • alpha – The scale factor for the matrix product.

  • A – The matrix.

  • X – The input vector.

  • beta – The scale factor on the accumulation vector. If zero, then the output vector will not be

mixed into the matrix-vector product. :param X: The output vector. :raises einsums.core.rank_error: if the X or Y tensors are not rank-1 or the A matrix is not rank-2. :raises einsums.core.tensor_compat_error: if the rows and columns of the matrix are incompatible with the vectors. :raises ValueError: if the storage types of the matrices are not compatible.

einsums.core.syev(A, W)#
einsums.core.heev(A, W)#

Perform the eigendecomposition of a real symmetric or complex hermitian matrix. That is, solve the following.

\[\mathbf{Av} = \mathbf{v}\lambda\]
Parameters:
  • A – The input matrix. At exit, it will be overwritten by the eigenvectors.

  • W – The output vector for the eigenvalues. This must hold only real values, since

the eigenvalues of symmetric/hermitian matrices are always real. :raises einsums.core.rank_error: if A is not a matrix or W is not a vector. :raises ValueError: if the storage types of A and W are incompatible or one of the arguments passed to the underlying library call had an illegal value. This second case should hopefully never happen. :raisees RuntimeError: if the algorithm does not converge, or the memory for internal buffers could not be allocated.

einsums.core.geev(jobvl: str, jobvr: str, A, W, Vl, Vr)#

Perform the eigendecomposition of a general matrix. The left and right eigenvectors are able to be computed. That is, solve the following to get the left eigenvectors.

\[\mathbf{uA} = \mathbf{u}\lambda\]

And for the right eigenvectors, the following.

\[\mathbf{Av} = \mathbf{v}\lambda\]
Parameters:

jobvl – Whether to compute the left eigenvectors. Pass 'V' to compute them, 'N' to not.

If the vectors are computed, then a tensor needs to be passed to Vl. :param jobvr: Whether to compute the right eigenvectors. Pass 'V' to compute them, 'N' to not. If the vectors are computed, then a tensor needs to be passed to Vr. :param A: The matrix to decompose. :param W: The output for the eigenvalues. This needs to be complex. :param Vl: The output for the left eigenvectors. If jobvl = 'N', then this is not referenced and can be set to None. :param Vr: The output for the right eigenvectors. If jobvr = 'N', then this is not referenced and can be set to None. :raises einsums.core.rank_error: if the input matrix or any of the referenced output matrices are not rank-2, or the W vector is not rank-1. :raises einsums.core.tensor_compat_error: if A is not a square matrix or any of the outputs don’t have the proper dimensions. :raises TypeError: if a set of eigenvectors is requested, but the output tensor is None. :raises ValueError: if the storage types of any of the tensors is incompatible.

einsums.core.gesv(A, B)#

Solve a linear system like the following.

\[\mathbf{Ax} = \mathbf{B}\]
Parameters:
  • A – The coefficient matrix. Needs to be square.

  • B – The result matrix. It can have multiple columns representing different linear systems with

the same coefficients. It will be overwritten by the values of x in the equation above. :raises einsums.core.rank_error: if A is not rank-2 or B is not rank-1 or rank-2. :raises einsums.core.dimension_error: if A is not square. :raises einsums.core.tensor_compat_error: if the number of rows in B does not match the number of rows in A. :raises ValueError: if the storage types of A and B are invalid or an invalid value was passed to the underlying library function. This second case should not happen. :raises RuntimeError: if the input matrix is singular, meaning no solutions could be found.

einsums.core.scale(alpha, A)#

Scale a tensor by a scale factor.

Parameters:
  • alpha – The scale factor.

  • A – The tensor to scale.

Raises:

ValueError – if A does not store real or complex floating point data.

einsums.core.scale_row(row: int, alpha, A)#

Scales a row of a matrix by a scale factor.

Parameters:

row – Which row to scale. If row is negative, it will be treated from the end of the matrix.

For instance, row = -1 will scale the last row. :param alpha: The scale factor. :param A: The matrix to scale. :raises einsums.core.rank_error: if A is not a matrix. :raises IndexError: if the requested row is outside of the range of the matrix. :raises ValueError: if the matrix does not store real or complex floating point data.

einsums.core.scale_column(col: int, alpha, A)#

Scales a column of a matrix by a scale factor.

Parameters:

col – Which column to scale. If col is negative, it will be treated from the end of the matrix.

For instance, col = -1 will scale the last column. :param alpha: The scale factor. :param A: The matrix to scale. :raises einsums.core.rank_error: if A is not a matrix. :raises IndexError: if the requested column is outside of the range of the matrix. :raises ValueError: if the matrix does not store real or complex floating point data.

einsums.core.dot(A, B)#

Performs the unconjugated dot product. For real arguments, this is the dot product. For complex arguments, it is not. This is equivalent to the following formula. The reason this is still called dot is because of how useful this function is, even if the result isn’t what mathematicians would call the dot product.

\[out = \sum_i A_i B_i\]

One thing to note is that if the same tensor is passed for both A and B, then this will not return the norm-squared for complex arguments. It will for real arguments simply because real arguments don’t feel the effects of conjugation. This function is used when you want to take two tensors, multiply them element-wise, and sum the result. If you need the geometric dot product, consider using true_dot instead. This is not an inner product for complex arguments, since it does not follow conjugate symmetry or positive-definiteness.

Parameters:
  • A – One input tensor.

  • B – The other input tensor.

Returns:

The unconjugated dot product.

Raises:

not real or complex floating point.

einsums.core.true_dot(A, B)#

Performs the possibly conjugated dot product. This is the true dot product. That is, if the same tensor is passed to both arguments, the norm-squared will be returned. This is equivalent to the following formula.

\[out = \sum_i A_i^* B_i\]

For real arguments, this is equivalent to dot. The difference lies in the complex behavior. This is a true inner product for complex arguments.

Parameters:

A – One input tensor. The values of this tensor will be conjugated before being used.

This is done after accessing the elements, so there will be no change to this tensor. :param B: The other input tensor. :return: The true dot product. :raises einsums.core.rank_error: if the input tensors do not have the same rank. :raises einsums.core.dimension_error: if the input tensors do not have the same dimensions. :raises ValueError: if the tensors do not store the same data type or the stored data type is not real or complex floating point.

einsums.core.axpy(alpha, x, y)#

Performs a scale and add operation. It is similar to axpby where the beta argument is set to 1. In mathematical notation, this performs the following.

\[\mathbf{y} := \mathbf{y} + \alpha \mathbf{x}\]
Parameters:
  • alpha – The scale factor for the input tensor.

  • x – The input tensor.

  • y – The output tensor. Its value is used as an input as well.

Raises:
  • einsums.core.rank_error – if the tensors do not have the same rank.

  • ValueError – if the tensors do not have the same storage type or the tensors

do not store real or complex floating point data. :raises einsums.core.tensor_compat_error: if the tensors do not have the same dimensions.

einsums.core.axpby(alpha, x, beta, y)#

Performs a scale and add operation. It is similar to axpy, but the y tensor is also scaled before being accumulated. In mathematical notation, this performs the following.

\[\mathbf{y} := \beta \mathbf{y} + \alpha \mathbf{x}\]
Parameters:
  • alpha – The scale factor for the input tensor.

  • x – The input tensor.

  • beta – The scale factor for the output tensor on input.

  • y – The output tensor. Its value is used as an input as well.

Raises:
  • einsums.core.rank_error – if the tensors do not have the same rank.

  • ValueError – if the tensors do not have the same storage type or the tensors

do not store real or complex floating point data. :raises einsums.core.tensor_compat_error: if the tensors do not have the same dimensions.

einsums.core.ger(alpha, x, y, A)#

Performs an outer product update. This is essentially equivalent to the following.

\[\mathbf{A} := \mathbf{A} + \alpha \mathbf{x} \mathbf{y}^T\]

Or, in index notation, the following.

\[A_{ij} := A_{ij} + \alpha x_i y_j\]
Parameters:
  • alpha – The scale factor for the outer product.

  • x – The left input vector.

  • y – The right input vector.

  • A – The output matrix.

Raises:

is not real or complex floating point data.

einsums.core.getrf(A) list[int]#

Performs LU decomposition. Essentially performs the following.

\[A = PLU\]

In the equation above, P is the pivot matrix, which is represented by the pivot argument, L is a lower triangular matrix with 1 in all diagonal entries, and U is an upper triangular matrix. On exit, the upper triangle of A will contain U and the lower triangle of A will contain L. The diagonal entries of L are not stored since they are all 1. The diagonal entries of A will be the diagonal entries of U. The pivot vector will contain a list of the pivots that took place. A pivot vector that looks like [3, 4, 4, 4] means that first, the first row was swapped with the third row, then the second with the fourth, then the third with the fourth, and the fourth row was not moved. Since this ultimately calls Fortran, these pivot values are 1-indexed, the 3 in the list would actually refer to A[2, :]. To extract the data from this, use extract_plu.

This function will give a warning if the matrix is singular.

Parameters:

A – The matrix to decompose.

Returns:

The pivot list. Pass this into extract_plu to get the matrix factors.

Raises:
  • einsums.core.rank_error – if the tensor is not rank-2.

  • ValueError – if the tensor does not store real or complex floating point data or if an invalid

argument is passed to the internal getrf call. This last case should not happen.

einsums.core.extract_plu(A, pivot: list[int]) tuple#

Extracts the matrices from a call to getrf.

Parameters:
  • A – The matrix to process after a call to getrf.

  • pivot – The return value from getrf.

Returns:

Gives the pivot matrix, the lower triangular factor, and the upper triangular factor

in that order. :raises einsums.core.rank_error: if the input tensor is not a matrix. :raises RuntimeError: if the pivot list is not formatted correctly. :raises ValueError: if the matrix does not store real or complex floating point data.

einsums.core.getri(A, pivot: list[int])#

Computes the matrix inverse based on the data returned from getrf. This does not take the inverse of A. The input must have been modified by getrf before calling this function.

Parameters:

A – The matrix output from getrf. After calling this function, this will

contain the matrix inverse. :param pivot: The pivot list from getrf. :raises einsums.core.rank_error: if the input tensor is not a matrix. :raises einsums.core.dimension_error: if the matrix is not square. :raises ValueError: if the pivot list has not been formatted properly, the input tensor does not store real or complex floating point data, or an illegal argument is passed to the underlying getri call. This last one should not happen. :raises RuntimeError: if the matrix is singular.

einsums.core.invert(A)#

Computes the matrix inverse. This calls getrf and getri under the hood so that you don’t have to worry about them.

Parameters:

A – The matrix to invert. After calling this function, this will contain the inverse matrix.

Raises:

does not store real or complex floating point data, or an illegal argument is passed to one of the underlying LAPACK calls. This last one should not happen. :raises RuntimeError: if the matrix is singular.

einsums.core.norm(norm_type: einsums.core.Norm, A)#

Computes the norm of a matrix. Does not handle vectors.

Parameters:
  • norm_type – The kind of norm to take.

  • A – The matrix to use.

Returns:

The norm of the matrix.

Raises:
  • einsums.core.rank_error – if the input tensor is not a matrix.

  • ValueError – if the matrix does not store real or complex floating point data.

einsums.core.vec_norm(A)#

Computes the norm of a vector.

Parameters:

A – The vector to use.

Returns:

The norm of the vector.

Raises:
  • einsums.core.rank_error – if the input is not a vector.

  • ValueError – if the vector does not store real or complex floating point data.

einsums.core.svd(A) tuple#

Performs singular value decomposition on a matrix.

Parameters:

A – The matrix to decompose.

Returns:

The left singular vectors, the singular value vector, and the right singular vectors in a tuple.

Raises:
  • einsums.core.rank_error – if the input is not a matrix.

  • ValueError – if the matrix does not store real or complex floating point values, or an

illegal argument is passed to the underlying LAPACK call. This last one should never happen. :raises RuntimeError: if the SVD iterations did not converge.

einsums.core.svd_nullspace(A)#

Computes the nullspace of a matrix using singular value decomposition.

Parameters:

A – The matrix to use.

Returns:

The nullspace basis as a matrix.

Raises:
  • einsums.core.rank_error – if the input tensor is not a matrix.

  • ValueError – if the matrix does not store real or complex floating point data, or an

invalid argument was passed to the underlying LAPACK call. This last one should not happen. :raises RuntimeError: if the SVD iterations did not converge.

einsums.core.svd_dd(A, job: einsums.core.Vectors = einsums.core.ALL) tuple#

Performs singular value decomposition on a matrix using the divide and conquer algorithm.

Parameters:
  • A – The matrix to decompose.

  • job – Determines which vectors to compute.

Returns:

The left singular vectors, the singular value vector, and the right singular vectors in a tuple.

Raises:
  • einsums.core.rank_error – if the input is not a matrix.

  • ValueError – if the matrix does not store real or complex floating point values, or an

illegal argument is passed to the underlying LAPACK call. This last one should never happen. :raises RuntimeError: if the SVD iterations did not converge.

einsums.core.truncated_svd(A, k: int) tuple#

Computes the singular value decomposition, but truncates the number of singular values.

Parameters:
  • A – The matrix to decompose.

  • k – The number of singular values to use.

Returns:

A tuple containing the left singular vectors, the list of singular values, and the right singular

vectors. :raises einsums.core.rank_error: if the input is not a matrix. :raises ValueError: if the matrix does not store real or complex floating point data.

einsums.core.truncated_syev(A, k: int) tuple#

Computes the eigendecomposition, but truncates the number of eigenvalues.

Parameters:
  • A – The matrix to decompose.

  • k – The number of eigenvalues to use.

Returns:

A tuple containing the eigenvectors and the list of eigenvalues.

Raises:
einsums.core.pseudoinverse(A, tol: float)#

Computes the pseudoinverse of a matrix.

Parameters:
  • A – The matrix to pseudoinvert.

  • tol – The tolerance on the singular values.

Returns:

The pseudoinverse of the input matrix.

Raises:
  • einsums.core.rank_error – if the input tensor is not a matrix.

  • ValueError – if the matrix does not store real or complex floating point data.

einsums.core.solve_continuous_lyapunov(A, Q)#

Solves a continuous Lyapunov equation. This is an equation of the following form.

\[\mathbf{AX} + \mathbf{XA}^H + \mathbf{Q} = 0\]
Parameters:
  • A – The A matrix.

  • Q – The Q matrix.

Returns:

The X matrix that solves this equation.

Raises:

with each other. :raises ValueError: if the input tensors do not have the same storage type, the inputs do not store real or complex floating point data, or an invalid argument is passed to one of the underlying LAPACK functions. This last case should hopefully not happen. :raises RuntimeError: if the Schur decomposition step fails to converge.

einsums.core.qr(A) tuple#

Perform QR decomposition. The information to get Q and R are returned.

Parameters:

A – The matrix to decompose.

Returns:

A tuple to be passed to q and r.

Raises:
  • einsums.core.rank_error – if the input is not a matrix.

  • ValueError – if the matrix input does not store real or complex floating point data,

or an invalid value was passed to the underlying LAPACK call. The second case should not happen.

einsums.core.q(QR, tau)#

Extract the Q factor from the return from qr.

Parameters:
  • QR – The first returned value from qr.

  • tau – The second returned value from qr.

Returns:

The Q matrix from the decomposition.

Raises:
  • einsums.core.rank_error – if the input is not a matrix.

  • ValueError – if the matrix inputs do not store the same data type,

do not store real or complex floating point data, or an invalid value was passed to the underlying LAPACK call. The second case should not happen.

einsums.core.r(QR, tau)#

Extract the R factor from the return from qr.

Parameters:
  • QR – The first returned value from qr.

  • tau – The second returned value from qr. Unused, but present to make it look like

the corresponding q call. :return: The R matrix from the decomposition. :raises einsums.core.rank_error: if the input is not a matrix. :raises ValueError: if the matrix inputs do not store real or complex floating point data.

einsums.core.direct_product(alpha, A, B, beta, C)#

Performs the following formula.

\[C_i := \beta C_i + \alpha A_i B_i\]
Parameters:
  • alpha – The scale factor for the product.

  • A – The first tensor in the product.

  • B – The second tensor in the product.

  • beta – The scale factor for the accumulation tensor.

  • C – The accumulation tensor.

Raises:

store real or complex floating point data.

einsums.core.det(A)#

Computes the determinant of a matrix.

Parameters:

A – The matrix to use.

Returns:

The determinant of the matrix.

Raises:

argument passed to the underlying LAPACK call was invalid. The second case should not happen.