flopscope.
Guides

Linear Algebra

Use this page to learn how to use fnp.linalg operations and their FLOP costs.

You will learn:

  • How to use decompositions, solvers, and property operations in fnp.linalg
  • How symmetric inputs reduce linalg costs
  • How to query linalg costs before running them

Prerequisites

Available operations

Decompositions

OperationCostWeightNotes
fnp.linalg.svd(A, k=k)min⁡(4mnk+6(m+n)k2+20k3,6ab2+20b3)\min(4mnk+6(m+n)k^2+20k^3,6ab^2+20b^3)1.0Truncated, with vectors
fnp.linalg.eig(A)10n310n^34.0General eigendecomposition
fnp.linalg.eigh(A)4n3/34n^3/34.0Symmetric eigendecomposition
fnp.linalg.cholesky(A)n3/3n^3/34.0Cholesky (symmetric positive definite)
fnp.linalg.qr(A)mn2−n3/3mn^2 - n^3/34.0Householder QR (FMA=2)
fnp.linalg.eigvals(A)10n310n^34.0Eigenvalues only
fnp.linalg.eigvalsh(A)4n3/34n^3/34.0Symmetric eigenvalues only
fnp.linalg.svdvals(A)2ab2+2b32ab^2+2b^31.0Full singular values only

For SVD, a=max(m,n) and b=min(m,n). Truncated values-only calls (svd(A, compute_uv=False, k=k) or svdvals(A, k=k)) bill min(4mnk+2(m+n)k²+2k³, 2ab²+2b³) for 1 <= k < b. At k=b, the corresponding full economy price applies. Full calls without k retain their thin/full-vector/values-only formulas, including the rectangular full-vector premium. Multiply per-matrix prices by the batch size and apply dtype/complex rates. The backend returns exact factors; pricing is an analytical convention. See the cost model for details and the limits of the near-full-rank accounting guarantee.

Solvers

solve_cost(n) always returns n^3 regardless of the symmetric or nrhs parameters — those arguments exist for API compatibility but are currently ignored in the cost model.

OperationCostWeight
fnp.linalg.solve(A, b)n3n^34.0
fnp.linalg.inv(A)n3n^34.0
fnp.linalg.lstsq(A, b)m⋅n⋅min⁡(m,n)m \cdot n \cdot \min(m,n)4.0
fnp.linalg.pinv(A)m⋅n⋅min⁡(m,n)m \cdot n \cdot \min(m,n)4.0

inv of a symmetric matrix returns a SymmetricTensor.

Properties

OperationCostWeight
fnp.linalg.det(A)n3n^34.0
fnp.linalg.slogdet(A)n3n^34.0
fnp.linalg.norm(x)depends on ordvaries
fnp.linalg.cond(A)m⋅n⋅min⁡(m,n)m \cdot n \cdot \min(m,n)varies
fnp.linalg.matrix_rank(A)Values-only SVD per matrix + bb comparisons per broadcast (matrix,tol/rtol) pairvaries
fnp.linalg.trace(A)nnvaries

Compound

OperationCostNotes
fnp.linalg.multi_dot(arrays)Optimal chain orderingUses np.linalg.multi_dot
fnp.linalg.matrix_power(A, n)n3×{exponent}n^3 \times \text\{exponent\}Repeated squaring

Symmetric input savings

Pass a SymmetricTensor to get automatic cost reductions:

import flopscope as flops
import flopscope.numpy as fnp

with flops.BudgetContext(flop_budget=10**8) as budget:
    A = flops.as_symmetric(fnp.multiply(fnp.eye(10), 2.0), symmetry=(0, 1))

    # solve_cost(n=10) = n^3 = 1000 FLOPs (symmetric/nrhs params are currently ignored)
    x = fnp.linalg.solve(A, fnp.ones(10))

    # inv returns SymmetricTensor
    A_inv = fnp.linalg.inv(A)
    print(isinstance(A_inv, flops.SymmetricTensor))  # True

See Exploit Symmetry Savings for full details.

Query cost before running

cost = flops.accounting.svd_cost(m=256, n=256, k=10)
print(f"SVD cost: {cost:,}")  # 2,725,840 (values-only default; dtype-neutral query)

cost = flops.accounting.solve_cost(n=256)
print(f"Solve cost: {cost:,}")  # 16,777,216 (= 256^3; symmetric/nrhs params currently ignored)

Common pitfalls

Symptom: Using numpy.linalg.svd instead of fnp.linalg.svd

Fix: Operations called through numpy directly bypass FLOP counting. Always use fnp.linalg.*.

On this page