Table of Contents

Class np.linalg

Namespace
NumSharp
Assembly
NumSharp.dll

NumPy's numpy.linalg module.

[ModuleName("np.linalg")]
public static class np.linalg
Inheritance
np.linalg
Inherited Members

Remarks

Most of this module needs a matrix backend and raises OpenBlasMissingBackendException without one. NumSharp.Core is 100 % managed C# and carries no LU, QR, SVD or eigensolver, so — unlike the matrix products, which always have a managed kernel to fall back on — a factorisation has nothing to compute with until something assigns Blas. The validation in front of the throw is NumPy-exact, so shape, rank and argument errors are the real ones.

What works today, because it composes out of primitives NumSharp already has: multi_dot(NDArray[], NDArray), matrix_power(NDArray, int) at a NON-NEGATIVE exponent, the Array-API forms matmul(NDArray, NDArray)/outer(NDArray, NDArray)/tensordot(NDArray, NDArray, int)/ trace(NDArray, int, DType)/diagonal(NDArray, int)/cross(NDArray, NDArray, int)/ matrix_transpose(NDArray)/vecdot(NDArray, NDArray, int), and every norm(NDArray, object, int?, bool) order except the three that are defined through singular values (matrix ord 2, -2 and 'nuc').

The Array-API forms are NOT aliases of their main-namespace twins — NumPy gives them different signatures and different defaults, and the differences are observable: np.linalg.trace reduces the LAST two axes where np.trace reduces the first two, np.linalg.outer demands 1-D operands where np.outer flattens anything, and np.linalg.cross requires 3-vectors where np.cross still accepts 2-vectors. Each is implemented against its own contract.

Methods

cholesky(NDArray, bool)

Cholesky decomposition of a Hermitian positive-definite matrix.

public static NDArray cholesky(NDArray a, bool upper = false)

Parameters

a NDArray
upper bool

False (the default) returns the LOWER-triangular factor L with a = L L*; true returns the upper-triangular U with a = U* U.

Returns

NDArray

Remarks

https://numpy.org/doc/stable/reference/generated/numpy.linalg.cholesky.html

Only the lower triangle of a is read, so a non-Hermitian operand is interpreted as its own reflection rather than rejected. A matrix that is not positive definite raises LinAlgError("Matrix is not positive definite") from the factorisation.

Exceptions

OpenBlasMissingBackendException

No matrix backend serves these operands.

cond(NDArray, object)

Condition number of a matrix in the given norm.

public static NDArray cond(NDArray x, object p = null)

Parameters

x NDArray
p object

The order: null (default) and ±2 use singular values; ±1, ±inf and "fro" are defined as norm(x, p) * norm(inv(x), p).

Returns

NDArray

Remarks

https://numpy.org/doc/stable/reference/generated/numpy.linalg.cond.html

Every order needs a factorisation — the singular-value ones directly, the rest through inv(NDArray) — so unlike norm(NDArray, object, int?, bool) there is no order that works without a backend.

Exceptions

OpenBlasMissingBackendException

No matrix backend serves these operands.

cross(NDArray, NDArray, int)

Cross product of 3-element vectors.

public static NDArray cross(NDArray x1, NDArray x2, int axis = -1)

Parameters

x1 NDArray
x2 NDArray
axis int

The axis holding the three components. Defaults to the last.

Returns

NDArray

Remarks

https://numpy.org/doc/stable/reference/generated/numpy.linalg.cross.html

Stricter than cross(NDArray, NDArray, int, int, int, int?): the Array-API form accepts 3-vectors ONLY, over a single axis, where the main-namespace cross(NDArray, NDArray, int, int, int, int?) also takes the 2-vector form (deprecated in NumPy 2.0) and a separate axisa/axisb/axisc per operand.

det(NDArray)

Determinant of a matrix, or of each matrix in a stack.

public static NDArray det(NDArray a)

Parameters

a NDArray

Returns

NDArray

Remarks

https://numpy.org/doc/stable/reference/generated/numpy.linalg.det.html

