Matrices as Two-Dimensional Arrays
A Matrix in Julia is simply Array{T,2} — a two-dimensional array where both a row and column index locate an element. You can build one with a literal like [1 2; 3 4], where spaces separate columns and semicolons separate rows, or with functions such as zeros(3,3), Matrix{Float64}(I, 3, 3) for an identity matrix, or rand(2,4) for a random matrix. size(A) returns a tuple (rows, columns), and size(A, 1) or size(A, 2) returns just one dimension, which is commonly used to write dimension-agnostic algorithms.
Cricket analogy: A matrix literal [1 2; 3 4] is like a 2x2 net session schedule where rows are net bays and columns are time slots; size(A) tells the coach exactly how many bays and slots exist, just like size(A,1) and size(A,2) report rows and columns separately.
Core Linear Algebra Operations
Julia's LinearAlgebra standard library provides the core operations: * performs matrix multiplication (not element-wise, which instead uses .*), transpose(A) or A' computes the transpose (A' is the adjoint, i.e., conjugate transpose for complex matrices), and the backslash operator A \ b solves the linear system Ax = b using an appropriate factorization chosen automatically based on A's structure. Functions like det(A), inv(A), tr(A), and dot(u, v) round out the common toolkit, though inv(A) is rarely the right tool for solving a system — A \ b is both faster and numerically more stable.
Cricket analogy: Using A \ b to solve a system is like a captain choosing the best bowling change based on pitch conditions rather than always opening with the same pacer (inv(A)) — Julia picks the stable 'bowler' (factorization) for the situation, just as A \ b adapts to A's structure.
using LinearAlgebra
A = [4.0 3.0; 6.0 3.0]
b = [1.0, 2.0]
x = A \ b # solve Ax = b via an automatically chosen factorization
At = A' # adjoint (transpose for real matrices)
d = det(A) # determinant
# Prefer A \ b over inv(A) * b for both speed and numerical stabilityMatrix Factorizations
For larger or repeated solves, Julia exposes matrix factorizations directly: lu(A) computes an LU decomposition, qr(A) a QR decomposition, cholesky(A) a Cholesky factorization for symmetric positive-definite matrices, and svd(A) a singular value decomposition. Calling factorize(A) lets Julia automatically pick an appropriate factorization based on A's detected structure (symmetric, triangular, etc.), and reusing the resulting factorization object to solve A \ b1, A \ b2 for multiple right-hand sides is far cheaper than refactorizing A each time, since the expensive O(n^3) decomposition step is only paid once.
Cricket analogy: Reusing a factorization for multiple right-hand sides is like a team doing one thorough pitch report (lu(A)) at the start of a Test match and then reusing it to plan strategy for every session, rather than re-analyzing the pitch from scratch each session.
Prefer the well-tested LinearAlgebra stdlib types (Symmetric, Diagonal, etc.) over hand-rolled loops — wrapping a matrix as Symmetric(A) or Diagonal(A) not only documents intent but lets Julia's dispatch system route to a faster specialized algorithm automatically.
BLAS/LAPACK and Performance
For standard numeric types like Float64 and ComplexF64, Julia's matrix operations dispatch to highly optimized BLAS and LAPACK routines under the hood, the same battle-tested Fortran/C libraries used by NumPy, MATLAB, and R. Julia additionally provides special matrix wrapper types — Symmetric, Diagonal, UpperTriangular, Tridiagonal — that carry structural information in the type itself, so multiplying or solving with a Diagonal matrix dispatches to an O(n) algorithm instead of the general O(n^3) dense routine, purely because the type system knows the structure at compile time.
Cricket analogy: A Diagonal matrix dispatching to an O(n) algorithm is like a scorer who knows in advance that only one bowler bowled the entire innings — instead of cross-checking every possible bowler-over combination, they just read down one column, drastically cutting the work, exactly like the diagonal type shortcut.
Converting a structured matrix like Diagonal or Symmetric back into a plain dense Array (e.g., with Array(D)) throws away the structural information the type system was using to select fast algorithms — operations on the resulting dense matrix fall back to general O(n^3) routines even though the numbers themselves haven't changed.
- Matrix{T} is an alias for Array{T,2}; size(A) returns (rows, columns).
- * is matrix multiplication; .* is element-wise multiplication — they are not interchangeable.
- A \ b solves Ax = b using an automatically chosen, numerically stable factorization.
- inv(A) is rarely the right tool for solving linear systems — prefer A \ b.
- lu, qr, cholesky, and svd expose explicit factorizations for reuse across multiple solves.
- Structured types like Symmetric, Diagonal, and UpperTriangular let dispatch pick faster algorithms.
- Julia's dense linear algebra is backed by the same BLAS/LAPACK libraries used by NumPy and MATLAB.
Practice what you learned
1. Which operator performs true matrix multiplication (not element-wise) in Julia?
2. Why is A \ b generally preferred over inv(A) * b for solving Ax = b?
3. What is the benefit of wrapping a matrix as Diagonal(A) instead of leaving it as a plain dense matrix?
4. What does reusing a matrix factorization like lu(A) across multiple right-hand-side solves save?
5. What libraries does Julia's dense linear algebra for Float64 matrices dispatch to under the hood?
Was this page helpful?
You May Also Like
Arrays in Julia
Learn how Julia's built-in Array type stores, indexes, and mutates collections of data, and why column-major memory layout matters for performance.
Broadcasting in Julia
Learn Julia's dot-syntax broadcasting mechanism, how chained operations fuse into allocation-free loops, and how to make custom types broadcast correctly.
The Type System and Abstract Types
Understand Julia's single-rooted type hierarchy, how abstract types organize dispatch, how multiple dispatch selects methods, and how to diagnose type instability.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics