Repository files navigation

Matrices

English | 中文文档

Matrices is a matrix computation and linear algebra library for Dart and Flutter. It focuses on high performance and script-style ergonomics, providing NumPy/MATLAB-like construction, indexing, broadcasting, and operator semantics, while keeping explicit 32-bit and 64-bit precision choices.

Project features:

  • Uses Dart's built-in SIMD APIs to accelerate computation, without depending on FFI or platform-specific binary runtimes.
  • Uses contiguous typed-data storage to avoid performance and semantic issues from nested-list structures.
  • Explicit Matrix64 / Matrix32 and Vector64 / Vector32 APIs.
  • Covers common dense matrices, CSR sparse matrices, direct decompositions, advanced decompositions, iterative methods, and Krylov methods.

Quick Start

import'package:matrices/matrices.dart';
voidmain() {
final a =mat([
[1, 2, 3],
[4, 5, 6],
]);
final b =mat([
[7, 8],
[9, 10],
[11, 12],
]);
final x =vec([1, 1, 1]);
print(a * b); // Matrix64 matrix multiplicationprint(a * x); // Matrix64 * Vector64print(a +1); // scalar broadcastingprint(a + x); // row-vector broadcastingprint(a.transpose);
}

Explicit 32-bit path:

final a32 =mat32([
[1, 2],
[3, 4],
]);
final x32 =vec32([1, 1]);
print(a32 * x32); // Vector32print(a32 * a32); // Matrix32print(a32.toFloat64()); // Matrix64

Type System

TypeStorageUse
Matrix64Float64ListDefault high-precision dense matrix
Matrix32Float32ListThroughput and memory-oriented dense matrix
Vector64Float64ListDefault high-precision vector
Vector32Float32ListThroughput-oriented float32 vector
Matrixtypedef Matrix = Matrix64Script-friendly short name
Vectortypedef Vector = Vector64Script-friendly short name

Matrix and Vector are 64-bit aliases, not separate implementations. Public APIs and documentation should prefer Matrix64 / Vector64 when precision must be explicit. Use Matrix32 / Vector32 for float32. The package does not silently downgrade precision.

Default constructors use full words, with short aliases for script-style code. Examples use short aliases for interactive ergonomics.

Default APIShort aliasReturn type
matrix([...])mat([...])Matrix64
matrix32([...])mat32([...])Matrix32
vector([...])vec([...])Vector64
vector32([...])vec32([...])Vector32

Helper constructors follow the same pattern, for example vectorZeros / vecZeros and vectorLinspace32 / vecLinspace32.

Construction

64-bit matrices:

final a =Matrix64([
[1, 2],
[3, 4],
]);
final b =Matrix([
[1, 2],
[3, 4],
]); // Matrix is an alias for Matrix64final z =zeros(2, 3);
final o =ones(2, 3);
final f =full(2, 3, 9);
final r =rand(2, 3, seed:42);
final i =eye(4);
final d =diag([1, 2, 3]);
final grid =arange(0, 12, columns:4);
final samples =linspace(0, 1, 5);

32-bit matrices:

final a32 =Matrix32([
[1, 2],
[3, 4],
]);
final z32 =zeros32(2, 3);
final o32 =ones32(2, 3);
final f32 =full32(2, 3, 1.5);
final r32 =rand32(1024, 1024, seed:7);
final i32 =eye32(4);
final d32 =diag32([1, 2, 3]);
final grid32 =arange32(0, 12, columns:4);
final samples32 =linspace32(0, 1, 5);

Other constructors:

final fromRows =Matrix64.fromRows([[1, 2], [3, 4]]);
final fromColumns =Matrix64.fromColumns([[1, 3], [2, 4]]);
final fromFlat =Matrix64.fromFlat([1, 2, 3, 4], 2, 2);
final fromBytes =Matrix64.fromByteData(
Float64List.fromList([1, 2, 3, 4]).buffer.asByteData(),
2,
2,
);
final spd =Matrix64.randomSPD(4, seed:1);

Indexing, Views, And Conversion

final a =arange(0, 9, columns:3);
print(a(1, 2)); // element accessprint(a[1][2]); // row view accessprint(a.row(0)); // Vector64print(a.column(1)); // Vector64
a.set(0, 0, 99);
a[1][1] =42;
final rows = a.toRows();
final values = a.values; // Float64List copyfinal unsafe = a.unsafeValuesView; // internal storage view for advanced usefinal json = a.toJson();
final restored =Matrix64.fromJson(json);

Rows are fixed-length views. Vector64 and Vector32 are fixed-length linear algebra objects that implement Iterable<double>; they are not growable List<double> objects.

Arithmetic Semantics

final a =mat([
[1, 2],
[3, 4],
]);
final b =mat([
[5, 6],
[7, 8],
]);
final x =vec([1, 1]);
print(a + b); // elementwise additionprint(a -1); // scalar broadcastingprint(a *2); // scalar multiplicationprint(a * b); // matrix multiplicationprint(a * x); // matrix-vector multiplicationprint(x * a); // vector-matrix multiplicationprint(a + x); // row-vector broadcastingprint(a.hadamard(b)); // Hadamard elementwise multiplicationprint(a /2);

The meaning of * depends on the right-hand side:

  • matrix * matrix is matrix multiplication.
  • matrix * vector is matrix-vector multiplication.
  • vector * matrix is row-vector matrix multiplication.
  • matrix * number and vector * number are scalar multiplication.
  • Use hadamard for elementwise matrix multiplication.

Invalid shapes throw ArgumentError immediately. The library does not silently reshape, pad, or truncate data.

Shape And Data Operations

final a =arange(0, 12, columns:4);
print(a.transpose);
print(a.t);
print(a.reshape(4, 3));
print(a.slice(rowStart:1, rowEnd:3, columnStart:1));
print(a.sample(rowIndices: [0, 2], columnIndices: [1, 3]));
print(a.vstack(a));
print(a.hstack(a));
print(a.flatten());

Transforms and statistics:

final centered = a.mapColumns((column) => column - column.mean);
final selected = a.filterRows((row, index) => row.sum >10);
final sorted = a.sort((row) => row.sum, direction:SortDirection.desc);
print(a.mean);
print(a.meanByAxis(Axis.columns));
print(a.variance(Axis.rows));
print(a.deviation(Axis.rows));
print(a.norm());

Vector API

final x =vec([1, 2, 3]);
final y =vec([4, 5, 6]);
final x32 =vec32([1, 2, 3, 4]);
final y32 =vec32([5, 6, 7, 8]);
print(x.dot(y));
print(x.norm());
print(x.distanceTo(y, Distance.euclidean));
print(x.cosine(y));
print(x.normalize());
print(x.subvector(1));
print(x.unique());
print(x32.dot(y32));
print(x32 + y32);

Helper constructors:

final z =vecZeros(3);
final o =vecOnes(3);
final f =vecFull(3, 2);
final r =randVec(3, seed:1);
final range =vecRange(0, 10, step:2);
final line =vecLinspace(0, 1, 5);
final z32 =vecZeros32(4);
final o32 =vecOnes32(4);

Direct Linear Algebra

final a =mat([
[4, 7],
[2, 6],
]);
print(a.determinant);
print(a.inverse);
print(a.trace);
print(a.rank);
print(a.rref());
final rhs =mat([
[1],
[0],
]);
print(a.solve(rhs));

Square-matrix entry point:

final s =SquareMatrix.fromList([
[4, 7],
[2, 6],
]);
print(s.determinant);
print(s.inverse);
print(s.logAbsDeterminant);

Direct solve, determinant, and inverse use pivoting. Singular matrices throw at working precision. Ill-conditioned problems should pass explicit tolerances.

Decompositions And Advanced Algorithms

final a =mat([
[4, 1],
[1, 3],
]);
final lu = a.lu();
final qr = a.qr();
final cholesky = a.cholesky();
final eigen = a.eigenSymmetric();
final svd = a.svd();
print(lu.solve(mat([[1], [2]])));
print(qr.q * qr.r);
print(cholesky.lower * cholesky.lower.transpose);
print(eigen.values);
print(svd.singularValues);

High-level APIs:

final design =mat([
[1, 1],
[1, 2],
[1, 3],
]);
final observed =mat([
[1],
[2],
[2],
]);
print(design.leastSquares(observed));
print(design.pseudoInverse());
final pca = design.pca(components:1);
print(pca.components);
print(pca.explainedVariance);
APIApplies toTypical use
lu()square matricesDirect solve, determinant, pivoted factorization
qr()tall or full-rank square matricesLeast squares, orthogonalization
cholesky()symmetric positive definite matricesSPD solve and factorization
eigenSymmetric()real symmetric matricesFull eigenvalues and eigenvectors
eigen()symmetric full solve or power iterationHigh-level eigen interface
svd()rectangular or square matricesLow-rank analysis, pseudoinverse
pseudoInverse()rectangular or square matricesMoore-Penrose pseudoinverse
leastSquares(rhs)overdetermined or full-rank systemsLeast squares
pca()observation x feature matrixPrincipal component analysis

Matrix32 exposes the same high-level API names. Matrix-valued results keep 32-bit storage; scalar accumulations may use Dart double temporaries where the language requires it.

Iterative And Krylov Methods

final a =mat([
[4, 1],
[1, 3],
]);
final b =vec([1, 2]);
print(a.jacobi(b).solution);
print(a.gaussSeidel(b).solution);
print(a.sor(b, omega:1.1).solution);
print(a.conjugateGradient(b).solution);
print(a.gmres(b, restart:20).solution);
print(a.arnoldi(b, 2).hessenberg);
print(a.powerIteration().eigenvalue);

Result objects include convergence status, iteration count, residual norm, and the computed solution or eigenpair. Iterative methods are sensitive to initial guess, tolerance, conditioning, and expected convergence properties. Production code should set tolerance and maxIterations explicitly.

Sparse Matrices

final sparse =SparseMatrix.fromRows([
[1, 0, 2],
[0, 0, 3],
[4, 0, 0],
]);
print(sparse.nnz);
print(sparse.mv(vec([1, 2, 3])));
print(sparse.matmul(eye(3)));
print(sparse.transpose().toDense());
final fromTriplets =SparseMatrix.fromTriplets(3, 3, [
SparseEntry(0, 0, 1),
SparseEntry(0, 2, 2),
SparseEntry(2, 1, 4),
]);
final compact =mat([
[1, 0],
[0, 2],
]).toSparse();

Sparse matrices use CSR storage. The sparse API is separate from Matrix64 / Matrix32 dense kernels and is intended for matrices where nonzero entries are a small fraction of total entries.

Precision, Numerics, And Performance Policy

Recommended choices:

  • Use Matrix64 / Vector64 by default.
  • Use Matrix32 / Vector32 for large throughput-oriented workloads when float32 error is acceptable.
  • Set explicit tolerances for ill-conditioned matrices, rank decisions, near-singular systems, and iterative solvers.

Matrix32 and Vector32 use Float32x4 on suitable hot paths, including matrix multiplication, matrix-vector multiplication, vector-matrix multiplication, elementwise arithmetic, scalar arithmetic, dot products, sums, and norms. Matrix64 / Vector64 use Float64List and Float64x2-oriented kernels.

API scope:

  • Covers common dense-matrix workflows: construction, indexing, shape operations, arithmetic, statistics, JSON, decompositions, and solves.
  • Adds QR, SVD, pseudoinverse, least squares, PCA, iterative methods, Krylov methods, and CSR sparse matrices.
  • Does not include native BLAS/LAPACK, GPU execution, autodiff, distributed matrices, or full complex nonsymmetric eigensolvers.

Benchmark

Benchmark scripts use an AOT runner by default. JIT is for smoke/debug runs and must not be used for published performance claims.

Focused matrix multiplication comparison:

dart run test/benchmark_matmul.dart 256,512,1024 3 1 build/performance_report.md

Broader benchmark suite:

dart run test/benchmark_suite.dart 100,256,512,1000 3 1 build/benchmark_suite.md

The suite covers construction, scalar/elementwise operations, broadcasting, square and rectangular matrix multiplication, matrix-vector, vector-matrix, transpose, direct solves, vectors, sparse matrices, decompositions, least squares, statistics, and iterative/Krylov algorithms.

Generated reports:

Performance claims must name:

  • Dart SDK and command line.
  • AOT/JIT mode.
  • Precision: float32 or float64.
  • Matrix size and shape.
  • Compared package version and interface.
  • Iterations, warmups, and sample count.

Testing And Quality Gates

Routine checks:

dart format --output=none --set-exit-if-changed lib test
dart analyze
dart test

Optional performance regression:

MATRICES_PERF_REGRESSION=1 dart test test/performance_regression_test.dart

The test suite covers:

  • Construction, indexing, shape validation, and error paths.
  • Matrix64 / Matrix32 / Vector64 / Vector32 arithmetic.
  • Matrix multiplication against reference implementations.
  • LU, QR, Cholesky, determinant, inverse, and solve.
  • Symmetric eigen, SVD, pseudoinverse, least squares, PCA.
  • Jacobi, Gauss-Seidel, SOR, CG, GMRES, Arnoldi, power iteration.
  • CSR sparse construction, conversion, transpose, serialization, vector multiply, and dense multiply.
  • Randomized property tests, ill-conditioned Hilbert residuals, near-singular tolerance behavior, and float32 tolerances.

Recommended quality gates should at least include format checks, static analysis, tests, benchmark smoke, coverage artifacts, and API reference generation.

Error Handling

Matrices fails fast on shape and numerical preconditions:

mat([[1, 2]]) *mat([[1, 2]]); // ArgumentErrormat([[1, 2], [2, 4]]).inverse; // StateErrormat([[1, 2], [3, 4]]).cholesky(); // StateError

The package does not silently reshape, pad, truncate, or change precision.

About

Matrix Computing and Linear Algebra Library for Dart and Flutter

Topics

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all \u003cpre\u003e\u003ccode\u003e blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks"); } } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); } })(); (function(){ try { var __m = "github.com"; var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

Matrices

English | 中文文档

Matrices is a matrix computation and linear algebra library for Dart and Flutter. It focuses on high performance and script-style ergonomics, providing NumPy/MATLAB-like construction, indexing, broadcasting, and operator semantics, while keeping explicit 32-bit and 64-bit precision choices.

Project features:

  • Uses Dart's built-in SIMD APIs to accelerate computation, without depending on FFI or platform-specific binary runtimes.
  • Uses contiguous typed-data storage to avoid performance and semantic issues from nested-list structures.
  • Explicit Matrix64 / Matrix32 and Vector64 / Vector32 APIs.
  • Covers common dense matrices, CSR sparse matrices, direct decompositions, advanced decompositions, iterative methods, and Krylov methods.

Quick Start

import'package:matrices/matrices.dart';
voidmain() {
final a =mat([
[1, 2, 3],
[4, 5, 6],
]);
final b =mat([
[7, 8],
[9, 10],
[11, 12],
]);
final x =vec([1, 1, 1]);
print(a * b); // Matrix64 matrix multiplicationprint(a * x); // Matrix64 * Vector64print(a +1); // scalar broadcastingprint(a + x); // row-vector broadcastingprint(a.transpose);
}

Explicit 32-bit path:

final a32 =mat32([
[1, 2],
[3, 4],
]);
final x32 =vec32([1, 1]);
print(a32 * x32); // Vector32print(a32 * a32); // Matrix32print(a32.toFloat64()); // Matrix64

Type System

TypeStorageUse
Matrix64Float64ListDefault high-precision dense matrix
Matrix32Float32ListThroughput and memory-oriented dense matrix
Vector64Float64ListDefault high-precision vector
Vector32Float32ListThroughput-oriented float32 vector
Matrixtypedef Matrix = Matrix64Script-friendly short name
Vectortypedef Vector = Vector64Script-friendly short name

Matrix and Vector are 64-bit aliases, not separate implementations. Public APIs and documentation should prefer Matrix64 / Vector64 when precision must be explicit. Use Matrix32 / Vector32 for float32. The package does not silently downgrade precision.

Default constructors use full words, with short aliases for script-style code. Examples use short aliases for interactive ergonomics.

Default APIShort aliasReturn type
matrix([...])mat([...])Matrix64
matrix32([...])mat32([...])Matrix32
vector([...])vec([...])Vector64
vector32([...])vec32([...])Vector32

Helper constructors follow the same pattern, for example vectorZeros / vecZeros and vectorLinspace32 / vecLinspace32.

Construction

64-bit matrices:

final a =Matrix64([
[1, 2],
[3, 4],
]);
final b =Matrix([
[1, 2],
[3, 4],
]); // Matrix is an alias for Matrix64final z =zeros(2, 3);
final o =ones(2, 3);
final f =full(2, 3, 9);
final r =rand(2, 3, seed:42);
final i =eye(4);
final d =diag([1, 2, 3]);
final grid =arange(0, 12, columns:4);
final samples =linspace(0, 1, 5);

32-bit matrices:

final a32 =Matrix32([
[1, 2],
[3, 4],
]);
final z32 =zeros32(2, 3);
final o32 =ones32(2, 3);
final f32 =full32(2, 3, 1.5);
final r32 =rand32(1024, 1024, seed:7);
final i32 =eye32(4);
final d32 =diag32([1, 2, 3]);
final grid32 =arange32(0, 12, columns:4);
final samples32 =linspace32(0, 1, 5);

Other constructors:

final fromRows =Matrix64.fromRows([[1, 2], [3, 4]]);
final fromColumns =Matrix64.fromColumns([[1, 3], [2, 4]]);
final fromFlat =Matrix64.fromFlat([1, 2, 3, 4], 2, 2);
final fromBytes =Matrix64.fromByteData(
Float64List.fromList([1, 2, 3, 4]).buffer.asByteData(),
2,
2,
);
final spd =Matrix64.randomSPD(4, seed:1);

Indexing, Views, And Conversion

final a =arange(0, 9, columns:3);
print(a(1, 2)); // element accessprint(a[1][2]); // row view accessprint(a.row(0)); // Vector64print(a.column(1)); // Vector64
a.set(0, 0, 99);
a[1][1] =42;
final rows = a.toRows();
final values = a.values; // Float64List copyfinal unsafe = a.unsafeValuesView; // internal storage view for advanced usefinal json = a.toJson();
final restored =Matrix64.fromJson(json);

Rows are fixed-length views. Vector64 and Vector32 are fixed-length linear algebra objects that implement Iterable<double>; they are not growable List<double> objects.

Arithmetic Semantics

final a =mat([
[1, 2],
[3, 4],
]);
final b =mat([
[5, 6],
[7, 8],
]);
final x =vec([1, 1]);
print(a + b); // elementwise additionprint(a -1); // scalar broadcastingprint(a *2); // scalar multiplicationprint(a * b); // matrix multiplicationprint(a * x); // matrix-vector multiplicationprint(x * a); // vector-matrix multiplicationprint(a + x); // row-vector broadcastingprint(a.hadamard(b)); // Hadamard elementwise multiplicationprint(a /2);

The meaning of * depends on the right-hand side:

  • matrix * matrix is matrix multiplication.
  • matrix * vector is matrix-vector multiplication.
  • vector * matrix is row-vector matrix multiplication.
  • matrix * number and vector * number are scalar multiplication.
  • Use hadamard for elementwise matrix multiplication.

Invalid shapes throw ArgumentError immediately. The library does not silently reshape, pad, or truncate data.

Shape And Data Operations

final a =arange(0, 12, columns:4);
print(a.transpose);
print(a.t);
print(a.reshape(4, 3));
print(a.slice(rowStart:1, rowEnd:3, columnStart:1));
print(a.sample(rowIndices: [0, 2], columnIndices: [1, 3]));
print(a.vstack(a));
print(a.hstack(a));
print(a.flatten());

Transforms and statistics:

final centered = a.mapColumns((column) => column - column.mean);
final selected = a.filterRows((row, index) => row.sum >10);
final sorted = a.sort((row) => row.sum, direction:SortDirection.desc);
print(a.mean);
print(a.meanByAxis(Axis.columns));
print(a.variance(Axis.rows));
print(a.deviation(Axis.rows));
print(a.norm());

Vector API

final x =vec([1, 2, 3]);
final y =vec([4, 5, 6]);
final x32 =vec32([1, 2, 3, 4]);
final y32 =vec32([5, 6, 7, 8]);
print(x.dot(y));
print(x.norm());
print(x.distanceTo(y, Distance.euclidean));
print(x.cosine(y));
print(x.normalize());
print(x.subvector(1));
print(x.unique());
print(x32.dot(y32));
print(x32 + y32);

Helper constructors:

final z =vecZeros(3);
final o =vecOnes(3);
final f =vecFull(3, 2);
final r =randVec(3, seed:1);
final range =vecRange(0, 10, step:2);
final line =vecLinspace(0, 1, 5);
final z32 =vecZeros32(4);
final o32 =vecOnes32(4);

Direct Linear Algebra

final a =mat([
[4, 7],
[2, 6],
]);
print(a.determinant);
print(a.inverse);
print(a.trace);
print(a.rank);
print(a.rref());
final rhs =mat([
[1],
[0],
]);
print(a.solve(rhs));

Square-matrix entry point:

final s =SquareMatrix.fromList([
[4, 7],
[2, 6],
]);
print(s.determinant);
print(s.inverse);
print(s.logAbsDeterminant);

Direct solve, determinant, and inverse use pivoting. Singular matrices throw at working precision. Ill-conditioned problems should pass explicit tolerances.

Decompositions And Advanced Algorithms

final a =mat([
[4, 1],
[1, 3],
]);
final lu = a.lu();
final qr = a.qr();
final cholesky = a.cholesky();
final eigen = a.eigenSymmetric();
final svd = a.svd();
print(lu.solve(mat([[1], [2]])));
print(qr.q * qr.r);
print(cholesky.lower * cholesky.lower.transpose);
print(eigen.values);
print(svd.singularValues);

High-level APIs:

final design =mat([
[1, 1],
[1, 2],
[1, 3],
]);
final observed =mat([
[1],
[2],
[2],
]);
print(design.leastSquares(observed));
print(design.pseudoInverse());
final pca = design.pca(components:1);
print(pca.components);
print(pca.explainedVariance);
APIApplies toTypical use
lu()square matricesDirect solve, determinant, pivoted factorization
qr()tall or full-rank square matricesLeast squares, orthogonalization
cholesky()symmetric positive definite matricesSPD solve and factorization
eigenSymmetric()real symmetric matricesFull eigenvalues and eigenvectors
eigen()symmetric full solve or power iterationHigh-level eigen interface
svd()rectangular or square matricesLow-rank analysis, pseudoinverse
pseudoInverse()rectangular or square matricesMoore-Penrose pseudoinverse
leastSquares(rhs)overdetermined or full-rank systemsLeast squares
pca()observation x feature matrixPrincipal component analysis

Matrix32 exposes the same high-level API names. Matrix-valued results keep 32-bit storage; scalar accumulations may use Dart double temporaries where the language requires it.

Iterative And Krylov Methods

final a =mat([
[4, 1],
[1, 3],
]);
final b =vec([1, 2]);
print(a.jacobi(b).solution);
print(a.gaussSeidel(b).solution);
print(a.sor(b, omega:1.1).solution);
print(a.conjugateGradient(b).solution);
print(a.gmres(b, restart:20).solution);
print(a.arnoldi(b, 2).hessenberg);
print(a.powerIteration().eigenvalue);

Result objects include convergence status, iteration count, residual norm, and the computed solution or eigenpair. Iterative methods are sensitive to initial guess, tolerance, conditioning, and expected convergence properties. Production code should set tolerance and maxIterations explicitly.

Sparse Matrices

final sparse =SparseMatrix.fromRows([
[1, 0, 2],
[0, 0, 3],
[4, 0, 0],
]);
print(sparse.nnz);
print(sparse.mv(vec([1, 2, 3])));
print(sparse.matmul(eye(3)));
print(sparse.transpose().toDense());
final fromTriplets =SparseMatrix.fromTriplets(3, 3, [
SparseEntry(0, 0, 1),
SparseEntry(0, 2, 2),
SparseEntry(2, 1, 4),
]);
final compact =mat([
[1, 0],
[0, 2],
]).toSparse();

Sparse matrices use CSR storage. The sparse API is separate from Matrix64 / Matrix32 dense kernels and is intended for matrices where nonzero entries are a small fraction of total entries.

Precision, Numerics, And Performance Policy

Recommended choices:

  • Use Matrix64 / Vector64 by default.
  • Use Matrix32 / Vector32 for large throughput-oriented workloads when float32 error is acceptable.
  • Set explicit tolerances for ill-conditioned matrices, rank decisions, near-singular systems, and iterative solvers.

Matrix32 and Vector32 use Float32x4 on suitable hot paths, including matrix multiplication, matrix-vector multiplication, vector-matrix multiplication, elementwise arithmetic, scalar arithmetic, dot products, sums, and norms. Matrix64 / Vector64 use Float64List and Float64x2-oriented kernels.

API scope:

  • Covers common dense-matrix workflows: construction, indexing, shape operations, arithmetic, statistics, JSON, decompositions, and solves.
  • Adds QR, SVD, pseudoinverse, least squares, PCA, iterative methods, Krylov methods, and CSR sparse matrices.
  • Does not include native BLAS/LAPACK, GPU execution, autodiff, distributed matrices, or full complex nonsymmetric eigensolvers.

Benchmark

Benchmark scripts use an AOT runner by default. JIT is for smoke/debug runs and must not be used for published performance claims.

Focused matrix multiplication comparison:

dart run test/benchmark_matmul.dart 256,512,1024 3 1 build/performance_report.md

Broader benchmark suite:

dart run test/benchmark_suite.dart 100,256,512,1000 3 1 build/benchmark_suite.md

The suite covers construction, scalar/elementwise operations, broadcasting, square and rectangular matrix multiplication, matrix-vector, vector-matrix, transpose, direct solves, vectors, sparse matrices, decompositions, least squares, statistics, and iterative/Krylov algorithms.

Generated reports:

Performance claims must name:

  • Dart SDK and command line.
  • AOT/JIT mode.
  • Precision: float32 or float64.
  • Matrix size and shape.
  • Compared package version and interface.
  • Iterations, warmups, and sample count.

Testing And Quality Gates

Routine checks:

dart format --output=none --set-exit-if-changed lib test
dart analyze
dart test

Optional performance regression:

MATRICES_PERF_REGRESSION=1 dart test test/performance_regression_test.dart

The test suite covers:

  • Construction, indexing, shape validation, and error paths.
  • Matrix64 / Matrix32 / Vector64 / Vector32 arithmetic.
  • Matrix multiplication against reference implementations.
  • LU, QR, Cholesky, determinant, inverse, and solve.
  • Symmetric eigen, SVD, pseudoinverse, least squares, PCA.
  • Jacobi, Gauss-Seidel, SOR, CG, GMRES, Arnoldi, power iteration.
  • CSR sparse construction, conversion, transpose, serialization, vector multiply, and dense multiply.
  • Randomized property tests, ill-conditioned Hilbert residuals, near-singular tolerance behavior, and float32 tolerances.

Recommended quality gates should at least include format checks, static analysis, tests, benchmark smoke, coverage artifacts, and API reference generation.

Error Handling

Matrices fails fast on shape and numerical preconditions:

mat([[1, 2]]) *mat([[1, 2]]); // ArgumentErrormat([[1, 2], [2, 4]]).inverse; // StateErrormat([[1, 2], [3, 4]]).cholesky(); // StateError

The package does not silently reshape, pad, truncate, or change precision.