Computed from an LU factorisation (getrf), not by expansion — so for a large or ill-conditioned matrix the product of the pivots can overflow or underflow where slogdet(NDArray) stays finite.

Exceptions

OpenBlasMissingBackendException

No matrix backend serves these operands.

diagonal(NDArray, int)

Diagonals of the LAST TWO axes.

public static NDArray diagonal(NDArray x, int offset = 0)

Parameters

x NDArray
offset int

Returns

NDArray

Remarks

https://numpy.org/doc/stable/reference/generated/numpy.linalg.diagonal.html

As with trace(NDArray, int, DType), the axes differ from diagonal(NDArray, int, int, int)'s first-two default: a (2,3,3) stack gives (2,3) here and (3,2) there.

eig(NDArray)

Eigenvalues and right eigenvectors of a general (not necessarily symmetric) matrix.

public static (NDArray eigenvalues, NDArray eigenvectors) eig(NDArray a)

Parameters

a NDArray

Returns

(NDArray Lhs, NDArray Rhs)

(eigenvalues, eigenvectors), the columns of the second being the vectors.

Remarks

https://numpy.org/doc/stable/reference/generated/numpy.linalg.eig.html

The result dtype is DATA-dependent: a real matrix with a complex-conjugate pair of eigenvalues yields complex output, so the dtype cannot be predicted from the input dtype alone. Use eigh(NDArray, char) where the operand is known symmetric or Hermitian — it is both faster and guaranteed to give real eigenvalues.

Exceptions

OpenBlasMissingBackendException

No matrix backend serves these operands.

eigh(NDArray, char)

Eigenvalues and eigenvectors of a real symmetric or complex Hermitian matrix.

public static (NDArray eigenvalues, NDArray eigenvectors) eigh(NDArray a, char UPLO = 'L')

Parameters

a NDArray
UPLO char

Which triangle holds the data — 'L' (default) or 'U'. Case insensitive. The other triangle is NOT read, so a non-symmetric operand is silently interpreted as its own reflection rather than rejected.

Returns

(NDArray Lhs, NDArray Rhs)

(eigenvalues, eigenvectors) with the eigenvalues in ASCENDING order and always REAL — even for a complex operand, where they come back as the real counterpart dtype.

Remarks

Exceptions

OpenBlasMissingBackendException

No matrix backend serves these operands.

eigvals(NDArray)

Eigenvalues of a general matrix, without the eigenvectors.

public static NDArray eigvals(NDArray a)

Parameters

a NDArray

Returns

NDArray

Remarks

Exceptions

OpenBlasMissingBackendException

No matrix backend serves these operands.

eigvalsh(NDArray, char)

Eigenvalues of a real symmetric or complex Hermitian matrix, ascending.

public static NDArray eigvalsh(NDArray a, char UPLO = 'L')

Parameters

a NDArray
UPLO char

Which triangle holds the data — 'L' (default) or 'U'. Case insensitive. The other triangle is NOT read, so a non-symmetric operand is silently interpreted as its own reflection rather than rejected.

Returns

NDArray

(eigenvalues, eigenvectors) with the eigenvalues in ASCENDING order and always REAL — even for a complex operand, where they come back as the real counterpart dtype.

Remarks

Exceptions

OpenBlasMissingBackendException

No matrix backend serves these operands.

inv(NDArray)

Multiplicative inverse of a matrix, or of each matrix in a stack.

public static NDArray inv(NDArray a)

Parameters

a NDArray

Returns

NDArray

Remarks

https://numpy.org/doc/stable/reference/generated/numpy.linalg.inv.html

NumPy does not call an explicit inversion routine: it solves a x = I with gesv, which is why a singular operand surfaces as LinAlgError("Singular matrix") from the factorisation rather than from a determinant test.

Exceptions

OpenBlasMissingBackendException

No matrix backend serves these operands.

lstsq(NDArray, NDArray, double?)

Least-squares solution to a x = b.

public static (NDArray Solution, NDArray Residuals, NDArray Rank, NDArray SingularValues) lstsq(NDArray a, NDArray b, double? rcond = null)

Parameters

a NDArray

