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
aNDArrayupperboolFalse (the default) returns the LOWER-triangular factor
Lwitha = L L*; true returns the upper-triangularUwitha = U* U.
Returns
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
xNDArraypobjectThe order:
null(default) and±2use singular values;±1,±infand"fro"are defined asnorm(x, p) * norm(inv(x), p).
Returns
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
Returns
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
aNDArray
Returns
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
Returns
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
aNDArray
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
aNDArrayUPLOcharWhich 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
aNDArray
Returns
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
aNDArrayUPLOcharWhich 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
aNDArray
Returns
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
aNDArrayCoefficient matrix,
(M, N). Exactly 2-D — lstsq does NOT stack.bNDArrayOrdinate values,
(M,)or(M, K).rconddouble?Singular values smaller than
rcondtimes 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)
Matrix product — the Array-API spelling of matmul(NDArray, NDArray, NDArray, int[][], int?, bool?, DType, string, char).
public static NDArray matmul(NDArray x1, NDArray x2)
Parameters
Returns
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
xNDArraykeepdimsboolordobjectThe order.
nullmeans NumPy's default of"fro"— C# cannot spell a non-null default for anobjectparameter, so the sentinel carries it.
Returns
Remarks
matrix_power(NDArray, int)
Raises a square matrix to the (integer) power n.
public static NDArray matrix_power(NDArray a, int n)
Parameters
Returns
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
ANDArraytoldouble?Absolute threshold. Defaults to
S.max() * max(M, N) * eps.hermitianboolAssume the operand is Hermitian.
rtoldouble?Relative threshold; supplying it together with
tolis an error.
Returns
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
xNDArray
Returns
Remarks
multi_dot(params NDArray[])
Chained matrix product, evaluated in the cheapest association order.
public static NDArray multi_dot(params NDArray[] arrays)
Parameters
arraysNDArray[]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
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
arraysNDArray[]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.
outNDArrayWhere to deposit the answer. NumPy hands
outto the finaldot, so it receives the TWO-DIMENSIONAL product and the returned array is a reshaped view of it —outformulti_dot([v, B, C])is shaped(1, k), not(k,).
Returns
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
xNDArrayInput array. Integer and bool operands are computed in float64.
ordobjectThe order:
null(Frobenius for a matrix, 2-norm for a vector), a number (includingdouble.PositiveInfinity), or one of"fro","f","nuc".axisint[]The axis to reduce.
nullflattens.keepdimsboolLeave the reduced axes in the result with length 1.
Returns
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
xNDArrayInput array. Integer and bool operands are computed in float64.
ordobjectThe order:
null(Frobenius for a matrix, 2-norm for a vector), a number (includingdouble.PositiveInfinity), or one of"fro","f","nuc".axisint?The axis to reduce.
nullflattens.keepdimsboolLeave the reduced axes in the result with length 1.
Returns
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
Returns
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
aNDArrayrconddouble?Singular values below
rcond * largestare treated as zero. NumPy's default is1e-15.hermitianboolAssume the operand is Hermitian, allowing the cheaper symmetric eigensolver.
rtoldouble?The Array-API spelling of
rcond. Supplying both is an error, as upstream.
Returns
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
aNDArraymodestring"reduced"(default) givesQ:(...,M,K),R:(...,K,N)forK = min(M,N);"complete"gives a squareQ:(...,M,M);"r"returns R alone;"raw"returns LAPACK's packed(h, tau)pair rather than (Q, R).
Returns
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
aNDArray
Returns
- (NDArray Lhs, NDArray Rhs)
(sign, logabsdet), such thatsign * 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
Returns
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
aNDArrayfull_matricesboolTrue (the default) makes U and Vh full square factors; false truncates them to
K = min(M, N)columns/rows.compute_uvboolFalse returns the singular values alone —
UandVhare then null.hermitianboolAssume the operand is Hermitian, allowing the cheaper symmetric eigensolver.
Returns
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
xNDArray
Returns
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
Returns
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
Returns
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
Returns
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
Returns
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
Returns
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
Returns
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
xNDArrayaxisintkeepdimsboolordobjectThe order.
nullmeans NumPy's default of 2 — C# cannot spell a non-null default for anobjectparameter, so the sentinel carries it.
Returns
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
xNDArrayaxisint[]keepdimsboolordobjectThe order.
nullmeans NumPy's default of 2 — C# cannot spell a non-null default for anobjectparameter, so the sentinel carries it.