About

Matrix Computing and Linear Algebra Library for Dart and Flutter

Topics

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Matrices

English | 中文文档

Matrices is a matrix computation and linear algebra library for Dart and Flutter. It focuses on high performance and script-style ergonomics, providing NumPy/MATLAB-like construction, indexing, broadcasting, and operator semantics, while keeping explicit 32-bit and 64-bit precision choices.

Project features:

  • Uses Dart's built-in SIMD APIs to accelerate computation, without depending on FFI or platform-specific binary runtimes.
  • Uses contiguous typed-data storage to avoid performance and semantic issues from nested-list structures.
  • Explicit Matrix64 / Matrix32 and Vector64 / Vector32 APIs.
  • Covers common dense matrices, CSR sparse matrices, direct decompositions, advanced decompositions, iterative methods, and Krylov methods.

Quick Start

import'package:matrices/matrices.dart';
voidmain() {
final a =mat([
[1, 2, 3],
[4, 5, 6],
]);
final b =mat([
[7, 8],
[9, 10],
[11, 12],
]);
final x =vec([1, 1, 1]);
print(a * b); // Matrix64 matrix multiplicationprint(a * x); // Matrix64 * Vector64print(a +1); // scalar broadcastingprint(a + x); // row-vector broadcastingprint(a.transpose);
}

Explicit 32-bit path:

final a32 =mat32([
[1, 2],
[3, 4],
]);
final x32 =vec32([1, 1]);
print(a32 * x32); // Vector32print(a32 * a32); // Matrix32print(a32.toFloat64()); // Matrix64

Type System

TypeStorageUse
Matrix64Float64ListDefault high-precision dense matrix
Matrix32Float32ListThroughput and memory-oriented dense matrix
Vector64Float64ListDefault high-precision vector
Vector32Float32ListThroughput-oriented float32 vector
Matrixtypedef Matrix = Matrix64Script-friendly short name
Vectortypedef Vector = Vector64Script-friendly short name

Matrix and Vector are 64-bit aliases, not separate implementations. Public APIs and documentation should prefer Matrix64 / Vector64 when precision must be explicit. Use Matrix32 / Vector32 for float32. The package does not silently downgrade precision.

Default constructors use full words, with short aliases for script-style code. Examples use short aliases for interactive ergonomics.

Default APIShort aliasReturn type
matrix([...])mat([...])Matrix64
matrix32([...])mat32([...])Matrix32
vector([...])vec([...])Vector64
vector32([...])vec32([...])Vector32

Helper constructors follow the same pattern, for example vectorZeros / vecZeros and vectorLinspace32 / vecLinspace32.

Construction

64-bit matrices:

final a =Matrix64([
[1, 2],
[3, 4],
]);
final b =Matrix([
[1, 2],
[3, 4],
]); // Matrix is an alias for Matrix64final z =zeros(2, 3);
final o =ones(2, 3);
final f =full(2, 3, 9);
final r =rand(2, 3, seed:42);
final i =eye(4);
final d =diag([1, 2, 3]);
final grid =arange(0, 12, columns:4);
final samples =linspace(0, 1, 5);

32-bit matrices:

final a32 =Matrix32([
[1, 2],
[3, 4],
]);
final z32 =zeros32(2, 3);
final o32 =ones32(2, 3);
final f32 =full32(2, 3, 1.5);
final r32 =rand32(1024, 1024, seed:7);
final i32 =eye32(4);
final d32 =diag32([1, 2, 3]);
final grid32 =arange32(0, 12, columns:4);
final samples32 =linspace32(0, 1, 5);

Other constructors:

final fromRows =Matrix64.fromRows([[1, 2], [3, 4]]);
final fromColumns =Matrix64.fromColumns([[1, 3], [2, 4]]);
final fromFlat =Matrix64.fromFlat([1, 2, 3, 4], 2, 2);
final fromBytes =Matrix64.fromByteData(
Float64List.fromList([1, 2, 3, 4]).buffer.asByteData(),
2,
2,
);
final spd =Matrix64.randomSPD(4, seed:1);

Indexing, Views, And Conversion

final a =arange(0, 9, columns:3);
print(a(1, 2)); // element accessprint(a[1][2]); // row view accessprint(a.row(0)); // Vector64print(a.column(1)); // Vector64
a.set(0, 0, 99);
a[1][1] =42;
final rows = a.toRows();
final values = a.values; // Float64List copyfinal unsafe = a.unsafeValuesView; // internal storage view for advanced usefinal json = a.toJson();
final restored =Matrix64.fromJson(json);

Rows are fixed-length views. Vector64 and Vector32 are fixed-length linear algebra objects that implement Iterable<double>; they are not growable List<double> objects.

Arithmetic Semantics

final a =mat([
[1, 2],
[3, 4],
]);
final b =mat([
[5, 6],
[7, 8],
]);
final x =vec([1, 1]);
print(a + b); // elementwise additionprint(a -1); // scalar broadcastingprint(a *2); // scalar multiplicationprint(a * b); // matrix multiplicationprint(a * x); // matrix-vector multiplicationprint(x * a); // vector-matrix multiplicationprint(a + x); // row-vector broadcastingprint(a.hadamard(b)); // Hadamard elementwise multiplicationprint(a /2);

The meaning of * depends on the right-hand side:

  • matrix * matrix is matrix multiplication.
  • matrix * vector is matrix-vector multiplication.
  • vector * matrix is row-vector matrix multiplication.
  • matrix * number and vector * number are scalar multiplication.
  • Use hadamard for elementwise matrix multiplication.

Invalid shapes throw ArgumentError immediately. The library does not silently reshape, pad, or truncate data.

Shape And Data Operations

final a =arange(0, 12, columns:4);
print(a.transpose);
print(a.t);
print(a.reshape(4, 3));
print(a.slice(rowStart:1, rowEnd:3, columnStart:1));
print(a.sample(rowIndices: [0, 2], columnIndices: [1, 3]));
print(a.vstack(a));
print(a.hstack(a));
print(a.flatten());

Transforms and statistics:

final centered = a.mapColumns((column) => column - column.mean);
final selected = a.filterRows((row, index) => row.sum >10);
final sorted = a.sort((row) => row.sum, direction:SortDirection.desc);
print(a.mean);
print(a.meanByAxis(Axis.columns));
print(a.variance(Axis.rows));
print(a.deviation(Axis.rows));
print(a.norm());

Vector API

final x =vec([1, 2, 3]);
final y =vec([4, 5, 6]);
final x32 =vec32([1, 2, 3, 4]);
final y32 =vec32([5, 6, 7, 8]);
print(x.dot(y));
print(x.norm());
print(x.distanceTo(y, Distance.euclidean));
print(x.cosine(y));
print(x.normalize());
print(x.subvector(1));
print(x.unique());
print(x32.dot(y32));
print(x32 + y32);

Helper constructors:

final z =vecZeros(3);
final o =vecOnes(3);
final f =vecFull(3, 2);
final r =randVec(3, seed:1);
final range =vecRange(0, 10, step:2);
final line =vecLinspace(0, 1, 5);
final z32 =vecZeros32(4);
final o32 =vecOnes32(4);

Direct Linear Algebra

final a =mat([
[4, 7],
[2, 6],
]);
print(a.determinant);
print(a.inverse);
print(a.trace);
print(a.rank);
print(a.rref());
final rhs =mat([
[1],
[0],
]);
print(a.solve(rhs));

Square-matrix entry point:

final s =SquareMatrix.fromList([
[4, 7],
[2, 6],
]);
print(s.determinant);
print(s.inverse);
print(s.logAbsDeterminant);

Direct solve, determinant, and inverse use pivoting. Singular matrices throw at working precision. Ill-conditioned problems should pass explicit tolerances.

Decompositions And Advanced Algorithms

final a =mat([
[4, 1],
[1, 3],
]);
final lu = a.lu();
final qr = a.qr();
final cholesky = a.cholesky();
final eigen = a.eigenSymmetric();
final svd = a.svd();
print(lu.solve(mat([[1], [2]])));
print(qr.q * qr.r);
print(cholesky.lower * cholesky.lower.transpose);
print(eigen.values);
print(svd.singularValues);

High-level APIs:

final design =mat([
[1, 1],
[1, 2],
[1, 3],
]);
final observed =mat([
[1],
[2],
[2],
]);
print(design.leastSquares(observed));
print(design.pseudoInverse());
final pca = design.pca(components:1);
print(pca.components);
print(pca.explainedVariance);
APIApplies toTypical use
lu()square matricesDirect solve, determinant, pivoted factorization
qr()tall or full-rank square matricesLeast squares, orthogonalization
cholesky()symmetric positive definite matricesSPD solve and factorization
eigenSymmetric()real symmetric matricesFull eigenvalues and eigenvectors
eigen()symmetric full solve or power iterationHigh-level eigen interface
svd()rectangular or square matricesLow-rank analysis, pseudoinverse
pseudoInverse()rectangular or square matricesMoore-Penrose pseudoinverse
leastSquares(rhs)overdetermined or full-rank systemsLeast squares
pca()observation x feature matrixPrincipal component analysis

Matrix32 exposes the same high-level API names. Matrix-valued results keep 32-bit storage; scalar accumulations may use Dart double temporaries where the language requires it.

Iterative And Krylov Methods

final a =mat([
[4, 1],
[1, 3],
]);
final b =vec([1, 2]);
print(a.jacobi(b).solution);
print(a.gaussSeidel(b).solution);
print(a.sor(b, omega:1.1).solution);
print(a.conjugateGradient(b).solution);
print(a.gmres(b, restart:20).solution);
print(a.arnoldi(b, 2).hessenberg);
print(a.powerIteration().eigenvalue);

Result objects include convergence status, iteration count, residual norm, and the computed solution or eigenpair. Iterative methods are sensitive to initial guess, tolerance, conditioning, and expected convergence properties. Production code should set tolerance and maxIterations explicitly.

Sparse Matrices

final sparse =SparseMatrix.fromRows([
[1, 0, 2],
[0, 0, 3],
[4, 0, 0],
]);
print(sparse.nnz);
print(sparse.mv(vec([1, 2, 3])));
print(sparse.matmul(eye(3)));
print(sparse.transpose().toDense());
final fromTriplets =SparseMatrix.fromTriplets(3, 3, [
SparseEntry(0, 0, 1),
SparseEntry(0, 2, 2),
SparseEntry(2, 1, 4),
]);
final compact =mat([
[1, 0],
[0, 2],
]).toSparse();

Sparse matrices use CSR storage. The sparse API is separate from Matrix64 / Matrix32 dense kernels and is intended for matrices where nonzero entries are a small fraction of total entries.

Precision, Numerics, And Performance Policy

Recommended choices:

  • Use Matrix64 / Vector64 by default.
  • Use Matrix32 / Vector32 for large throughput-oriented workloads when float32 error is acceptable.
  • Set explicit tolerances for ill-conditioned matrices, rank decisions, near-singular systems, and iterative solvers.

Matrix32 and Vector32 use Float32x4 on suitable hot paths, including matrix multiplication, matrix-vector multiplication, vector-matrix multiplication, elementwise arithmetic, scalar arithmetic, dot products, sums, and norms. Matrix64 / Vector64 use Float64List and Float64x2-oriented kernels.

API scope:

  • Covers common dense-matrix workflows: construction, indexing, shape operations, arithmetic, statistics, JSON, decompositions, and solves.
  • Adds QR, SVD, pseudoinverse, least squares, PCA, iterative methods, Krylov methods, and CSR sparse matrices.
  • Does not include native BLAS/LAPACK, GPU execution, autodiff, distributed matrices, or full complex nonsymmetric eigensolvers.

Benchmark

Benchmark scripts use an AOT runner by default. JIT is for smoke/debug runs and must not be used for published performance claims.

Focused matrix multiplication comparison:

dart run test/benchmark_matmul.dart 256,512,1024 3 1 build/performance_report.md

Broader benchmark suite:

dart run test/benchmark_suite.dart 100,256,512,1000 3 1 build/benchmark_suite.md

The suite covers construction, scalar/elementwise operations, broadcasting, square and rectangular matrix multiplication, matrix-vector, vector-matrix, transpose, direct solves, vectors, sparse matrices, decompositions, least squares, statistics, and iterative/Krylov algorithms.

Generated reports:

Performance claims must name:

  • Dart SDK and command line.
  • AOT/JIT mode.
  • Precision: float32 or float64.
  • Matrix size and shape.
  • Compared package version and interface.
  • Iterations, warmups, and sample count.

Testing And Quality Gates

Routine checks:

dart format --output=none --set-exit-if-changed lib test
dart analyze
dart test

Optional performance regression:

MATRICES_PERF_REGRESSION=1 dart test test/performance_regression_test.dart

The test suite covers:

  • Construction, indexing, shape validation, and error paths.
  • Matrix64 / Matrix32 / Vector64 / Vector32 arithmetic.
  • Matrix multiplication against reference implementations.
  • LU, QR, Cholesky, determinant, inverse, and solve.
  • Symmetric eigen, SVD, pseudoinverse, least squares, PCA.
  • Jacobi, Gauss-Seidel, SOR, CG, GMRES, Arnoldi, power iteration.
  • CSR sparse construction, conversion, transpose, serialization, vector multiply, and dense multiply.
  • Randomized property tests, ill-conditioned Hilbert residuals, near-singular tolerance behavior, and float32 tolerances.

Recommended quality gates should at least include format checks, static analysis, tests, benchmark smoke, coverage artifacts, and API reference generation.

Error Handling

Matrices fails fast on shape and numerical preconditions:

mat([[1, 2]]) *mat([[1, 2]]); // ArgumentErrormat([[1, 2], [2, 4]]).inverse; // StateErrormat([[1, 2], [3, 4]]).cholesky(); // StateError

The package does not silently reshape, pad, truncate, or change precision.