Coefficient matrix, (M, N). Exactly 2-D — lstsq does NOT stack.

b NDArray

Ordinate values, (M,) or (M, K).

rcond double?

Singular values smaller than rcond times the largest are treated as zero.

Returns

(NDArray, NDArray, NDArray, NDArray)

(solution, residuals, rank, singularValues) — NumPy's four-tuple. The residuals are EMPTY unless the system is overdetermined and full-rank.

Remarks

https://numpy.org/doc/stable/reference/generated/numpy.linalg.lstsq.html

Unlike most of this module, lstsq takes a single matrix rather than a stack — a 3-D operand is rejected with the "must be two-dimensional" message rather than the "at least two-dimensional" one.

Exceptions

OpenBlasMissingBackendException

No matrix backend serves these operands.

matmul(NDArray, NDArray)

public static NDArray matmul(NDArray x1, NDArray x2)

Parameters

x1 NDArray
x2 NDArray

Returns

NDArray

Remarks

https://numpy.org/doc/stable/reference/generated/numpy.linalg.matmul.html

This one really is the same operation as its main-namespace twin, unlike the rest of the forms in this file.

matrix_norm(NDArray, bool, object)

The Array-API matrix norm — always reduces the LAST TWO axes, and defaults to Frobenius.

public static NDArray matrix_norm(NDArray x, bool keepdims = false, object ord = null)

Parameters

x NDArray
keepdims bool
ord object

The order. null means NumPy's default of "fro" — C# cannot spell a non-null default for an object parameter, so the sentinel carries it.

Returns

NDArray

Remarks

matrix_power(NDArray, int)

Raises a square matrix to the (integer) power n.

public static NDArray matrix_power(NDArray a, int n)

Parameters

a NDArray
n int

Any integer. 0 gives the identity, a NEGATIVE power inverts first.

Returns

NDArray

Remarks

https://numpy.org/doc/stable/reference/generated/numpy.linalg.matrix_power.html

Computed by binary exponentiation, so the cost is logarithmic in n rather than linear — NumPy's own algorithm, and the reason the first three powers are special-cased before the loop starts.

A negative power is the only route here that needs a matrix backend (a**-n is inv(a)**n), so it raises OpenBlasMissingBackendException while none is installed. Non-negative powers work.

matrix_rank(NDArray, double?, bool, double?)

Rank of a matrix — the number of singular values greater than the tolerance.

public static NDArray matrix_rank(NDArray A, double? tol = null, bool hermitian = false, double? rtol = null)

Parameters

A NDArray
tol double?

Absolute threshold. Defaults to S.max() * max(M, N) * eps.

hermitian bool

Assume the operand is Hermitian.

rtol double?

Relative threshold; supplying it together with tol is an error.

Returns

NDArray

Remarks

Exceptions

OpenBlasMissingBackendException

No matrix backend serves these operands.

matrix_transpose(NDArray)

Transposes the last two axes — the Array-API spelling of matrix_transpose(NDArray). An O(1) view.

public static NDArray matrix_transpose(NDArray x)

Parameters

x NDArray

Returns

NDArray

Remarks

multi_dot(params NDArray[])

Chained matrix product, evaluated in the cheapest association order.

public static NDArray multi_dot(params NDArray[] arrays)

Parameters

arrays NDArray[]

Two or more arrays. With three or more, every one must be 2-D EXCEPT the endpoints, which may be 1-D (a 1-D first operand is a row, a 1-D last a column); a 0-D, a 3-D-or-higher, or a 1-D operand anywhere in the MIDDLE raises LinAlgError "{ndim}-dimensional array given. Array must be two-dimensional". With exactly two arrays this is a plain dot(NDArray, NDArray, NDArray) and imposes no such restriction.

Returns

NDArray

Remarks

https://numpy.org/doc/stable/reference/generated/numpy.linalg.multi_dot.html

Matrix multiplication is associative but its COST is not: chaining (10000,100) @ (100,1000) @ (1000,5) left to right costs about 10⁹ multiplications and right to left about 10⁷. This picks the order with the classic O(n³) dynamic program (Cormen et al. 15.2) — except for exactly three matrices, where the single comparison is done directly.

A 1-D first operand is treated as a ROW vector and a 1-D last operand as a COLUMN vector, with the added axis removed again afterwards — so the chain's endpoints behave like np.dot's.

multi_dot(NDArray[], NDArray)

Chained matrix product, evaluated in the cheapest association order.

public static NDArray multi_dot(NDArray[] arrays, NDArray @out = null)

Parameters

arrays NDArray[]

Two or more arrays. With three or more, every one must be 2-D EXCEPT the endpoints, which may be 1-D (a 1-D first operand is a row, a 1-D last a column); a 0-D, a 3-D-or-higher, or a 1-D operand anywhere in the MIDDLE raises LinAlgError "{ndim}-dimensional array given. Array must be two-dimensional". With exactly two arrays this is a plain dot(NDArray, NDArray, NDArray) and imposes no such restriction.

out NDArray

Where to deposit the answer. NumPy hands out to the final dot, so it receives the TWO-DIMENSIONAL product and the returned array is a reshaped view of it — out for multi_dot([v, B, C]) is shaped (1, k), not (k,).

Returns

NDArray

Remarks

https://numpy.org/doc/stable/reference/generated/numpy.linalg.multi_dot.html

Matrix multiplication is associative but its COST is not: chaining (10000,100) @ (100,1000) @ (1000,5) left to right costs about 10⁹ multiplications and right to left about 10⁷. This picks the order with the classic O(n³) dynamic program (Cormen et al. 15.2) — except for exactly three matrices, where the single comparison is done directly.

A 1-D first operand is treated as a ROW vector and a 1-D last operand as a COLUMN vector, with the added axis removed again afterwards — so the chain's endpoints behave like np.dot's.

norm(NDArray, object, int[], bool)

Matrix or vector norm reduced over an explicit axis tuple.

public static NDArray norm(NDArray x, object ord, int[] axis, bool keepdims = false)

Parameters

x NDArray

Input array. Integer and bool operands are computed in float64.

ord object

The order: null (Frobenius for a matrix, 2-norm for a vector), a number (including double.PositiveInfinity), or one of "fro", "f", "nuc".

axis int[]

The axis to reduce. null flattens.

keepdims bool

Leave the reduced axes in the result with length 1.

Returns

NDArray

Remarks

https://numpy.org/doc/stable/reference/generated/numpy.linalg.norm.html

Every order works WITHOUT a matrix backend except three — matrix ord 2, -2 and "nuc", which are defined through singular values and so raise OpenBlasMissingBackendException. The rest are reductions (abs(NDArray), sum(NDArray), amax(NDArray, int?, bool, DType), power(NDArray, object)) and compute normally.

How many axes are being reduced decides which vocabulary of orders applies, which is why norm(vector, "fro") and norm(matrix, 3) both raise but with DIFFERENT messages, and a 3-D operand with an explicit ord and no axis raises a third ("Improper number of dimensions to norm.").

norm(NDArray, object, int?, bool)

Matrix or vector norm.

public static NDArray norm(NDArray x, object ord = null, int? axis = null, bool keepdims = false)

Parameters

x NDArray

Input array. Integer and bool operands are computed in float64.

ord object

The order: null (Frobenius for a matrix, 2-norm for a vector), a number (including double.PositiveInfinity), or one of "fro", "f", "nuc".

axis int?

The axis to reduce. null flattens.

keepdims bool

Leave the reduced axes in the result with length 1.

Returns

NDArray

Remarks

https://numpy.org/doc/stable/reference/generated/numpy.linalg.norm.html

Every order works WITHOUT a matrix backend except three — matrix ord 2, -2 and "nuc", which are defined through singular values and so raise OpenBlasMissingBackendException. The rest are reductions (abs(NDArray), sum(NDArray), amax(NDArray, int?, bool, DType), power(NDArray, object)) and compute normally.

How many axes are being reduced decides which vocabulary of orders applies, which is why norm(vector, "fro") and norm(matrix, 3) both raise but with DIFFERENT messages, and a 3-D operand with an explicit ord and no axis raises a third ("Improper number of dimensions to norm.").

