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)mnkm \cdot n \cdot k4.0Truncated SVD
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)mn2n3/3mn^2 - n^3/34.0Householder QR (FMA=1)
fnp.linalg.eigvals(A)10n310n^34.0Eigenvalues only
fnp.linalg.eigvalsh(A)4n3/34n^3/34.0Symmetric eigenvalues only
fnp.linalg.svdvals(A)mnmin(m,n)m \cdot n \cdot \min(m,n)4.0Singular values only

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)mnmin(m,n)m \cdot n \cdot \min(m,n)4.0
fnp.linalg.pinv(A)mnmin(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)mnmin(m,n)m \cdot n \cdot \min(m,n)varies
fnp.linalg.matrix_rank(A)mnmin(m,n)m \cdot n \cdot \min(m,n)varies
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), symmetric_axes=(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.svd_cost(m=256, n=256, k=10)
print(f"SVD cost: {cost:,}")  # 655,360

cost = flops.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