About

Matrix Computing and Linear Algebra Library for Dart and Flutter

Topics

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length \u003e 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Matrices

English | 中文文档

Matrices is a matrix computation and linear algebra library for Dart and Flutter. It focuses on high performance and script-style ergonomics, providing NumPy/MATLAB-like construction, indexing, broadcasting, and operator semantics, while keeping explicit 32-bit and 64-bit precision choices.

Project features:

  • Uses Dart's built-in SIMD APIs to accelerate computation, without depending on FFI or platform-specific binary runtimes.
  • Uses contiguous typed-data storage to avoid performance and semantic issues from nested-list structures.
  • Explicit Matrix64 / Matrix32 and Vector64 / Vector32 APIs.
  • Covers common dense matrices, CSR sparse matrices, direct decompositions, advanced decompositions, iterative methods, and Krylov methods.

Quick Start

import'package:matrices/matrices.dart';
voidmain() {
final a =mat([
[1, 2, 3],
[4, 5, 6],
]);
final b =mat([
[7, 8],
[9, 10],
[11, 12],
]);
final x =vec([1, 1, 1]);
print(a * b); // Matrix64 matrix multiplicationprint(a * x); // Matrix64 * Vector64print(a +1); // scalar broadcastingprint(a + x); // row-vector broadcastingprint(a.transpose);
}

Explicit 32-bit path:

final a32 =mat32([
[1, 2],
[3, 4],
]);
final x32 =vec32([1, 1]);
print(a32 * x32); // Vector32print(a32 * a32); // Matrix32print(a32.toFloat64()); // Matrix64

Type System

TypeStorageUse
Matrix64Float64ListDefault high-precision dense matrix
Matrix32Float32ListThroughput and memory-oriented dense matrix
Vector64Float64ListDefault high-precision vector
Vector32Float32ListThroughput-oriented float32 vector
Matrixtypedef Matrix = Matrix64Script-friendly short name
Vectortypedef Vector = Vector64Script-friendly short name

Matrix and Vector are 64-bit aliases, not separate implementations. Public APIs and documentation should prefer Matrix64 / Vector64 when precision must be explicit. Use Matrix32 / Vector32 for float32. The package does not silently downgrade precision.

Default constructors use full words, with short aliases for script-style code. Examples use short aliases for interactive ergonomics.

Default APIShort aliasReturn type
matrix([...])mat([...])Matrix64
matrix32([...])mat32([...])Matrix32
vector([...])vec([...])Vector64
vector32([...])vec32([...])Vector32

Helper constructors follow the same pattern, for example vectorZeros / vecZeros and vectorLinspace32 / vecLinspace32.

Construction

64-bit matrices:

final a =Matrix64([
[1, 2],
[3, 4],
]);
final b =Matrix([
[1, 2],
[3, 4],
]); // Matrix is an alias for Matrix64final z =zeros(2, 3);
final o =ones(2, 3);
final f =full(2, 3, 9);
final r =rand(2, 3, seed:42);
final i =eye(4);
final d =diag([1, 2, 3]);
final grid =arange(0, 12, columns:4);
final samples =linspace(0, 1, 5);

32-bit matrices:

final a32 =Matrix32([
[1, 2],
[3, 4],
]);
final z32 =zeros32(2, 3);
final o32 =ones32(2, 3);
final f32 =full32(2, 3, 1.5);
final r32 =rand32(1024, 1024, seed:7);
final i32 =eye32(4);
final d32 =diag32([1, 2, 3]);
final grid32 =arange32(0, 12, columns:4);
final samples32 =linspace32(0, 1, 5);

Other constructors:

final fromRows =Matrix64.fromRows([[1, 2], [3, 4]]);
final fromColumns =Matrix64.fromColumns([[1, 3], [2, 4]]);
final fromFlat =Matrix64.fromFlat([1, 2, 3, 4], 2, 2);
final fromBytes =Matrix64.fromByteData(
Float64List.fromList([1, 2, 3, 4]).buffer.asByteData(),
2,
2,
);
final spd =Matrix64.randomSPD(4, seed:1);

Indexing, Views, And Conversion

final a =arange(0, 9, columns:3);
print(a(1, 2)); // element accessprint(a[1][2]); // row view accessprint(a.row(0)); // Vector64print(a.column(1)); // Vector64
a.set(0, 0, 99);
a[1][1] =42;
final rows = a.toRows();
final values = a.values; // Float64List copyfinal unsafe = a.unsafeValuesView; // internal storage view for advanced usefinal json = a.toJson();
final restored =Matrix64.fromJson(json);

Rows are fixed-length views. Vector64 and Vector32 are fixed-length linear algebra objects that implement Iterable<double>; they are not growable List<double> objects.

Arithmetic Semantics

final a =mat([
[1, 2],
[3, 4],
]);
final b =mat([
[5, 6],
[7, 8],
]);
final x =vec([1, 1]);
print(a + b); // elementwise additionprint(a -1); // scalar broadcastingprint(a *2); // scalar multiplicationprint(a * b); // matrix multiplicationprint(a * x); // matrix-vector multiplicationprint(x * a); // vector-matrix multiplicationprint(a + x); // row-vector broadcastingprint(a.hadamard(b)); // Hadamard elementwise multiplicationprint(a /2);

The meaning of * depends on the right-hand side:

  • matrix * matrix is matrix multiplication.
  • matrix * vector is matrix-vector multiplication.
  • vector * matrix is row-vector matrix multiplication.
  • matrix * number and vector * number are scalar multiplication.
  • Use hadamard for elementwise matrix multiplication.

Invalid shapes throw ArgumentError immediately. The library does not silently reshape, pad, or truncate data.

Shape And Data Operations

final a =arange(0, 12, columns:4);
print(a.transpose);
print(a.t);
print(a.reshape(4, 3));
print(a.slice(rowStart:1, rowEnd:3, columnStart:1));
print(a.sample(rowIndices: [0, 2], columnIndices: [1, 3]));
print(a.vstack(a));
print(a.hstack(a));
print(a.flatten());

Transforms and statistics:

final centered = a.mapColumns((column) => column - column.mean);
final selected = a.filterRows((row, index) => row.sum >10);
final sorted = a.sort((row) => row.sum, direction:SortDirection.desc);
print(a.mean);
print(a.meanByAxis(Axis.columns));
print(a.variance(Axis.rows));
print(a.deviation(Axis.rows));
print(a.norm());

Vector API

final x =vec([1, 2, 3]);
final y =vec([4, 5, 6]);
final x32 =vec32([1, 2, 3, 4]);
final y32 =vec32([5, 6, 7, 8]);
print(x.dot(y));
print(x.norm());
print(x.distanceTo(y, Distance.euclidean));
print(x.cosine(y));
print(x.normalize());
print(x.subvector(1));
print(x.unique());
print(x32.dot(y32));
print(x32 + y32);

Helper constructors:

final z =vecZeros(3);
final o =vecOnes(3);
final f =vecFull(3, 2);
final r =randVec(3, seed:1);
final range =vecRange(0, 10, step:2);
final line =vecLinspace(0, 1, 5);
final z32 =vecZeros32(4);
final o32 =vecOnes32(4);

Direct Linear Algebra

final a =mat([
[4, 7],
[2, 6],
]);
print(a.determinant);
print(a.inverse);
print(a.trace);
print(a.rank);
print(a.rref());
final rhs =mat([
[1],
[0],
]);
print(a.solve(rhs));

Square-matrix entry point:

final s =SquareMatrix.fromList([
[4, 7],
[2, 6],
]);
print(s.determinant);
print(s.inverse);
print(s.logAbsDeterminant);

Direct solve, determinant, and inverse use pivoting. Singular matrices throw at working precision. Ill-conditioned problems should pass explicit tolerances.

Decompositions And Advanced Algorithms

final a =mat([
[4, 1],
[1, 3],
]);
final lu = a.lu();
final qr = a.qr();
final cholesky = a.cholesky();
final eigen = a.eigenSymmetric();
final svd = a.svd();
print(lu.solve(mat([[1], [2]])));
print(qr.q * qr.r);
print(cholesky.lower * cholesky.lower.transpose);
print(eigen.values);
print(svd.singularValues);

High-level APIs:

final design =mat([
[1, 1],
[1, 2],
[1, 3],
]);
final observed =mat([
[1],
[2],
[2],
]);
print(design.leastSquares(observed));
print(design.pseudoInverse());
final pca = design.pca(components:1);
print(pca.components);
print(pca.explainedVariance);
APIApplies toTypical use
lu()square matricesDirect solve, determinant, pivoted factorization
qr()tall or full-rank square matricesLeast squares, orthogonalization
cholesky()symmetric positive definite matricesSPD solve and factorization
eigenSymmetric()real symmetric matricesFull eigenvalues and eigenvectors
eigen()symmetric full solve or power iterationHigh-level eigen interface
svd()rectangular or square matricesLow-rank analysis, pseudoinverse
pseudoInverse()rectangular or square matricesMoore-Penrose pseudoinverse
leastSquares(rhs)overdetermined or full-rank systemsLeast squares
pca()observation x feature matrixPrincipal component analysis

Matrix32 exposes the same high-level API names. Matrix-valued results keep 32-bit storage; scalar accumulations may use Dart double temporaries where the language requires it.

Iterative And Krylov Methods

final a =mat([
[4, 1],
[1, 3],
]);
final b =vec([1, 2]);
print(a.jacobi(b).solution);
print(a.gaussSeidel(b).solution);
print(a.sor(b, omega:1.1).solution);
print(a.conjugateGradient(b).solution);
print(a.gmres(b, restart:20).solution);
print(a.arnoldi(b, 2).hessenberg);
print(a.powerIteration().eigenvalue);

Result objects include convergence status, iteration count, residual norm, and the computed solution or eigenpair. Iterative methods are sensitive to initial guess, tolerance, conditioning, and expected convergence properties. Production code should set tolerance and maxIterations explicitly.

Sparse Matrices

final sparse =SparseMatrix.fromRows([
[1, 0, 2],
[0, 0, 3],
[4, 0, 0],
]);
print(sparse.nnz);
print(sparse.mv(vec([1, 2, 3])));
print(sparse.matmul(eye(3)));
print(sparse.transpose().toDense());
final fromTriplets =SparseMatrix.fromTriplets(3, 3, [
SparseEntry(0, 0, 1),
SparseEntry(0, 2, 2),
SparseEntry(2, 1, 4),
]);
final compact =mat([
[1, 0],
[0, 2],
]).toSparse();

Sparse matrices use CSR storage. The sparse API is separate from Matrix64 / Matrix32 dense kernels and is intended for matrices where nonzero entries are a small fraction of total entries.

Precision, Numerics, And Performance Policy

Recommended choices:

  • Use Matrix64 / Vector64 by default.
  • Use Matrix32 / Vector32 for large throughput-oriented workloads when float32 error is acceptable.
  • Set explicit tolerances for ill-conditioned matrices, rank decisions, near-singular systems, and iterative solvers.

Matrix32 and Vector32 use Float32x4 on suitable hot paths, including matrix multiplication, matrix-vector multiplication, vector-matrix multiplication, elementwise arithmetic, scalar arithmetic, dot products, sums, and norms. Matrix64 / Vector64 use Float64List and Float64x2-oriented kernels.

API scope:

  • Covers common dense-matrix workflows: construction, indexing, shape operations, arithmetic, statistics, JSON, decompositions, and solves.
  • Adds QR, SVD, pseudoinverse, least squares, PCA, iterative methods, Krylov methods, and CSR sparse matrices.
  • Does not include native BLAS/LAPACK, GPU execution, autodiff, distributed matrices, or full complex nonsymmetric eigensolvers.

Benchmark

Benchmark scripts use an AOT runner by default. JIT is for smoke/debug runs and must not be used for published performance claims.

Focused matrix multiplication comparison:

dart run test/benchmark_matmul.dart 256,512,1024 3 1 build/performance_report.md

Broader benchmark suite:

dart run test/benchmark_suite.dart 100,256,512,1000 3 1 build/benchmark_suite.md

The suite covers construction, scalar/elementwise operations, broadcasting, square and rectangular matrix multiplication, matrix-vector, vector-matrix, transpose, direct solves, vectors, sparse matrices, decompositions, least squares, statistics, and iterative/Krylov algorithms.

Generated reports:

Performance claims must name:

  • Dart SDK and command line.
  • AOT/JIT mode.
  • Precision: float32 or float64.
  • Matrix size and shape.
  • Compared package version and interface.
  • Iterations, warmups, and sample count.

Testing And Quality Gates

Routine checks:

dart format --output=none --set-exit-if-changed lib test
dart analyze
dart test

Optional performance regression:

MATRICES_PERF_REGRESSION=1 dart test test/performance_regression_test.dart

The test suite covers:

  • Construction, indexing, shape validation, and error paths.
  • Matrix64 / Matrix32 / Vector64 / Vector32 arithmetic.
  • Matrix multiplication against reference implementations.
  • LU, QR, Cholesky, determinant, inverse, and solve.
  • Symmetric eigen, SVD, pseudoinverse, least squares, PCA.
  • Jacobi, Gauss-Seidel, SOR, CG, GMRES, Arnoldi, power iteration.
  • CSR sparse construction, conversion, transpose, serialization, vector multiply, and dense multiply.
  • Randomized property tests, ill-conditioned Hilbert residuals, near-singular tolerance behavior, and float32 tolerances.

Recommended quality gates should at least include format checks, static analysis, tests, benchmark smoke, coverage artifacts, and API reference generation.

Error Handling

Matrices fails fast on shape and numerical preconditions:

mat([[1, 2]]) *mat([[1, 2]]); // ArgumentErrormat([[1, 2], [2, 4]]).inverse; // StateErrormat([[1, 2], [3, 4]]).cholesky(); // StateError

The package does not silently reshape, pad, truncate, or change precision.