outer(NDArray, NDArray)

Outer product of two VECTORS.

public static NDArray outer(NDArray x1, NDArray x2)

Parameters

x1 NDArray
x2 NDArray

Returns

NDArray

Remarks

https://numpy.org/doc/stable/reference/generated/numpy.linalg.outer.html

Not a synonym for outer(NDArray, NDArray, NDArray): that one flattens whatever it is given, while this rejects anything but 1-D. np.outer(ones((2,3)), ones(3)) is a (6,3) array; np.linalg.outer of the same pair raises.

pinv(NDArray, double?, bool, double?)

Moore-Penrose pseudo-inverse, computed from the singular value decomposition.

public static NDArray pinv(NDArray a, double? rcond = null, bool hermitian = false, double? rtol = null)

Parameters

a NDArray
rcond double?

Singular values below rcond * largest are treated as zero. NumPy's default is 1e-15.

hermitian bool

Assume the operand is Hermitian, allowing the cheaper symmetric eigensolver.

rtol double?

The Array-API spelling of rcond. Supplying both is an error, as upstream.

Returns

NDArray

Remarks

Exceptions

OpenBlasMissingBackendException

No matrix backend serves these operands.

qr(NDArray, string)

QR factorisation — a = Q R with Q orthonormal and R upper-triangular.

public static (NDArray Q, NDArray R) qr(NDArray a, string mode = "reduced")

Parameters

a NDArray
mode string

"reduced" (default) gives Q:(...,M,K), R:(...,K,N) for K = min(M,N); "complete" gives a square Q:(...,M,M); "r" returns R alone; "raw" returns LAPACK's packed (h, tau) pair rather than (Q, R).

Returns

(NDArray Lhs, NDArray Rhs)

(Q, R). For "r" the Q slot is null; for "raw" the pair is (h, tau).

Remarks

Exceptions

OpenBlasMissingBackendException

No matrix backend serves these operands.

slogdet(NDArray)

Sign and natural log of the absolute determinant — the overflow-safe det(NDArray).

public static (NDArray sign, NDArray logabsdet) slogdet(NDArray a)

Parameters

a NDArray

Returns

(NDArray Lhs, NDArray Rhs)

(sign, logabsdet), such that sign * exp(logabsdet) is the determinant. A singular matrix gives (0, -inf); for a complex operand the sign is a unit-modulus complex number rather than ±1.

Remarks

Exceptions

OpenBlasMissingBackendException

No matrix backend serves these operands.

solve(NDArray, NDArray)

Solves the linear system a x = b for x.

public static NDArray solve(NDArray a, NDArray b)

Parameters

a NDArray

Coefficient matrix, (..., M, M).

b NDArray

Ordinate values, (..., M) or (..., M, K).

Returns

NDArray

Remarks

https://numpy.org/doc/stable/reference/generated/numpy.linalg.solve.html

NumPy 2.0 tightened the b-is-a-vector rule: b is treated as a stack of vectors ONLY when it is exactly 1-D. Anything else is a stack of matrices, so the two gufuncs — (m,m),(m)->(m) and (m,m),(m,n)->(m,n) — are selected by rank alone and report their own core-dimension errors.

Exceptions

OpenBlasMissingBackendException

No matrix backend serves these operands.

svd(NDArray, bool, bool, bool)

Singular value decomposition — a = U diag(S) Vh.

public static (NDArray U, NDArray S, NDArray Vh) svd(NDArray a, bool full_matrices = true, bool compute_uv = true, bool hermitian = false)

Parameters

a NDArray
full_matrices bool

True (the default) makes U and Vh full square factors; false truncates them to K = min(M, N) columns/rows.

compute_uv bool

False returns the singular values alone — U and Vh are then null.

hermitian bool

Assume the operand is Hermitian, allowing the cheaper symmetric eigensolver.

Returns

(NDArray, NDArray, NDArray)

Remarks

https://numpy.org/doc/stable/reference/generated/numpy.linalg.svd.html

Singular values come back in DESCENDING order. This is the routine behind pinv(NDArray, double?, bool, double?), matrix_rank(NDArray, double?, bool, double?), cond(NDArray, object) and the spectral and nuclear matrix norms — which is why all of those stop here too.

Exceptions

OpenBlasMissingBackendException

No matrix backend serves these operands.

svdvals(NDArray)

Singular values of a matrix, descending — the Array-API spelling of svd(x, compute_uv: false).

public static NDArray svdvals(NDArray x)

Parameters

x NDArray

Returns

NDArray

Remarks

Exceptions

OpenBlasMissingBackendException

No matrix backend serves these operands.

tensordot(NDArray, NDArray, int)

Tensor contraction — the Array-API spelling of tensordot(NDArray, NDArray, int).

public static NDArray tensordot(NDArray x1, NDArray x2, int axes = 2)

Parameters

x1 NDArray
x2 NDArray
axes int

Returns

NDArray

Remarks

tensordot(NDArray, NDArray, int[], int[])

Tensor contraction — the Array-API spelling of tensordot(NDArray, NDArray, int).

public static NDArray tensordot(NDArray x1, NDArray x2, int[] axesA, int[] axesB)

Parameters

x1 NDArray
x2 NDArray
axesA int[]
axesB int[]

Returns

NDArray

Remarks

tensorinv(NDArray, int)

Inverse of an N-dimensional array with respect to a tensordot(NDArray, NDArray, int) contraction over its last a.ndim - ind axes.

public static NDArray tensorinv(NDArray a, int ind = 2)

Parameters

a NDArray
ind int

How many LEADING axes form the "row" side. Must be positive.

Returns

NDArray

Remarks

Exceptions

OpenBlasMissingBackendException

No matrix backend serves these operands.

tensorsolve(NDArray, NDArray, int[])

Solves the tensor equation a x = b for x.

public static NDArray tensorsolve(NDArray a, NDArray b, int[] axes = null)

Parameters

a NDArray
b NDArray
axes int[]

Axes of a to move to the right before inversion.

Returns

NDArray

Remarks

https://numpy.org/doc/stable/reference/generated/numpy.linalg.tensorsolve.html

A reshape of solve(NDArray, NDArray): a is collapsed to a square matrix whose side is prod(b.shape), solved, and the answer reshaped to the trailing block of a.shape.

Exceptions

OpenBlasMissingBackendException

No matrix backend serves these operands.

trace(NDArray, int, DType)

Sum along the diagonals of the LAST TWO axes.

public static NDArray trace(NDArray x, int offset = 0, DType dtype = null)

Parameters

x NDArray
offset int
dtype DType

Returns

NDArray

Remarks

https://numpy.org/doc/stable/reference/generated/numpy.linalg.trace.html

The axes differ from trace(NDArray, int, int, int, DType, NDArray)'s, which defaults to the FIRST two — so on a (2,3,3) stack this returns shape (2,) (one trace per matrix) where np.trace returns (3,). Neither is wrong; they are different functions.

vecdot(NDArray, NDArray, int)

Vector dot product over axis, conjugating the first operand.

public static NDArray vecdot(NDArray x1, NDArray x2, int axis = -1)

Parameters

x1 NDArray
x2 NDArray
axis int

Returns

NDArray

Remarks

vector_norm(NDArray, int, bool, object)

The Array-API vector norm reduced over a single axis.

public static NDArray vector_norm(NDArray x, int axis, bool keepdims = false, object ord = null)

Parameters

x NDArray
axis int
keepdims bool
ord object

The order. null means NumPy's default of 2 — C# cannot spell a non-null default for an object parameter, so the sentinel carries it.

Returns

NDArray

Remarks

vector_norm(NDArray, int[], bool, object)

The Array-API vector norm — axis defaults to flattening and ord to 2.

public static NDArray vector_norm(NDArray x, int[] axis = null, bool keepdims = false, object ord = null)

Parameters

x NDArray
axis int[]
keepdims bool
ord object

The order. null means NumPy's default of 2 — C# cannot spell a non-null default for an object parameter, so the sentinel carries it.

Returns

NDArray

Remarks