Snapshot / Computational Thinking Repo ↗

Taking Advantage of Structure

A list of a million numbers that are all 0 except one isn't really a million numbers of information — it's one position. A diagonal matrix is "mostly zeros". A multiplication table looks big but is built from just one row and one column. The art of scientific computing is spotting the structure so you can store and compute with far less. Below, every kind of structure is shown as an image — drag the sliders and watch it.

begin
    using PlutoUI, WasmMakie
end
gray_figure (generic function with 1 method)
begin
    # WasmMakie grayscale helper: a FLAT, column-major Vector{Float64} of length nr*nc,
    # row 1 drawn at the top. (No Matrix literals — they trap inside wasm kernels.)
    function gray_figure(vals::Vector{Float64}, nr::Int, nc::Int; px::Int = 320)
        pix = Vector{NTuple{4,Float64}}(undef, nr * nc)
        for k in 1:(nr * nc)
            v = vals[k]
            pix[k] = (v, v, v, 1.0)
        end
        fig = Figure(size = (px, max(40, round(Int, px * nr / nc))))
        ax = Axis(fig[1, 1])
        hidedecorations!(ax)
        hidespines!(ax)
        image!(ax, (0.0, Float64(nc)), (0.0, Float64(nr)), pix,
               Int64(nc), Int64(nr); interpolate = false)
        fig
    end
end

A one-hot vector

The simplest structure: a vector that is 0 everywhere except a single 1. Whatever its length, all you need to know is where the 1 is. Below it's drawn as a strip of cells (white = the hot entry).

length n = 12

hot position k = 4

let
    nn = n9
    kk = k9
    kk > nn && (kk = nn)
    vals = Vector{Float64}(undef, nn)
    for t in 1:nn
        vals[t] = 0.12
    end
    vals[kk] = 0.97
    gray_figure(vals, 1, nn; px = 420)
end

Diagonal matrices

A diagonal matrix is 0 off the diagonal. An $n\times n$ matrix has $n^2$ entries, but a diagonal one is fully described by just $n$ numbers — so Julia's Diagonal type stores only the diagonal and skips the zeros entirely. Look for structure where it exists!

size n = 9

let
    m = nd
    vals = Vector{Float64}(undef, m * m)
    for i in 1:m
        for j in 1:m
            vals[j + (m - i) * m] = (i == j) ? 0.92 : 0.12
        end
    end
    gray_figure(vals, m, m; px = 300)
end

Sparse matrices

A sparse matrix is mostly zeros — not necessarily on the diagonal, just few and far between. Instead of every entry, you store only the handful of nonzero (row, col, value) triples. Slide the density up and watch the (deterministic) scatter of nonzeros fill in; at low density there's almost nothing to store.

nonzero density = 0.2

let
    m = 16
    vals = Vector{Float64}(undef, m * m)
    thr = dens * 17.0
    for i in 1:m
        for j in 1:m
            on = ((i * 7 + j * 13) % 17) < thr
            vals[j + (m - i) * m] = on ? 0.9 : 0.08
        end
    end
    gray_figure(vals, m, m; px = 300)
end

Hidden structure: a multiplication table

This one has no zeros at all, yet it's still highly structured. Entry $(i, j)$ is just $i \times j$ — so the whole $n \times n$ grid is rebuilt from a single row and a single column ($2n$ numbers, not $n^2$). That's low rank: a smooth, redundant pattern hiding in what looks like a full matrix.

size n = 10

let
    m = nm
    vals = Vector{Float64}(undef, m * m)
    denom = Float64(m * m)
    for i in 1:m
        for j in 1:m
            vals[j + (m - i) * m] = (i * j) / denom
        end
    end
    gray_figure(vals, m, m; px = 300)
end
Dict{Symbol, Any}(:diagnostics => Dict{Symbol, Any}[Dict(:line => 13, :from => 571, :message => "unterminated string literal", :severity => "error", :to => 571, :source => "JuliaSyntax.jl")], :source => "md\"\"\"\n# Summary\n\n- **Structure** is information you *don't* have to store. A one-hot vector is a single\n position; a diagonal matrix is \$n\$ numbers, not \$n^2\$.\n- **Sparse** matrices keep only their nonzeros; **low-rank** ones (like a multiplication\n table) rebuild a whole grid from a row and a column.\n- In Julia these are real *types* (`Diagonal`, `SparseMatrixCSC`, …) that store the\n compact form and run the fast algorithm automatically — \"look for structure where it\n exists\".\n\nEvery image above is a live WebAssembly island, rebuilt as you drag the sliders.\n\"\"")