About

Matrix Computing and Linear Algebra Library for Dart and Flutter

Topics

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

Matrices

English | 中文文档

Matrices is a matrix computation and linear algebra library for Dart and Flutter. It focuses on high performance and script-style ergonomics, providing NumPy/MATLAB-like construction, indexing, broadcasting, and operator semantics, while keeping explicit 32-bit and 64-bit precision choices.

Project features:

  • Uses Dart's built-in SIMD APIs to accelerate computation, without depending on FFI or platform-specific binary runtimes.
  • Uses contiguous typed-data storage to avoid performance and semantic issues from nested-list structures.
  • Explicit Matrix64 / Matrix32 and Vector64 / Vector32 APIs.
  • Covers common dense matrices, CSR sparse matrices, direct decompositions, advanced decompositions, iterative methods, and Krylov methods.

Quick Start

import'package:matrices/matrices.dart';
voidmain() {
final a =mat([
[1, 2, 3],
[4, 5, 6],
]);
final b =mat([
[7, 8],
[9, 10],
[11, 12],
]);
final x =vec([1, 1, 1]);
print(a * b); // Matrix64 matrix multiplicationprint(a * x); // Matrix64 * Vector64print(a +1); // scalar broadcastingprint(a + x); // row-vector broadcastingprint(a.transpose);
}

Explicit 32-bit path:

final a32 =mat32([
[1, 2],
[3, 4],
]);
final x32 =vec32([1, 1]);
print(a32 * x32); // Vector32print(a32 * a32); // Matrix32print(a32.toFloat64()); // Matrix64

Type System

TypeStorageUse
Matrix64Float64ListDefault high-precision dense matrix
Matrix32Float32ListThroughput and memory-oriented dense matrix
Vector64Float64ListDefault high-precision vector
Vector32Float32ListThroughput-oriented float32 vector
Matrixtypedef Matrix = Matrix64Script-friendly short name
Vectortypedef Vector = Vector64Script-friendly short name

Matrix and Vector are 64-bit aliases, not separate implementations. Public APIs and documentation should prefer Matrix64 / Vector64 when precision must be explicit. Use Matrix32 / Vector32 for float32. The package does not silently downgrade precision.

Default constructors use full words, with short aliases for script-style code. Examples use short aliases for interactive ergonomics.

Default APIShort aliasReturn type
matrix([...])mat([...])Matrix64
matrix32([...])mat32([...])Matrix32
vector([...])vec([...])Vector64
vector32([...])vec32([...])Vector32

Helper constructors follow the same pattern, for example vectorZeros / vecZeros and vectorLinspace32 / vecLinspace32.

Construction

64-bit matrices:

final a =Matrix64([
[1, 2],
[3, 4],
]);
final b =Matrix([
[1, 2],
[3, 4],
]); // Matrix is an alias for Matrix64final z =zeros(2, 3);
final o =ones(2, 3);
final f =full(2, 3, 9);
final r =rand(2, 3, seed:42);
final i =eye(4);
final d =diag([1, 2, 3]);
final grid =arange(0, 12, columns:4);
final samples =linspace(0, 1, 5);

32-bit matrices:

final a32 =Matrix32([
[1, 2],
[3, 4],
]);
final z32 =zeros32(2, 3);
final o32 =ones32(2, 3);
final f32 =full32(2, 3, 1.5);
final r32 =rand32(1024, 1024, seed:7);
final i32 =eye32(4);
final d32 =diag32([1, 2, 3]);
final grid32 =arange32(0, 12, columns:4);
final samples32 =linspace32(0, 1, 5);

Other constructors:

final fromRows =Matrix64.fromRows([[1, 2], [3, 4]]);
final fromColumns =Matrix64.fromColumns([[1, 3], [2, 4]]);
final fromFlat =Matrix64.fromFlat([1, 2, 3, 4], 2, 2);
final fromBytes =Matrix64.fromByteData(
Float64List.fromList([1, 2, 3, 4]).buffer.asByteData(),
2,
2,
);
final spd =Matrix64.randomSPD(4, seed:1);

Indexing, Views, And Conversion

final a =arange(0, 9, columns:3);
print(a(1, 2)); // element accessprint(a[1][2]); // row view accessprint(a.row(0)); // Vector64print(a.column(1)); // Vector64
a.set(0, 0, 99);
a[1][1] =42;
final rows = a.toRows();
final values = a.values; // Float64List copyfinal unsafe = a.unsafeValuesView; // internal storage view for advanced usefinal json = a.toJson();
final restored =Matrix64.fromJson(json);

Rows are fixed-length views. Vector64 and Vector32 are fixed-length linear algebra objects that implement Iterable<double>; they are not growable List<double> objects.

Arithmetic Semantics

final a =mat([
[1, 2],
[3, 4],
]);
final b =mat([
[5, 6],
[7, 8],
]);
final x =vec([1, 1]);
print(a + b); // elementwise additionprint(a -1); // scalar broadcastingprint(a *2); // scalar multiplicationprint(a * b); // matrix multiplicationprint(a * x); // matrix-vector multiplicationprint(x * a); // vector-matrix multiplicationprint(a + x); // row-vector broadcastingprint(a.hadamard(b)); // Hadamard elementwise multiplicationprint(a /2);

The meaning of * depends on the right-hand side:

  • matrix * matrix is matrix multiplication.
  • matrix * vector is matrix-vector multiplication.
  • vector * matrix is row-vector matrix multiplication.
  • matrix * number and vector * number are scalar multiplication.
  • Use hadamard for elementwise matrix multiplication.

Invalid shapes throw ArgumentError immediately. The library does not silently reshape, pad, or truncate data.

Shape And Data Operations

final a =arange(0, 12, columns:4);
print(a.transpose);
print(a.t);
print(a.reshape(4, 3));
print(a.slice(rowStart:1, rowEnd:3, columnStart:1));
print(a.sample(rowIndices: [0, 2], columnIndices: [1, 3]));
print(a.vstack(a));
print(a.hstack(a));
print(a.flatten());

Transforms and statistics:

final centered = a.mapColumns((column) => column - column.mean);
final selected = a.filterRows((row, index) => row.sum >10);
final sorted = a.sort((row) => row.sum, direction:SortDirection.desc);
print(a.mean);
print(a.meanByAxis(Axis.columns));
print(a.variance(Axis.rows));
print(a.deviation(Axis.rows));
print(a.norm());

Vector API

final x =vec([1, 2, 3]);
final y =vec([4, 5, 6]);
final x32 =vec32([1, 2, 3, 4]);
final y32 =vec32([5, 6, 7, 8]);
print(x.dot(y));
print(x.norm());
print(x.distanceTo(y, Distance.euclidean));
print(x.cosine(y));
print(x.normalize());
print(x.subvector(1));
print(x.unique());
print(x32.dot(y32));
print(x32 + y32);

Helper constructors:

final z =vecZeros(3);
final o =vecOnes(3);
final f =vecFull(3, 2);
final r =randVec(3, seed:1);
final range =vecRange(0, 10, step:2);
final line =vecLinspace(0, 1, 5);
final z32 =vecZeros32(4);
final o32 =vecOnes32(4);

Direct Linear Algebra

final a =mat([
[4, 7],
[2, 6],
]);
print(a.determinant);
print(a.inverse);
print(a.trace);
print(a.rank);
print(a.rref());
final rhs =mat([
[1],
[0],
]);
print(a.solve(rhs));

Square-matrix entry point:

final s =SquareMatrix.fromList([
[4, 7],
[2, 6],
]);
print(s.determinant);
print(s.inverse);
print(s.logAbsDeterminant);

Direct solve, determinant, and inverse use pivoting. Singular matrices throw at working precision. Ill-conditioned problems should pass explicit tolerances.

Decompositions And Advanced Algorithms

final a =mat([
[4, 1],
[1, 3],
]);
final lu = a.lu();
final qr = a.qr();
final cholesky = a.cholesky();
final eigen = a.eigenSymmetric();
final svd = a.svd();
print(lu.solve(mat([[1], [2]])));
print(qr.q * qr.r);
print(cholesky.lower * cholesky.lower.transpose);
print(eigen.values);
print(svd.singularValues);

High-level APIs:

final design =mat([
[1, 1],
[1, 2],
[1, 3],
]);
final observed =mat([
[1],
[2],
[2],
]);
print(design.leastSquares(observed));
print(design.pseudoInverse());
final pca = design.pca(components:1);
print(pca.components);
print(pca.explainedVariance);
APIApplies toTypical use
lu()square matricesDirect solve, determinant, pivoted factorization
qr()tall or full-rank square matricesLeast squares, orthogonalization
cholesky()symmetric positive definite matricesSPD solve and factorization
eigenSymmetric()real symmetric matricesFull eigenvalues and eigenvectors
eigen()symmetric full solve or power iterationHigh-level eigen interface
svd()rectangular or square matricesLow-rank analysis, pseudoinverse
pseudoInverse()rectangular or square matricesMoore-Penrose pseudoinverse
leastSquares(rhs)overdetermined or full-rank systemsLeast squares
pca()observation x feature matrixPrincipal component analysis

Matrix32 exposes the same high-level API names. Matrix-valued results keep 32-bit storage; scalar accumulations may use Dart double temporaries where the language requires it.

Iterative And Krylov Methods

final a =mat([
[4, 1],
[1, 3],
]);
final b =vec([1, 2]);
print(a.jacobi(b).solution);
print(a.gaussSeidel(b).solution);
print(a.sor(b, omega:1.1).solution);
print(a.conjugateGradient(b).solution);
print(a.gmres(b, restart:20).solution);
print(a.arnoldi(b, 2).hessenberg);
print(a.powerIteration().eigenvalue);

Result objects include convergence status, iteration count, residual norm, and the computed solution or eigenpair. Iterative methods are sensitive to initial guess, tolerance, conditioning, and expected convergence properties. Production code should set tolerance and maxIterations explicitly.

Sparse Matrices

final sparse =SparseMatrix.fromRows([
[1, 0, 2],
[0, 0, 3],
[4, 0, 0],
]);
print(sparse.nnz);
print(sparse.mv(vec([1, 2, 3])));
print(sparse.matmul(eye(3)));
print(sparse.transpose().toDense());
final fromTriplets =SparseMatrix.fromTriplets(3, 3, [
SparseEntry(0, 0, 1),
SparseEntry(0, 2, 2),
SparseEntry(2, 1, 4),
]);
final compact =mat([
[1, 0],
[0, 2],
]).toSparse();

Sparse matrices use CSR storage. The sparse API is separate from Matrix64 / Matrix32 dense kernels and is intended for matrices where nonzero entries are a small fraction of total entries.

Precision, Numerics, And Performance Policy

Recommended choices:

  • Use Matrix64 / Vector64 by default.
  • Use Matrix32 / Vector32 for large throughput-oriented workloads when float32 error is acceptable.
  • Set explicit tolerances for ill-conditioned matrices, rank decisions, near-singular systems, and iterative solvers.

Matrix32 and Vector32 use Float32x4 on suitable hot paths, including matrix multiplication, matrix-vector multiplication, vector-matrix multiplication, elementwise arithmetic, scalar arithmetic, dot products, sums, and norms. Matrix64 / Vector64 use Float64List and Float64x2-oriented kernels.

API scope:

  • Covers common dense-matrix workflows: construction, indexing, shape operations, arithmetic, statistics, JSON, decompositions, and solves.
  • Adds QR, SVD, pseudoinverse, least squares, PCA, iterative methods, Krylov methods, and CSR sparse matrices.
  • Does not include native BLAS/LAPACK, GPU execution, autodiff, distributed matrices, or full complex nonsymmetric eigensolvers.

Benchmark

Benchmark scripts use an AOT runner by default. JIT is for smoke/debug runs and must not be used for published performance claims.

Focused matrix multiplication comparison:

dart run test/benchmark_matmul.dart 256,512,1024 3 1 build/performance_report.md

Broader benchmark suite:

dart run test/benchmark_suite.dart 100,256,512,1000 3 1 build/benchmark_suite.md

The suite covers construction, scalar/elementwise operations, broadcasting, square and rectangular matrix multiplication, matrix-vector, vector-matrix, transpose, direct solves, vectors, sparse matrices, decompositions, least squares, statistics, and iterative/Krylov algorithms.

Generated reports:

Performance claims must name:

  • Dart SDK and command line.
  • AOT/JIT mode.
  • Precision: float32 or float64.
  • Matrix size and shape.
  • Compared package version and interface.
  • Iterations, warmups, and sample count.

Testing And Quality Gates

Routine checks:

dart format --output=none --set-exit-if-changed lib test
dart analyze
dart test

Optional performance regression:

MATRICES_PERF_REGRESSION=1 dart test test/performance_regression_test.dart

The test suite covers:

  • Construction, indexing, shape validation, and error paths.
  • Matrix64 / Matrix32 / Vector64 / Vector32 arithmetic.
  • Matrix multiplication against reference implementations.
  • LU, QR, Cholesky, determinant, inverse, and solve.
  • Symmetric eigen, SVD, pseudoinverse, least squares, PCA.
  • Jacobi, Gauss-Seidel, SOR, CG, GMRES, Arnoldi, power iteration.
  • CSR sparse construction, conversion, transpose, serialization, vector multiply, and dense multiply.
  • Randomized property tests, ill-conditioned Hilbert residuals, near-singular tolerance behavior, and float32 tolerances.

Recommended quality gates should at least include format checks, static analysis, tests, benchmark smoke, coverage artifacts, and API reference generation.

Error Handling

Matrices fails fast on shape and numerical preconditions:

mat([[1, 2]]) *mat([[1, 2]]); // ArgumentErrormat([[1, 2], [2, 4]]).inverse; // StateErrormat([[1, 2], [3, 4]]).cholesky(); // StateError

The package does not silently reshape, pad, truncate, or change precision.

About

