Diffractive Networks and Metasurfaces
In 2018 a group at UCLA (Aydogan Ozcan's lab) published a neural network you could knock off a
table. Five plastic layers, 3-D printed with carefully bumpy surfaces, stacked a few centimetres
apart. Shine a terahertz image of a handwritten digit through the stack and the transmitted light
converges onto one of ten detector spots — the network's answer, correct about 90% of the time on
MNIST. No processor, no memory, no power supply, no clock. The multiplications happen while
the light travels, in the physics of
diffraction itself; the trained weights are
literally the thickness profile of the plastic. They called it a diffractive deep neural
network — D²NN — and it is the purest expression of an idea this course has circled since
the 4f correlator: propagation is computation. Inference at the speed of light, for the
energy cost of the illumination. The catch is equally pure, and this lesson takes both halves
seriously.
How a sheet of plastic multiplies
Unroll what happens between two layers. By Huygens' principle, every point of a wavefront acts as
a secondary source radiating onward — so every pixel of layer \ell
illuminates every pixel of layer \ell+1. That is a dense,
all-to-all linear map, applied by geometry at no cost: for layers of
N pixels, free space implements the full
N \times N complex matrix of Fresnel propagation kernels. The layer
itself adds the trainable part: each pixel's printed thickness t delays
the wave by a phase
\varphi = 2\pi (n - 1)\, t / \lambda, so the field leaving pixel
k is multiplied by e^{i\varphi_k}. One layer
of a D²NN is therefore
u_{\ell+1}(x) \;=\; \sum_{x'} \underbrace{w(x, x')}_{\text{diffraction}}\;
\underbrace{e^{\,i\varphi(x')}}_{\text{printed phase}}\; u_{\ell}(x'),
a fixed fully-connected matrix sandwiched with trainable phases — a neural network layer written
in optics. Training happens entirely in simulation: model the stack in software, backpropagate
through the (perfectly differentiable) diffraction equations to choose every pixel's phase, then
print the result. A worked number for scale: layers of
200 \times 200 pixels have
N = 4\times10^{4} neurons each, so a single inter-layer hop applies
N^2 = 1.6\times10^{9} complex connection weights — and a wavefront
crosses a five-layer, 15 cm stack in half a nanosecond. No electronic layer of any kind touches
those 8 billion multiplies.
Build one: a 1-D diffractive classifier
The program below is a complete diffractive network small enough to read: sixteen pixels per
layer, two trainable phase masks, Fresnel propagation between them. It must distinguish two input
beams that have identical intensity everywhere — pattern A has all pixels in phase, B
alternates phase pixel to pixel — so no single detector could ever tell them apart; only
diffraction, which converts phase structure into position, can. "Training" is a few hundred rounds
of hill-climbing on the mask phases (the print-shop version of what UCLA did with backprop),
rewarding masks that steer A's energy onto a left-hand detector zone and B's onto a right-hand
one:
// A 1-D diffractive network: two trainable phase masks + Fresnel diffraction.
// Pattern A: all pixels in phase. Pattern B: alternating phase.
// Their intensities are IDENTICAL — only diffraction can tell them apart.
const N = 16;
type C = { re: number; im: number };
const c = (re: number, im = 0): C => ({ re, im });
const mul = (a: C, b: C): C => c(a.re * b.re - a.im * b.im, a.re * b.im + a.im * b.re);
const cis = (p: number): C => c(Math.cos(p), Math.sin(p));
let seed = 42; // deterministic "randomness"
const rand = (): number => (seed = (seed * 1664525 + 1013904223) % 4294967296) / 4294967296;
// Fresnel kernel: every pixel of one layer talks to EVERY pixel of the next.
const kernel: C[][] = [];
for (let j = 0; j < N; j++) {
kernel.push([]);
for (let i = 0; i < N; i++) {
const d = (j - i) * 0.5;
kernel[j].push(cis(0.35 * d * d)); // quadratic (Fresnel) phase
}
}
function propagate(u: C[], mask: number[]): C[] {
const out: C[] = [];
for (let j = 0; j < N; j++) {
let acc = c(0);
for (let i = 0; i < N; i++) {
const w = mul(u[i], cis(mask[i])); // printed phase, then diffraction
const k = kernel[j][i];
acc = c(acc.re + w.re * k.re - w.im * k.im, acc.im + w.re * k.im + w.im * k.re);
}
out.push(c(acc.re / N, acc.im / N));
}
return out;
}
const A: C[] = [], B: C[] = [];
for (let i = 0; i < N; i++) { A.push(c(1)); B.push(c(i % 2 === 0 ? 1 : -1)); }
const zoneEnergy = (u: C[], lo: number, hi: number): number => {
let e = 0;
for (let i = lo; i < hi; i++) e += u[i].re * u[i].re + u[i].im * u[i].im;
return e;
};
function forward(u: C[], m1: number[], m2: number[]): [number, number] {
const out = propagate(propagate(u, m1), m2);
return [zoneEnergy(out, 1, 7), zoneEnergy(out, 9, 15)]; // left, right detectors
}
function score(m1: number[], m2: number[]): number { // worst-case margin:
const [aL, aR] = forward(A, m1, m2); // A must win LEFT and
const [bL, bR] = forward(B, m1, m2); // B must win RIGHT
return Math.min(aL - aR, bR - bL);
}
const m1: number[] = new Array(N).fill(0);
const m2: number[] = new Array(N).fill(0);
console.log("untrained margin: " + score(m1, m2).toFixed(3));
let best = score(m1, m2);
for (let it = 0; it < 600; it++) { // "training" = sculpting the masks
const m = rand() < 0.5 ? m1 : m2;
const i = Math.floor(rand() * N);
const old = m[i];
m[i] += (rand() - 0.5) * 2;
const s = score(m1, m2);
if (s > best) best = s; else m[i] = old;
}
console.log("trained margin: " + best.toFixed(3));
const [aL, aR] = forward(A, m1, m2);
console.log("A → left " + aL.toFixed(3) + ", right " + aR.toFixed(3) +
(aL > aR ? " classified A ✓" : " WRONG"));
const [bL, bR] = forward(B, m1, m2);
console.log("B → left " + bL.toFixed(3) + ", right " + bR.toFixed(3) +
(bR > bL ? " classified B ✓" : " WRONG"));
Run it: the untrained masks can't separate the patterns at all (margin ≈ 0), and after training
each pattern lands decisively on its own detector. Once the loop finishes, the two
m1/m2 arrays are the network — in the physical version you
would print them as thickness profiles, and the classification would thereafter cost nothing,
forever.
Metasurfaces: calculus in a coat of paint
The printed layers above are wavelength-thick bumps; metasurfaces shrink the idea
to a single layer of sub-wavelength pillars, each pillar a tiny antenna whose geometry sets the
local phase — an arbitrary phase profile in a film thinner than the wavelength. Beyond replacing
bulk lenses, metasurfaces can be designed as mathematical operators. Recall from Fourier
optics that differentiation is a multiplication in the frequency domain:
\partial u/\partial x \;\leftrightarrow\; i k_x\, \tilde u(k_x). A
surface engineered so its transmission grows linearly with the angle (i.e. spatial frequency) of
the incoming plane-wave component implements exactly that multiplication — it hands you the
spatial derivative of the incident image, optically. The showcase application is
edge detection: derivatives are large exactly at intensity boundaries, so a
camera looking through such a "differentiator glass" records an outline image directly — the first
layer of a convolutional network, executed by a passive coating before any photon reaches the
sensor. Laplacian (k^2) surfaces and even meta-structures that solve
small integral equations in the steady state of their internal reflections have been demonstrated
at proof-of-concept scale.
Two sober truths keep D²NN claims honest. First, the linearity trap. Diffraction
is linear, and a phase mask is linear in the field — so a cascade of any number of layers
collapses, mathematically, to a single complex matrix. In field-space, a "deep"
diffractive network is a one-layer linear network; calling it deep does not grant it the
expressive power of nonlinear depth. Where does its (real) classification ability come from? The
weights are complex and physically constrained (multiple masks parameterise matrices a single mask
cannot reach), and the detector at the end measures |u|^2 — one
quadratic nonlinearity at the output. That is enough for useful vision tasks, and fundamentally
less than a nonlinear deep network — there is no optical ReLU between the plastic sheets, for
exactly the reasons the
nonlinearity
problem lesson made painful. Second, the rigidity trap. Passive
zero-energy inference is bought by baking the weights into matter: retraining means reprinting,
there is no fine-tuning a lump of plastic, and micron-scale layer misalignment degrades the
computation. Demonstrated: printed THz digit classifiers, metasurface edge detectors, single-shot
optical logic demos. Speculative: reconfigurable, visible-light, camera-integrated diffractive
processors competing with silicon on real workloads.
How seriously should you take "computes for free"? Thermodynamically, quite seriously: a passive
stack adds no energy of its own — the only energy in the system is the illumination, and
if the scene is already lit (sunlight, a headlamp, a THz source you needed anyway), the marginal
cost of the computation truly is zero joules per inference, with latency set by light crossing
centimetres: sub-nanosecond. The fair accounting charges the boundaries: the source, and
the camera or detector array that reads the answer — the same electronic-photonic frontier this
course keeps meeting. That is why the natural home for diffractive optics is not "replace the
GPU" but preprocessing where light already exists: an edge-detecting or
feature-extracting front end fused onto a sensor, compressing the scene optically so the
electronics behind it can be smaller, slower and cooler. A lens has always been a free Fourier
transform bolted to every camera; diffractive networks generalise that dividend — compute smuggled
into the optics you were going to build anyway.
Where this goes next — and where the module lands
This closes the emerging-photonics tour: spiking lasers computing in time, phase-change cells
remembering in matter, meshes reprogrammed in software, combs multiplying channels in frequency,
and finally networks printed into space itself. Five different answers to "what else can light
do?", every one of them ultimately bounded by the same choke point: getting signals into the
optical domain and answers back out of it. That frontier — the
electronic–photonic
interface — is where the systems module begins, and where every architecture in this
course will be made to pay its honest, end-to-end bill.