Matrix Computing and Linear Algebra Library for Dart and Flutter

Topics

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Matrices

English | 中文文档

Matrices is a matrix computation and linear algebra library for Dart and Flutter. It focuses on high performance and script-style ergonomics, providing NumPy/MATLAB-like construction, indexing, broadcasting, and operator semantics, while keeping explicit 32-bit and 64-bit precision choices.

Project features:

  • Uses Dart's built-in SIMD APIs to accelerate computation, without depending on FFI or platform-specific binary runtimes.
  • Uses contiguous typed-data storage to avoid performance and semantic issues from nested-list structures.
  • Explicit Matrix64 / Matrix32 and Vector64 / Vector32 APIs.
  • Covers common dense matrices, CSR sparse matrices, direct decompositions, advanced decompositions, iterative methods, and Krylov methods.

Quick Start

import'package:matrices/matrices.dart';
voidmain() {
final a =mat([
[1, 2, 3],
[4, 5, 6],
]);
final b =mat([
[7, 8],
[9, 10],
[11, 12],
]);
final x =vec([1, 1, 1]);
print(a * b); // Matrix64 matrix multiplicationprint(a * x); // Matrix64 * Vector64print(a +1); // scalar broadcastingprint(a + x); // row-vector broadcastingprint(a.transpose);
}

Explicit 32-bit path:

final a32 =mat32([
[1, 2],
[3, 4],
]);
final x32 =vec32([1, 1]);
print(a32 * x32); // Vector32print(a32 * a32); // Matrix32print(a32.toFloat64()); // Matrix64

Type System

TypeStorageUse
Matrix64Float64ListDefault high-precision dense matrix
Matrix32Float32ListThroughput and memory-oriented dense matrix
Vector64Float64ListDefault high-precision vector
Vector32Float32ListThroughput-oriented float32 vector
Matrixtypedef Matrix = Matrix64Script-friendly short name
Vectortypedef Vector = Vector64Script-friendly short name

Matrix and Vector are 64-bit aliases, not separate implementations. Public APIs and documentation should prefer Matrix64 / Vector64 when precision must be explicit. Use Matrix32 / Vector32 for float32. The package does not silently downgrade precision.

Default constructors use full words, with short aliases for script-style code. Examples use short aliases for interactive ergonomics.

Default APIShort aliasReturn type
matrix([...])mat([...])Matrix64
matrix32([...])mat32([...])Matrix32
vector([...])vec([...])Vector64
vector32([...])vec32([...])Vector32

Helper constructors follow the same pattern, for example vectorZeros / vecZeros and vectorLinspace32 / vecLinspace32.

Construction

64-bit matrices:

final a =Matrix64([
[1, 2],
[3, 4],
]);
final b =Matrix([
[1, 2],
[3, 4],
]); // Matrix is an alias for Matrix64final z =zeros(2, 3);
final o =ones(2, 3);
final f =full(2, 3, 9);
final r =rand(2, 3, seed:42);
final i =eye(4);
final d =diag([1, 2, 3]);
final grid =arange(0, 12, columns:4);
final samples =linspace(0, 1, 5);

32-bit matrices:

final a32 =Matrix32([
[1, 2],
[3, 4],
]);
final z32 =zeros32(2, 3);
final o32 =ones32(2, 3);
final f32 =full32(2, 3, 1.5);
final r32 =rand32(1024, 1024, seed:7);
final i32 =eye32(4);
final d32 =diag32([1, 2, 3]);
final grid32 =arange32(0, 12, columns:4);
final samples32 =linspace32(0, 1, 5);

Other constructors:

final fromRows =Matrix64.fromRows([[1, 2], [3, 4]]);
final fromColumns =Matrix64.fromColumns([[1, 3], [2, 4]]);
final fromFlat =Matrix64.fromFlat([1, 2, 3, 4], 2, 2);
final fromBytes =Matrix64.fromByteData(
Float64List.fromList([1, 2, 3, 4]).buffer.asByteData(),
2,
2,
);
final spd =Matrix64.randomSPD(4, seed:1);

Indexing, Views, And Conversion

final a =arange(0, 9, columns:3);
print(a(1, 2)); // element accessprint(a[1][2]); // row view accessprint(a.row(0)); // Vector64print(a.column(1)); // Vector64
a.set(0, 0, 99);
a[1][1] =42;
final rows = a.toRows();
final values = a.values; // Float64List copyfinal unsafe = a.unsafeValuesView; // internal storage view for advanced usefinal json = a.toJson();
final restored =Matrix64.fromJson(json);

Rows are fixed-length views. Vector64 and Vector32 are fixed-length linear algebra objects that implement Iterable<double>; they are not growable List<double> objects.

Arithmetic Semantics

final a =mat([
[1, 2],
[3, 4],
]);
final b =mat([
[5, 6],
[7, 8],
]);
final x =vec([1, 1]);
print(a + b); // elementwise additionprint(a -1); // scalar broadcastingprint(a *2); // scalar multiplicationprint(a * b); // matrix multiplicationprint(a * x); // matrix-vector multiplicationprint(x * a); // vector-matrix multiplicationprint(a + x); // row-vector broadcastingprint(a.hadamard(b)); // Hadamard elementwise multiplicationprint(a /2);

The meaning of * depends on the right-hand side:

  • matrix * matrix is matrix multiplication.
  • matrix * vector is matrix-vector multiplication.
  • vector * matrix is row-vector matrix multiplication.
  • matrix * number and vector * number are scalar multiplication.
  • Use hadamard for elementwise matrix multiplication.

Invalid shapes throw ArgumentError immediately. The library does not silently reshape, pad, or truncate data.

Shape And Data Operations

final a =arange(0, 12, columns:4);
print(a.transpose);
print(a.t);
print(a.reshape(4, 3));
print(a.slice(rowStart:1, rowEnd:3, columnStart:1));
print(a.sample(rowIndices: [0, 2], columnIndices: [1, 3]));
print(a.vstack(a));
print(a.hstack(a));
print(a.flatten());

Transforms and statistics:

final centered = a.mapColumns((column) => column - column.mean);
final selected = a.filterRows((row, index) => row.sum >10);
final sorted = a.sort((row) => row.sum, direction:SortDirection.desc);
print(a.mean);
print(a.meanByAxis(Axis.columns));
print(a.variance(Axis.rows));
print(a.deviation(Axis.rows));
print(a.norm());

Vector API

final x =vec([1, 2, 3]);
final y =vec([4, 5, 6]);
final x32 =vec32([1, 2, 3, 4]);
final y32 =vec32([5, 6, 7, 8]);
print(x.dot(y));
print(x.norm());
print(x.distanceTo(y, Distance.euclidean));
print(x.cosine(y));
print(x.normalize());
print(x.subvector(1));
print(x.unique());
print(x32.dot(y32));
print(x32 + y32);

Helper constructors:

final z =vecZeros(3);
final o =vecOnes(3);
final f =vecFull(3, 2);
final r =randVec(3, seed:1);
final range =vecRange(0, 10, step:2);
final line =vecLinspace(0, 1, 5);
final z32 =vecZeros32(4);
final o32 =vecOnes32(4);

Direct Linear Algebra

final a =mat([
[4, 7],
[2, 6],
]);
print(a.determinant);
print(a.inverse);
print(a.trace);
print(a.rank);
print(a.rref());
final rhs =mat([
[1],
[0],
]);
print(a.solve(rhs));

Square-matrix entry point:

final s =SquareMatrix.fromList([
[4, 7],
[2, 6],
]);
print(s.determinant);
print(s.inverse);
print(s.logAbsDeterminant);

Direct solve, determinant, and inverse use pivoting. Singular matrices throw at working precision. Ill-conditioned problems should pass explicit tolerances.

Decompositions And Advanced Algorithms

final a =mat([
[4, 1],
[1, 3],
]);
final lu = a.lu();
final qr = a.qr();
final cholesky = a.cholesky();
final eigen = a.eigenSymmetric();
final svd = a.svd();
print(lu.solve(mat([[1], [2]])));
print(qr.q * qr.r);
print(cholesky.lower * cholesky.lower.transpose);
print(eigen.values);
print(svd.singularValues);

High-level APIs:

final design =mat([
[1, 1],
[1, 2],
[1, 3],
]);
final observed =mat([
[1],
[2],
[2],
]);
print(design.leastSquares(observed));
print(design.pseudoInverse());
final pca = design.pca(components:1);
print(pca.components);
print(pca.explainedVariance);
APIApplies toTypical use
lu()square matricesDirect solve, determinant, pivoted factorization
qr()tall or full-rank square matricesLeast squares, orthogonalization
cholesky()symmetric positive definite matricesSPD solve and factorization
eigenSymmetric()real symmetric matricesFull eigenvalues and eigenvectors
eigen()symmetric full solve or power iterationHigh-level eigen interface
svd()rectangular or square matricesLow-rank analysis, pseudoinverse
pseudoInverse()rectangular or square matricesMoore-Penrose pseudoinverse
leastSquares(rhs)overdetermined or full-rank systemsLeast squares
pca()observation x feature matrixPrincipal component analysis

Matrix32 exposes the same high-level API names. Matrix-valued results keep 32-bit storage; scalar accumulations may use Dart double temporaries where the language requires it.

Iterative And Krylov Methods

final a =mat([
[4, 1],
[1, 3],
]);
final b =vec([1, 2]);
print(a.jacobi(b).solution);
print(a.gaussSeidel(b).solution);
print(a.sor(b, omega:1.1).solution);
print(a.conjugateGradient(b).solution);
print(a.gmres(b, restart:20).solution);
print(a.arnoldi(b, 2).hessenberg);
print(a.powerIteration().eigenvalue);

Result objects include convergence status, iteration count, residual norm, and the computed solution or eigenpair. Iterative methods are sensitive to initial guess, tolerance, conditioning, and expected convergence properties. Production code should set tolerance and maxIterations explicitly.

Sparse Matrices

final sparse =SparseMatrix.fromRows([
[1, 0, 2],
[0, 0, 3],
[4, 0, 0],
]);
print(sparse.nnz);
print(sparse.mv(vec([1, 2, 3])));
print(sparse.matmul(eye(3)));
print(sparse.transpose().toDense());
final fromTriplets =SparseMatrix.fromTriplets(3, 3, [
SparseEntry(0, 0, 1),
SparseEntry(0, 2, 2),
SparseEntry(2, 1, 4),
]);
final compact =mat([
[1, 0],
[0, 2],
]).toSparse();

Sparse matrices use CSR storage. The sparse API is separate from Matrix64 / Matrix32 dense kernels and is intended for matrices where nonzero entries are a small fraction of total entries.

Precision, Numerics, And Performance Policy

Recommended choices:

  • Use Matrix64 / Vector64 by default.
  • Use Matrix32 / Vector32 for large throughput-oriented workloads when float32 error is acceptable.
  • Set explicit tolerances for ill-conditioned matrices, rank decisions, near-singular systems, and iterative solvers.

Matrix32 and Vector32 use Float32x4 on suitable hot paths, including matrix multiplication, matrix-vector multiplication, vector-matrix multiplication, elementwise arithmetic, scalar arithmetic, dot products, sums, and norms. Matrix64 / Vector64 use Float64List and Float64x2-oriented kernels.

API scope:

  • Covers common dense-matrix workflows: construction, indexing, shape operations, arithmetic, statistics, JSON, decompositions, and solves.
  • Adds QR, SVD, pseudoinverse, least squares, PCA, iterative methods, Krylov methods, and CSR sparse matrices.
  • Does not include native BLAS/LAPACK, GPU execution, autodiff, distributed matrices, or full complex nonsymmetric eigensolvers.

Benchmark

Benchmark scripts use an AOT runner by default. JIT is for smoke/debug runs and must not be used for published performance claims.

Focused matrix multiplication comparison:

dart run test/benchmark_matmul.dart 256,512,1024 3 1 build/performance_report.md

Broader benchmark suite:

dart run test/benchmark_suite.dart 100,256,512,1000 3 1 build/benchmark_suite.md

The suite covers construction, scalar/elementwise operations, broadcasting, square and rectangular matrix multiplication, matrix-vector, vector-matrix, transpose, direct solves, vectors, sparse matrices, decompositions, least squares, statistics, and iterative/Krylov algorithms.

Generated reports:

Performance claims must name:

  • Dart SDK and command line.
  • AOT/JIT mode.
  • Precision: float32 or float64.
  • Matrix size and shape.
  • Compared package version and interface.
  • Iterations, warmups, and sample count.

Testing And Quality Gates

Routine checks:

dart format --output=none --set-exit-if-changed lib test
dart analyze
dart test

Optional performance regression:

MATRICES_PERF_REGRESSION=1 dart test test/performance_regression_test.dart

The test suite covers:

  • Construction, indexing, shape validation, and error paths.
  • Matrix64 / Matrix32 / Vector64 / Vector32 arithmetic.
  • Matrix multiplication against reference implementations.
  • LU, QR, Cholesky, determinant, inverse, and solve.
  • Symmetric eigen, SVD, pseudoinverse, least squares, PCA.
  • Jacobi, Gauss-Seidel, SOR, CG, GMRES, Arnoldi, power iteration.
  • CSR sparse construction, conversion, transpose, serialization, vector multiply, and dense multiply.
  • Randomized property tests, ill-conditioned Hilbert residuals, near-singular tolerance behavior, and float32 tolerances.

Recommended quality gates should at least include format checks, static analysis, tests, benchmark smoke, coverage artifacts, and API reference generation.

Error Handling

Matrices fails fast on shape and numerical preconditions:

mat([[1, 2]]) *mat([[1, 2]]); // ArgumentErrormat([[1, 2], [2, 4]]).inverse; // StateErrormat([[1, 2], [3, 4]]).cholesky(); // StateError

The package does not silently reshape, pad, truncate, or change precision.

About

Matrix Computing and Linear Algebra Library for Dart and Flutter

Topics

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Matrices

English | 中文文档

Matrices is a matrix computation and linear algebra library for Dart and Flutter. It focuses on high performance and script-style ergonomics, providing NumPy/MATLAB-like construction, indexing, broadcasting, and operator semantics, while keeping explicit 32-bit and 64-bit precision choices.

Project features:

  • Uses Dart's built-in SIMD APIs to accelerate computation, without depending on FFI or platform-specific binary runtimes.
  • Uses contiguous typed-data storage to avoid performance and semantic issues from nested-list structures.
  • Explicit Matrix64 / Matrix32 and Vector64 / Vector32 APIs.
  • Covers common dense matrices, CSR sparse matrices, direct decompositions, advanced decompositions, iterative methods, and Krylov methods.

Quick Start

import'package:matrices/matrices.dart';
voidmain() {
final a =mat([
[1, 2, 3],
[4, 5, 6],
]);
final b =mat([
[7, 8],
[9, 10],
[11, 12],
]);
final x =vec([1, 1, 1]);
print(a * b); // Matrix64 matrix multiplicationprint(a * x); // Matrix64 * Vector64print(a +1); // scalar broadcastingprint(a + x); // row-vector broadcastingprint(a.transpose);
}

Explicit 32-bit path:

final a32 =mat32([
[1, 2],
[3, 4],
]);
final x32 =vec32([1, 1]);
print(a32 * x32); // Vector32print(a32 * a32); // Matrix32print(a32.toFloat64()); // Matrix64

Type System

TypeStorageUse
Matrix64Float64ListDefault high-precision dense matrix
Matrix32Float32ListThroughput and memory-oriented dense matrix
Vector64Float64ListDefault high-precision vector
Vector32Float32ListThroughput-oriented float32 vector
Matrixtypedef Matrix = Matrix64Script-friendly short name
Vectortypedef Vector = Vector64Script-friendly short name

Matrix and Vector are 64-bit aliases, not separate implementations. Public APIs and documentation should prefer Matrix64 / Vector64 when precision must be explicit. Use Matrix32 / Vector32 for float32. The package does not silently downgrade precision.

Default constructors use full words, with short aliases for script-style code. Examples use short aliases for interactive ergonomics.

Default APIShort aliasReturn type
matrix([...])mat([...])Matrix64
matrix32([...])mat32([...])Matrix32
vector([...])vec([...])Vector64
vector32([...])vec32([...])Vector32

Helper constructors follow the same pattern, for example vectorZeros / vecZeros and vectorLinspace32 / vecLinspace32.

Construction

64-bit matrices:

final a =Matrix64([
[1, 2],
[3, 4],
]);
final b =Matrix([
[1, 2],
[3, 4],
]); // Matrix is an alias for Matrix64final z =zeros(2, 3);
final o =ones(2, 3);
final f =full(2, 3, 9);
final r =rand(2, 3, seed:42);
final i =eye(4);
final d =diag([1, 2, 3]);
final grid =arange(0, 12, columns:4);
final samples =linspace(0, 1, 5);

32-bit matrices:

final a32 =Matrix32([
[1, 2],
[3, 4],
]);
final z32 =zeros32(2, 3);
final o32 =ones32(2, 3);
final f32 =full32(2, 3, 1.5);
final r32 =rand32(1024, 1024, seed:7);
final i32 =eye32(4);
final d32 =diag32([1, 2, 3]);
final grid32 =arange32(0, 12, columns:4);
final samples32 =linspace32(0, 1, 5);

Other constructors:

final fromRows =Matrix64.fromRows([[1, 2], [3, 4]]);
final fromColumns =Matrix64.fromColumns([[1, 3], [2, 4]]);
final fromFlat =Matrix64.fromFlat([1, 2, 3, 4], 2, 2);
final fromBytes =Matrix64.fromByteData(
Float64List.fromList([1, 2, 3, 4]).buffer.asByteData(),
2,
2,
);
final spd =Matrix64.randomSPD(4, seed:1);

Indexing, Views, And Conversion

final a =arange(0, 9, columns:3);
print(a(1, 2)); // element accessprint(a[1][2]); // row view accessprint(a.row(0)); // Vector64print(a.column(1)); // Vector64
a.set(0, 0, 99);
a[1][1] =42;
final rows = a.toRows();
final values = a.values; // Float64List copyfinal unsafe = a.unsafeValuesView; // internal storage view for advanced usefinal json = a.toJson();
final restored =Matrix64.fromJson(json);

Rows are fixed-length views. Vector64 and Vector32 are fixed-length linear algebra objects that implement Iterable<double>; they are not growable List<double> objects.

Arithmetic Semantics

final a =mat([
[1, 2],
[3, 4],
]);
final b =mat([
[5, 6],
[7, 8],
]);
final x =vec([1, 1]);
print(a + b); // elementwise additionprint(a -1); // scalar broadcastingprint(a *2); // scalar multiplicationprint(a * b); // matrix multiplicationprint(a * x); // matrix-vector multiplicationprint(x * a); // vector-matrix multiplicationprint(a + x); // row-vector broadcastingprint(a.hadamard(b)); // Hadamard elementwise multiplicationprint(a /2);

The meaning of * depends on the right-hand side:

  • matrix * matrix is matrix multiplication.
  • matrix * vector is matrix-vector multiplication.
  • vector * matrix is row-vector matrix multiplication.
  • matrix * number and vector * number are scalar multiplication.
  • Use hadamard for elementwise matrix multiplication.

Invalid shapes throw ArgumentError immediately. The library does not silently reshape, pad, or truncate data.

Shape And Data Operations

final a =arange(0, 12, columns:4);
print(a.transpose);
print(a.t);
print(a.reshape(4, 3));
print(a.slice(rowStart:1, rowEnd:3, columnStart:1));
print(a.sample(rowIndices: [0, 2], columnIndices: [1, 3]));
print(a.vstack(a));
print(a.hstack(a));
print(a.flatten());

Transforms and statistics:

final centered = a.mapColumns((column) => column - column.mean);
final selected = a.filterRows((row, index) => row.sum >10);
final sorted = a.sort((row) => row.sum, direction:SortDirection.desc);
print(a.mean);
print(a.meanByAxis(Axis.columns));
print(a.variance(Axis.rows));
print(a.deviation(Axis.rows));
print(a.norm());

Vector API

final x =vec([1, 2, 3]);
final y =vec([4, 5, 6]);
final x32 =vec32([1, 2, 3, 4]);
final y32 =vec32([5, 6, 7, 8]);
print(x.dot(y));
print(x.norm());
print(x.distanceTo(y, Distance.euclidean));
print(x.cosine(y));
print(x.normalize());
print(x.subvector(1));
print(x.unique());
print(x32.dot(y32));
print(x32 + y32);

Helper constructors:

final z =vecZeros(3);
final o =vecOnes(3);
final f =vecFull(3, 2);
final r =randVec(3, seed:1);
final range =vecRange(0, 10, step:2);
final line =vecLinspace(0, 1, 5);
final z32 =vecZeros32(4);
final o32 =vecOnes32(4);

Direct Linear Algebra

final a =mat([
[4, 7],
[2, 6],
]);
print(a.determinant);
print(a.inverse);
print(a.trace);
print(a.rank);
print(a.rref());
final rhs =mat([
[1],
[0],
]);
print(a.solve(rhs));

Square-matrix entry point:

final s =SquareMatrix.fromList([
[4, 7],
[2, 6],
]);
print(s.determinant);
print(s.inverse);
print(s.logAbsDeterminant);

Direct solve, determinant, and inverse use pivoting. Singular matrices throw at working precision. Ill-conditioned problems should pass explicit tolerances.

Decompositions And Advanced Algorithms

final a =mat([
[4, 1],
[1, 3],
]);
final lu = a.lu();
final qr = a.qr();
final cholesky = a.cholesky();
final eigen = a.eigenSymmetric();
final svd = a.svd();
print(lu.solve(mat([[1], [2]])));
print(qr.q * qr.r);
print(cholesky.lower * cholesky.lower.transpose);
print(eigen.values);
print(svd.singularValues);

High-level APIs:

final design =mat([
[1, 1],
[1, 2],
[1, 3],
]);
final observed =mat([
[1],
[2],
[2],
]);
print(design.leastSquares(observed));
print(design.pseudoInverse());
final pca = design.pca(components:1);
print(pca.components);
print(pca.explainedVariance);
APIApplies toTypical use
lu()square matricesDirect solve, determinant, pivoted factorization
qr()tall or full-rank square matricesLeast squares, orthogonalization
cholesky()symmetric positive definite matricesSPD solve and factorization
eigenSymmetric()real symmetric matricesFull eigenvalues and eigenvectors
eigen()symmetric full solve or power iterationHigh-level eigen interface
svd()rectangular or square matricesLow-rank analysis, pseudoinverse
pseudoInverse()rectangular or square matricesMoore-Penrose pseudoinverse
leastSquares(rhs)overdetermined or full-rank systemsLeast squares
pca()observation x feature matrixPrincipal component analysis

Matrix32 exposes the same high-level API names. Matrix-valued results keep 32-bit storage; scalar accumulations may use Dart double temporaries where the language requires it.

Iterative And Krylov Methods

final a =mat([
[4, 1],
[1, 3],
]);
final b =vec([1, 2]);
print(a.jacobi(b).solution);
print(a.gaussSeidel(b).solution);
print(a.sor(b, omega:1.1).solution);
print(a.conjugateGradient(b).solution);
print(a.gmres(b, restart:20).solution);
print(a.arnoldi(b, 2).hessenberg);
print(a.powerIteration().eigenvalue);

Result objects include convergence status, iteration count, residual norm, and the computed solution or eigenpair. Iterative methods are sensitive to initial guess, tolerance, conditioning, and expected convergence properties. Production code should set tolerance and maxIterations explicitly.

Sparse Matrices

final sparse =SparseMatrix.fromRows([
[1, 0, 2],
[0, 0, 3],
[4, 0, 0],
]);
print(sparse.nnz);
print(sparse.mv(vec([1, 2, 3])));
print(sparse.matmul(eye(3)));
print(sparse.transpose().toDense());
final fromTriplets =SparseMatrix.fromTriplets(3, 3, [
SparseEntry(0, 0, 1),
SparseEntry(0, 2, 2),
SparseEntry(2, 1, 4),
]);
final compact =mat([
[1, 0],
[0, 2],
]).toSparse();

Sparse matrices use CSR storage. The sparse API is separate from Matrix64 / Matrix32 dense kernels and is intended for matrices where nonzero entries are a small fraction of total entries.

Precision, Numerics, And Performance Policy

Recommended choices:

  • Use Matrix64 / Vector64 by default.
  • Use Matrix32 / Vector32 for large throughput-oriented workloads when float32 error is acceptable.
  • Set explicit tolerances for ill-conditioned matrices, rank decisions, near-singular systems, and iterative solvers.

Matrix32 and Vector32 use Float32x4 on suitable hot paths, including matrix multiplication, matrix-vector multiplication, vector-matrix multiplication, elementwise arithmetic, scalar arithmetic, dot products, sums, and norms. Matrix64 / Vector64 use Float64List and Float64x2-oriented kernels.

API scope:

  • Covers common dense-matrix workflows: construction, indexing, shape operations, arithmetic, statistics, JSON, decompositions, and solves.
  • Adds QR, SVD, pseudoinverse, least squares, PCA, iterative methods, Krylov methods, and CSR sparse matrices.
  • Does not include native BLAS/LAPACK, GPU execution, autodiff, distributed matrices, or full complex nonsymmetric eigensolvers.

Benchmark

Benchmark scripts use an AOT runner by default. JIT is for smoke/debug runs and must not be used for published performance claims.

Focused matrix multiplication comparison:

dart run test/benchmark_matmul.dart 256,512,1024 3 1 build/performance_report.md

Broader benchmark suite:

dart run test/benchmark_suite.dart 100,256,512,1000 3 1 build/benchmark_suite.md

The suite covers construction, scalar/elementwise operations, broadcasting, square and rectangular matrix multiplication, matrix-vector, vector-matrix, transpose, direct solves, vectors, sparse matrices, decompositions, least squares, statistics, and iterative/Krylov algorithms.

Generated reports:

Performance claims must name:

  • Dart SDK and command line.
  • AOT/JIT mode.
  • Precision: float32 or float64.
  • Matrix size and shape.
  • Compared package version and interface.
  • Iterations, warmups, and sample count.

Testing And Quality Gates

Routine checks:

dart format --output=none --set-exit-if-changed lib test
dart analyze
dart test

Optional performance regression:

MATRICES_PERF_REGRESSION=1 dart test test/performance_regression_test.dart

The test suite covers:

  • Construction, indexing, shape validation, and error paths.
  • Matrix64 / Matrix32 / Vector64 / Vector32 arithmetic.
  • Matrix multiplication against reference implementations.
  • LU, QR, Cholesky, determinant, inverse, and solve.
  • Symmetric eigen, SVD, pseudoinverse, least squares, PCA.
  • Jacobi, Gauss-Seidel, SOR, CG, GMRES, Arnoldi, power iteration.
  • CSR sparse construction, conversion, transpose, serialization, vector multiply, and dense multiply.
  • Randomized property tests, ill-conditioned Hilbert residuals, near-singular tolerance behavior, and float32 tolerances.

Recommended quality gates should at least include format checks, static analysis, tests, benchmark smoke, coverage artifacts, and API reference generation.

Error Handling

Matrices fails fast on shape and numerical preconditions:

mat([[1, 2]]) *mat([[1, 2]]); // ArgumentErrormat([[1, 2], [2, 4]]).inverse; // StateErrormat([[1, 2], [3, 4]]).cholesky(); // StateError

The package does not silently reshape, pad, truncate, or change precision.

About

Matrix Computing and Linear Algebra Library for Dart and Flutter

Topics

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

Matrices

English | 中文文档

Matrices is a matrix computation and linear algebra library for Dart and Flutter. It focuses on high performance and script-style ergonomics, providing NumPy/MATLAB-like construction, indexing, broadcasting, and operator semantics, while keeping explicit 32-bit and 64-bit precision choices.

Project features:

  • Uses Dart's built-in SIMD APIs to accelerate computation, without depending on FFI or platform-specific binary runtimes.
  • Uses contiguous typed-data storage to avoid performance and semantic issues from nested-list structures.
  • Explicit Matrix64 / Matrix32 and Vector64 / Vector32 APIs.
  • Covers common dense matrices, CSR sparse matrices, direct decompositions, advanced decompositions, iterative methods, and Krylov methods.

Quick Start

import'package:matrices/matrices.dart';
voidmain() {
final a =mat([
[1, 2, 3],
[4, 5, 6],
]);
final b =mat([
[7, 8],
[9, 10],
[11, 12],
]);
final x =vec([1, 1, 1]);
print(a * b); // Matrix64 matrix multiplicationprint(a * x); // Matrix64 * Vector64print(a +1); // scalar broadcastingprint(a + x); // row-vector broadcastingprint(a.transpose);
}

Explicit 32-bit path:

final a32 =mat32([
[1, 2],
[3, 4],
]);
final x32 =vec32([1, 1]);
print(a32 * x32); // Vector32print(a32 * a32); // Matrix32print(a32.toFloat64()); // Matrix64

Type System

TypeStorageUse
Matrix64Float64ListDefault high-precision dense matrix
Matrix32Float32ListThroughput and memory-oriented dense matrix
Vector64Float64ListDefault high-precision vector
Vector32Float32ListThroughput-oriented float32 vector
Matrixtypedef Matrix = Matrix64Script-friendly short name
Vectortypedef Vector = Vector64Script-friendly short name

Matrix and Vector are 64-bit aliases, not separate implementations. Public APIs and documentation should prefer Matrix64 / Vector64 when precision must be explicit. Use Matrix32 / Vector32 for float32. The package does not silently downgrade precision.

Default constructors use full words, with short aliases for script-style code. Examples use short aliases for interactive ergonomics.

Default APIShort aliasReturn type
matrix([...])mat([...])Matrix64
matrix32([...])mat32([...])Matrix32
vector([...])vec([...])Vector64
vector32([...])vec32([...])Vector32

Helper constructors follow the same pattern, for example vectorZeros / vecZeros and vectorLinspace32 / vecLinspace32.

Construction

64-bit matrices:

final a =Matrix64([
[1, 2],
[3, 4],
]);
final b =Matrix([
[1, 2],
[3, 4],
]); // Matrix is an alias for Matrix64final z =zeros(2, 3);
final o =ones(2, 3);
final f =full(2, 3, 9);
final r =rand(2, 3, seed:42);
final i =eye(4);
final d =diag([1, 2, 3]);
final grid =arange(0, 12, columns:4);
final samples =linspace(0, 1, 5);

32-bit matrices:

final a32 =Matrix32([
[1, 2],
[3, 4],
]);
final z32 =zeros32(2, 3);
final o32 =ones32(2, 3);
final f32 =full32(2, 3, 1.5);
final r32 =rand32(1024, 1024, seed:7);
final i32 =eye32(4);
final d32 =diag32([1, 2, 3]);
final grid32 =arange32(0, 12, columns:4);
final samples32 =linspace32(0, 1, 5);

Other constructors:

final fromRows =Matrix64.fromRows([[1, 2], [3, 4]]);
final fromColumns =Matrix64.fromColumns([[1, 3], [2, 4]]);
final fromFlat =Matrix64.fromFlat([1, 2, 3, 4], 2, 2);
final fromBytes =Matrix64.fromByteData(
Float64List.fromList([1, 2, 3, 4]).buffer.asByteData(),
2,
2,
);
final spd =Matrix64.randomSPD(4, seed:1);

Indexing, Views, And Conversion

final a =arange(0, 9, columns:3);
print(a(1, 2)); // element accessprint(a[1][2]); // row view accessprint(a.row(0)); // Vector64print(a.column(1)); // Vector64
a.set(0, 0, 99);
a[1][1] =42;
final rows = a.toRows();
final values = a.values; // Float64List copyfinal unsafe = a.unsafeValuesView; // internal storage view for advanced usefinal json = a.toJson();
final restored =Matrix64.fromJson(json);

Rows are fixed-length views. Vector64 and Vector32 are fixed-length linear algebra objects that implement Iterable<double>; they are not growable List<double> objects.

Arithmetic Semantics

final a =mat([
[1, 2],
[3, 4],
]);
final b =mat([
[5, 6],
[7, 8],
]);
final x =vec([1, 1]);
print(a + b); // elementwise additionprint(a -1); // scalar broadcastingprint(a *2); // scalar multiplicationprint(a * b); // matrix multiplicationprint(a * x); // matrix-vector multiplicationprint(x * a); // vector-matrix multiplicationprint(a + x); // row-vector broadcastingprint(a.hadamard(b)); // Hadamard elementwise multiplicationprint(a /2);

The meaning of * depends on the right-hand side:

  • matrix * matrix is matrix multiplication.
  • matrix * vector is matrix-vector multiplication.
  • vector * matrix is row-vector matrix multiplication.
  • matrix * number and vector * number are scalar multiplication.
  • Use hadamard for elementwise matrix multiplication.

Invalid shapes throw ArgumentError immediately. The library does not silently reshape, pad, or truncate data.

Shape And Data Operations

final a =arange(0, 12, columns:4);
print(a.transpose);
print(a.t);
print(a.reshape(4, 3));
print(a.slice(rowStart:1, rowEnd:3, columnStart:1));
print(a.sample(rowIndices: [0, 2], columnIndices: [1, 3]));
print(a.vstack(a));
print(a.hstack(a));
print(a.flatten());

Transforms and statistics:

final centered = a.mapColumns((column) => column - column.mean);
final selected = a.filterRows((row, index) => row.sum >10);
final sorted = a.sort((row) => row.sum, direction:SortDirection.desc);
print(a.mean);
print(a.meanByAxis(Axis.columns));
print(a.variance(Axis.rows));
print(a.deviation(Axis.rows));
print(a.norm());

Vector API

final x =vec([1, 2, 3]);
final y =vec([4, 5, 6]);
final x32 =vec32([1, 2, 3, 4]);
final y32 =vec32([5, 6, 7, 8]);
print(x.dot(y));
print(x.norm());
print(x.distanceTo(y, Distance.euclidean));
print(x.cosine(y));
print(x.normalize());
print(x.subvector(1));
print(x.unique());
print(x32.dot(y32));
print(x32 + y32);

Helper constructors:

final z =vecZeros(3);
final o =vecOnes(3);
final f =vecFull(3, 2);
final r =randVec(3, seed:1);
final range =vecRange(0, 10, step:2);
final line =vecLinspace(0, 1, 5);
final z32 =vecZeros32(4);
final o32 =vecOnes32(4);

Direct Linear Algebra

final a =mat([
[4, 7],
[2, 6],
]);
print(a.determinant);
print(a.inverse);
print(a.trace);
print(a.rank);
print(a.rref());
final rhs =mat([
[1],
[0],
]);
print(a.solve(rhs));

Square-matrix entry point:

final s =SquareMatrix.fromList([
[4, 7],
[2, 6],
]);
print(s.determinant);
print(s.inverse);
print(s.logAbsDeterminant);

Direct solve, determinant, and inverse use pivoting. Singular matrices throw at working precision. Ill-conditioned problems should pass explicit tolerances.

Decompositions And Advanced Algorithms

final a =mat([
[4, 1],
[1, 3],
]);
final lu = a.lu();
final qr = a.qr();
final cholesky = a.cholesky();
final eigen = a.eigenSymmetric();
final svd = a.svd();
print(lu.solve(mat([[1], [2]])));
print(qr.q * qr.r);
print(cholesky.lower * cholesky.lower.transpose);
print(eigen.values);
print(svd.singularValues);

High-level APIs:

final design =mat([
[1, 1],
[1, 2],
[1, 3],
]);
final observed =mat([
[1],
[2],
[2],
]);
print(design.leastSquares(observed));
print(design.pseudoInverse());
final pca = design.pca(components:1);
print(pca.components);
print(pca.explainedVariance);
APIApplies toTypical use
lu()square matricesDirect solve, determinant, pivoted factorization
qr()tall or full-rank square matricesLeast squares, orthogonalization
cholesky()symmetric positive definite matricesSPD solve and factorization
eigenSymmetric()real symmetric matricesFull eigenvalues and eigenvectors
eigen()symmetric full solve or power iterationHigh-level eigen interface
svd()rectangular or square matricesLow-rank analysis, pseudoinverse
pseudoInverse()rectangular or square matricesMoore-Penrose pseudoinverse
leastSquares(rhs)overdetermined or full-rank systemsLeast squares
pca()observation x feature matrixPrincipal component analysis

Matrix32 exposes the same high-level API names. Matrix-valued results keep 32-bit storage; scalar accumulations may use Dart double temporaries where the language requires it.

Iterative And Krylov Methods

final a =mat([
[4, 1],
[1, 3],
]);
final b =vec([1, 2]);
print(a.jacobi(b).solution);
print(a.gaussSeidel(b).solution);
print(a.sor(b, omega:1.1).solution);
print(a.conjugateGradient(b).solution);
print(a.gmres(b, restart:20).solution);
print(a.arnoldi(b, 2).hessenberg);
print(a.powerIteration().eigenvalue);

Result objects include convergence status, iteration count, residual norm, and the computed solution or eigenpair. Iterative methods are sensitive to initial guess, tolerance, conditioning, and expected convergence properties. Production code should set tolerance and maxIterations explicitly.

Sparse Matrices

final sparse =SparseMatrix.fromRows([
[1, 0, 2],
[0, 0, 3],
[4, 0, 0],
]);
print(sparse.nnz);
print(sparse.mv(vec([1, 2, 3])));
print(sparse.matmul(eye(3)));
print(sparse.transpose().toDense());
final fromTriplets =SparseMatrix.fromTriplets(3, 3, [
SparseEntry(0, 0, 1),
SparseEntry(0, 2, 2),
SparseEntry(2, 1, 4),
]);
final compact =mat([
[1, 0],
[0, 2],
]).toSparse();

Sparse matrices use CSR storage. The sparse API is separate from Matrix64 / Matrix32 dense kernels and is intended for matrices where nonzero entries are a small fraction of total entries.

Precision, Numerics, And Performance Policy

Recommended choices:

  • Use Matrix64 / Vector64 by default.
  • Use Matrix32 / Vector32 for large throughput-oriented workloads when float32 error is acceptable.
  • Set explicit tolerances for ill-conditioned matrices, rank decisions, near-singular systems, and iterative solvers.

Matrix32 and Vector32 use Float32x4 on suitable hot paths, including matrix multiplication, matrix-vector multiplication, vector-matrix multiplication, elementwise arithmetic, scalar arithmetic, dot products, sums, and norms. Matrix64 / Vector64 use Float64List and Float64x2-oriented kernels.

API scope:

  • Covers common dense-matrix workflows: construction, indexing, shape operations, arithmetic, statistics, JSON, decompositions, and solves.
  • Adds QR, SVD, pseudoinverse, least squares, PCA, iterative methods, Krylov methods, and CSR sparse matrices.
  • Does not include native BLAS/LAPACK, GPU execution, autodiff, distributed matrices, or full complex nonsymmetric eigensolvers.

Benchmark

Benchmark scripts use an AOT runner by default. JIT is for smoke/debug runs and must not be used for published performance claims.

Focused matrix multiplication comparison:

dart run test/benchmark_matmul.dart 256,512,1024 3 1 build/performance_report.md

Broader benchmark suite:

dart run test/benchmark_suite.dart 100,256,512,1000 3 1 build/benchmark_suite.md

The suite covers construction, scalar/elementwise operations, broadcasting, square and rectangular matrix multiplication, matrix-vector, vector-matrix, transpose, direct solves, vectors, sparse matrices, decompositions, least squares, statistics, and iterative/Krylov algorithms.

Generated reports:

Performance claims must name:

  • Dart SDK and command line.
  • AOT/JIT mode.
  • Precision: float32 or float64.
  • Matrix size and shape.
  • Compared package version and interface.
  • Iterations, warmups, and sample count.

Testing And Quality Gates

Routine checks:

dart format --output=none --set-exit-if-changed lib test
dart analyze
dart test

Optional performance regression:

MATRICES_PERF_REGRESSION=1 dart test test/performance_regression_test.dart

The test suite covers:

  • Construction, indexing, shape validation, and error paths.
  • Matrix64 / Matrix32 / Vector64 / Vector32 arithmetic.
  • Matrix multiplication against reference implementations.
  • LU, QR, Cholesky, determinant, inverse, and solve.
  • Symmetric eigen, SVD, pseudoinverse, least squares, PCA.
  • Jacobi, Gauss-Seidel, SOR, CG, GMRES, Arnoldi, power iteration.
  • CSR sparse construction, conversion, transpose, serialization, vector multiply, and dense multiply.
  • Randomized property tests, ill-conditioned Hilbert residuals, near-singular tolerance behavior, and float32 tolerances.

Recommended quality gates should at least include format checks, static analysis, tests, benchmark smoke, coverage artifacts, and API reference generation.

Error Handling

Matrices fails fast on shape and numerical preconditions:

mat([[1, 2]]) *mat([[1, 2]]); // ArgumentErrormat([[1, 2], [2, 4]]).inverse; // StateErrormat([[1, 2], [3, 4]]).cholesky(); // StateError

The package does not silently reshape, pad, truncate, or change precision.

About

Matrix Computing and Linear Algebra Library for Dart and Flutter

Topics

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages