<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://herr-professor.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://herr-professor.github.io/" rel="alternate" type="text/html" /><updated>2026-03-23T22:33:04+00:00</updated><id>https://herr-professor.github.io/feed.xml</id><title type="html">Farouq Oguntoye</title><subtitle>Software engineer focused on ML infrastructure, evaluation systems, and performance-critical software.</subtitle><author><name>Farouq Oguntoye</name><email>farouqoguntoye05@gmail.com</email></author><entry><title type="html">Neon: Building a Trustworthy Solver-Plus-ML Research Platform for Nanophotonics</title><link href="https://herr-professor.github.io/blog/neon-so-far/" rel="alternate" type="text/html" title="Neon: Building a Trustworthy Solver-Plus-ML Research Platform for Nanophotonics" /><published>2026-03-22T21:30:00+00:00</published><updated>2026-03-22T21:30:00+00:00</updated><id>https://herr-professor.github.io/blog/neon-so-far</id><content type="html" xml:base="https://herr-professor.github.io/blog/neon-so-far/"><![CDATA[<style>
  .neon-post-figure {
    margin: 2rem 0;
  }

  .neon-post-figure img {
    width: 100%;
    border: 1px solid #e5e7eb;
    border-radius: 8px;
  }

  .neon-post-figure figcaption {
    margin-top: 0.75rem;
    color: #4b5563;
    font-size: 0.95rem;
    line-height: 1.6;
  }

  .neon-ref {
    font-size: 0.9rem;
    color: #6b7280;
    border-left: 3px solid #e5e7eb;
    padding-left: 1rem;
    margin: 1rem 0;
  }
</style>

<p>I started Neon because I wanted a research codebase I could understand end to end — and because I was skeptical of most surrogate modeling papers I was reading.</p>

<p>The literature on machine learning for photonics has grown rapidly since Peurifoy et al. demonstrated in 2018 that neural networks could predict the scattering properties of multilayer nanoparticles far faster than direct simulation <a href="#references">[1]</a>. Since then, dozens of papers have trained networks on electromagnetic simulation data, reported strong accuracy numbers on held-out test sets, and moved on. What most of them do not report carefully: what happens outside the training distribution, whether the physics-informed losses actually earn their computational cost, whether uncertainty estimates are calibrated, and whether a better surrogate actually finds better designs.</p>

<p>Those are the questions Neon was built to answer, on a controlled benchmark, without overclaiming. This post is a completed-work summary. The codebase is stable, the experiments are done, and a paper is in preparation.</p>

<hr />

<h2 id="background-the-surrogate-modeling-problem-in-photonics">Background: The Surrogate Modeling Problem in Photonics</h2>

<p>The core challenge is well understood. Rigorous electromagnetic simulation — whether finite-difference time-domain (FDTD) as in Oskooi et al.’s Meep <a href="#references">[2]</a>, finite-difference frequency-domain (FDFD), or high-order discontinuous Galerkin methods as in the DIOGENeS suite from Inria’s Atlantis team <a href="#references">[3]</a> — is computationally expensive. A single solve on a modest 2D grid can take seconds; a full inverse-design sweep over thousands of configurations can take hours or days. This makes brute-force parameter search impractical and motivates surrogate-based approaches.</p>

<p>The surrogate idea is straightforward: train a neural network on a dataset of simulation inputs and outputs, then use the network instead of the full solver during design search. The network is wrong sometimes, but it is thousands of times faster. If you then verify only the most promising candidates with the direct solver, the total simulation budget shrinks dramatically.</p>

<p>This idea has been explored across many photonic problem classes. Liu et al. <a href="#references">[4]</a> trained tandem networks for metasurface design. Wiecha et al. <a href="#references">[5]</a> gave a broad review of deep learning in nanophotonics covering both forward prediction and inverse design. So and Bravo-Abad <a href="#references">[6]</a> reviewed the landscape specifically from the lens of inverse design. The accuracy numbers reported across these works are often impressive. What is reported less often is <em>why</em> the model works where it does, what happens when it encounters structures outside the training set, and whether the reported accuracy translates into better design outcomes.</p>

<p>The physics-informed neural network (PINN) framework, introduced rigorously by Raissi, Perdikaris, and Karniadakis in 2019 <a href="#references">[7]</a>, offered a natural way to incorporate governing equations directly into training. By adding a PDE residual term to the loss function, the network is penalized not just for fitting the data badly but for producing outputs that violate the physics. For electromagnetic problems, this has attracted significant interest — if physics constraints can substitute for data, maybe we need fewer expensive simulations to train a reliable surrogate.</p>

<p>That is the hypothesis Neon was built to test carefully. Not to implement a PINN and call it done, but to check whether the physics terms actually earn their place under controlled ablation.</p>

<hr />

<h2 id="what-neon-is">What Neon Is</h2>

<p>Neon is a C++ scalar frequency-domain Helmholtz solver with a Python/PyTorch ML layer built on top of it. It is not a general Maxwell solver. It is a research platform for careful, small-scope benchmarking.</p>

<p>The governing equation is the scalar out-of-plane Helmholtz model:</p>

\[\nabla^2 E_z(x, y) + k_0^2 \varepsilon_r(x, y) E_z(x, y) = s(x, y), \qquad k_0 = \frac{2\pi}{\lambda}\]

<p>This is a 2D, monochromatic, scalar formulation — the same class of reduced model used in many photonics surrogate benchmarks because it retains physically meaningful structure (resonance behavior, transmission and reflection, field concentration) while remaining computationally tractable enough to generate large datasets and run controlled ablations. The solver assembles a sparse finite-difference system on a structured Cartesian grid and solves it using Eigen’s SparseLU, with an optional iterative BiCGSTAB path. The current benchmark family is a parameterized rectangular dielectric slab in vacuum at normal incidence.</p>

<p>On top of this solver, Neon builds a complete ML experimentation layer: solver-driven dataset generation, baseline surrogate training, hybrid physics-informed training, deep ensemble uncertainty, active learning, and inverse design screening — all driven by the same direct solver outputs, with direct solver reevaluation mandatory at every design stage.</p>

<p>The codebase is now live at <a href="https://github.com/Herr-Professor/Neon">https://github.com/Herr-Professor/Neon</a> and the trained model is available at <a href="https://huggingface.co/Herrprofessor/Neon">https://huggingface.co/Herrprofessor/Neon</a>.</p>

<hr />

<h2 id="the-solver-validation-before-ml">The Solver: Validation Before ML</h2>

<p>A core design principle of Neon is that the direct solver must be validated before any ML layer is trusted. This sounds obvious, but it is easy to skip in practice: if the solver produces outputs that are wrong in a systematic way, every surrogate trained on those outputs learns to predict the wrong thing confidently.</p>

<h3 id="absorber-treatment">Absorber Treatment</h3>

<p>The first major solver upgrade was boundary treatment. Neon’s original sponge absorber — a gradually increasing imaginary permittivity layer that damps outgoing waves — is simple to implement but introduces significant spurious reflections. The standard improvement is the Perfectly Matched Layer (PML), originally introduced for time-domain Maxwell equations by Bérenger <a href="#references">[8]</a> and extended to stretched-coordinate formulations by Chew and Weedon <a href="#references">[9]</a>.</p>

<p>Neon implements a scalar stretched-coordinate PML for the current Helmholtz formulation:</p>

\[\partial_x \left( \frac{s_y}{s_x} \partial_x E \right) + \partial_y \left( \frac{s_x}{s_y} \partial_y E \right) + k_0^2 \varepsilon_r s_x s_y E = s_x s_y f\]

<p>where $s_x$ and $s_y$ are the complex stretching functions. This is not a general Maxwell PML — it is specifically derived for the current scalar Helmholtz formulation, and the outer boundary is still Dirichlet-terminated. But it is materially better than the legacy sponge on the current benchmark. The left reflection ratio drops from <code class="language-plaintext highlighter-rouge">0.1772</code> to <code class="language-plaintext highlighter-rouge">0.0109</code> — a 16.3x reduction — and the right-side backscatter ratio drops from <code class="language-plaintext highlighter-rouge">0.2765</code> to <code class="language-plaintext highlighter-rouge">0.0266</code>, a 10.4x reduction.</p>

<figure class="neon-post-figure">
  <img src="/images/blog/neon/pml_vs_sponge_validation.png" alt="Validation plots comparing scalar PML and sponge absorbers." />
  <figcaption>Scalar PML vs. legacy sponge on the homogeneous benchmark. The PML reduces backscatter contamination by over an order of magnitude on this test case.</figcaption>
</figure>

<h3 id="external-validation-the-tmm-lesson">External Validation: The TMM Lesson</h3>

<p>Once the absorber was in better shape, I wanted to compare Neon’s outputs against an external analytic reference. The Transfer Matrix Method (TMM) is the natural choice for a slab geometry: it gives exact transmission and reflection coefficients for planar multilayer structures at normal incidence, derivable directly from Maxwell’s boundary conditions <a href="#references">[10]</a>.</p>

<p>The first comparison failed badly: mean absolute error of 0.228 in transmission. But the failure was instructive. The signed bias was consistently positive — meaning Neon was systematically <em>overestimating</em> transmission relative to TMM, not scattering randomly around the right answer. That pattern is characteristic of a normalization or output-quantity mismatch, not a solver error.</p>

<p>The root cause was that Neon’s transmission and reflection values were monitor-based proxies: local field amplitude samples decomposed heuristically into forward and backward components at a monitor line. These are useful diagnostics, but they are not rigorous flux-normalized power coefficients. After implementing a proper benchmark-facing scalar normalization for the current lossless normal-incidence slab family, the TMM comparison improves to a mean absolute error of <code class="language-plaintext highlighter-rouge">0.0489</code> and now passes.</p>

<figure class="neon-post-figure">
  <img src="/images/blog/neon/tmm_comparison.png" alt="Scatter plots comparing Neon slab coefficients to TMM." />
  <figcaption>Legacy proxy outputs (left) versus benchmark-facing slab coefficients (right) in the TMM comparison. The normalization fix is what moves the comparison from FAIL to PASS — not a solver change.</figcaption>
</figure>

<p>The lesson is general: <strong>output quantity definition matters as much as model architecture</strong> when training surrogates. A network trained on a systematically biased output quantity will learn the bias, not the physics.</p>

<p>A cross-check against Ceviche <a href="#references">[11]</a> — a differentiable FDFD solver developed by Tyler Hughes and colleagues at Stanford — is less clean. Even after correcting a methodology error (comparing $E_z$ to $E_z$ rather than $E_z$ to $H_z$), the field magnitude correlation is <code class="language-plaintext highlighter-rouge">0.8737</code>. This discrepancy is not yet resolved. It could be grid resolution differences, PML padding mismatches, or source-placement conventions between the two codes. I keep this result in the repository as a documented open question, not a swept-under-the-rug failure.</p>

<hr />

<h2 id="the-ml-layer-three-models-one-question">The ML Layer: Three Models, One Question</h2>

<p>The ML experimentation ladder in Neon has three levels, each adding something to the training formulation.</p>

<p><strong>Model A</strong> is a small PyTorch MLP taking slab thickness, relative permittivity, and wavelength as inputs and returning transmission, reflection, and peak intensity. No physics in the loss. Trained from scratch on 72 simulation samples from 12 slab designs. This is the baseline against which everything else is measured.</p>

<p><strong>Model B</strong> adds a centerline field prediction and a physics-informed loss term: a reduced 1D Helmholtz residual computed along the centerline field, away from crop edges and slab interface points. This connects to the broader PINN framework of Raissi et al. <a href="#references">[7]</a> but is deliberately more modest: it applies only along a 1D cropped centerline, not the full 2D domain, and it uses precomputed solver fields rather than requiring the network to satisfy the PDE from scratch.</p>

<p><strong>Model C</strong> extends Model B with two additional physics-derived penalties:</p>

<ul>
  <li>A <em>boundary-aware loss</em> that penalizes backward-wave energy in a transmitted-side background window near the PML entrance region, derived from the same forward/backward decomposition used by the solver’s postprocessor.</li>
  <li>A <em>source-aware loss</em> that penalizes mismatch to the expected forward plane-wave structure in the source-side background region between the line source and the slab.</li>
</ul>

<p>Both terms are genuinely physics-derived for this specific setup. Neither is a general Maxwell constraint. But they are real, not decorative.</p>

<p>The trained Neon model released on HuggingFace is the Model C checkpoint. It takes thickness, epsilon, and wavelength as inputs and returns transmission, reflection, and intensity:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">neon</span> <span class="kn">import</span> <span class="n">Neon</span>
<span class="n">model</span> <span class="o">=</span> <span class="n">Neon</span><span class="p">.</span><span class="n">from_pretrained</span><span class="p">()</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">model</span><span class="p">.</span><span class="n">predict</span><span class="p">(</span><span class="n">thickness</span><span class="o">=</span><span class="mf">0.30</span><span class="p">,</span> <span class="n">epsilon_real</span><span class="o">=</span><span class="mf">2.25</span><span class="p">,</span> <span class="n">wavelength</span><span class="o">=</span><span class="mf">0.80</span><span class="p">)</span>
<span class="c1"># {"transmission": 0.87, "reflection": 0.09, "intensity": 1.31}
</span></code></pre></div></div>

<hr />

<h2 id="what-the-results-actually-say">What the Results Actually Say</h2>

<p>This is where the project becomes a benchmark platform rather than just a feature stack. The honest answer to “does adding physics to the loss function help?” is: <em>sometimes, and not in the ways you might expect.</em></p>

<h3 id="the-abc-comparison">The A/B/C Comparison</h3>

<p>On the full 72-sample training set, the test mean MAEs are:</p>

<table>
  <thead>
    <tr>
      <th>Model</th>
      <th>Test MAE</th>
      <th>OOD MAE</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>A (baseline)</td>
      <td>0.1548</td>
      <td>0.2627</td>
    </tr>
    <tr>
      <td>B (+ residual)</td>
      <td>0.1616</td>
      <td>0.2802</td>
    </tr>
    <tr>
      <td>C (+ residual + boundary + source)</td>
      <td>0.1522</td>
      <td>0.2653</td>
    </tr>
  </tbody>
</table>

<p>Model C improves on both Model B and slightly on Model A on in-domain test error. It also improves on Model B on OOD. But it still does not beat the simple baseline on OOD — a finding that mirrors cautionary results in the broader physics-informed ML literature, where Krishnapriyan et al. <a href="#references">[12]</a> showed that naive PINN formulations can fail on relatively simple problems, and where Wang et al. <a href="#references">[13]</a> demonstrated that gradient pathologies in multi-term losses can prevent physics terms from contributing meaningfully.</p>

<h3 id="the-ablation-what-is-actually-doing-the-work">The Ablation: What Is Actually Doing the Work</h3>

<p>The component ablation is more informative than the headline comparison. Removing the source-aware term from Model C degrades test MAE from <code class="language-plaintext highlighter-rouge">0.1522</code> to <code class="language-plaintext highlighter-rouge">0.1625</code> and OOD MAE from <code class="language-plaintext highlighter-rouge">0.2653</code> to <code class="language-plaintext highlighter-rouge">0.2704</code>. Removing the boundary-aware term changes almost nothing: <code class="language-plaintext highlighter-rouge">0.1522</code> to <code class="language-plaintext highlighter-rouge">0.1521</code> on test, <code class="language-plaintext highlighter-rouge">0.2653</code> to <code class="language-plaintext highlighter-rouge">0.2651</code> on OOD.</p>

<p><strong>The source-aware term is doing real work. The boundary-aware term is nearly inert at full data.</strong></p>

<p>This is a specific, interpretable finding. The source geometry — knowing where energy enters the domain, and what structure it should have there — is informative supervision that the data alone does not fully provide. The absorber-adjacent region, by contrast, does not carry enough additional signal beyond what the scalar targets already encode, at least in this reduced formulation.</p>

<p>This pattern connects to broader observations in the ML-for-PDE literature. Lagaris et al.’s original neural network approach to boundary value problems <a href="#references">[14]</a> showed that boundary conditions are often the hardest part to enforce. In Neon’s case, the source boundary is harder to ignore (it drives the whole field) and so a source-consistency penalty has more leverage than an absorber-exit penalty.</p>

<figure class="neon-post-figure">
  <img src="/images/blog/neon/model_abc_test_ood.png" alt="A/B/C comparison bar charts." />
  <figcaption>A/B/C comparison including component ablations. The source-aware term is the main active physics contribution; the boundary-aware term shows minimal effect at full data.</figcaption>
</figure>

<h3 id="the-reduced-data-study">The Reduced-Data Study</h3>

<p>The reduced-data ablation sweeps training set sizes from 2 to 12 slab designs across three random seeds:</p>

<table>
  <thead>
    <tr>
      <th>Train Designs</th>
      <th>Model A MAE</th>
      <th>Model B MAE</th>
      <th>Model C MAE</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>2</td>
      <td>0.1723</td>
      <td>0.1712</td>
      <td>0.1734</td>
    </tr>
    <tr>
      <td>4</td>
      <td>0.1490</td>
      <td>0.1392</td>
      <td>0.1394</td>
    </tr>
    <tr>
      <td>6</td>
      <td>0.1673</td>
      <td>0.1591</td>
      <td>0.1579</td>
    </tr>
    <tr>
      <td>8</td>
      <td>0.1657</td>
      <td>0.1651</td>
      <td>0.1628</td>
    </tr>
    <tr>
      <td>10</td>
      <td>0.1640</td>
      <td>0.1645</td>
      <td>0.1623</td>
    </tr>
    <tr>
      <td>12</td>
      <td>0.1548</td>
      <td>0.1616</td>
      <td>0.1522</td>
    </tr>
  </tbody>
</table>

<p>Model C beats Model B in 4/6 settings and beats Model A in 5/6 settings on in-domain test error. But at 2 training designs, Model C is <em>worse</em> than both. This is consistent with the known behavior of physics-informed losses identified by Rathore et al. <a href="#references">[15]</a>: physics constraints require enough data to orient themselves. In the extreme low-data limit, the regularization term competes with rather than complements the data term, because the network has not seen enough examples to place the physics constraint meaningfully in parameter space.</p>

<p>Model C beats Model A on OOD in exactly <strong>0/6</strong> settings. This is the most important result in the table. The physics terms help in-domain. They do not solve the extrapolation problem.</p>

<hr />

<h2 id="uncertainty-and-active-learning">Uncertainty and Active Learning</h2>

<p>The more recent additions to Neon address a different question: not whether to add physics to the loss, but whether the surrogate can tell you <em>when not to trust it</em>.</p>

<h3 id="deep-ensembles">Deep Ensembles</h3>

<p>The uncertainty approach follows Lakshminarayanan, Pritzel, and Blundell’s deep ensemble method <a href="#references">[16]</a>: train five independent MLPs with different random seeds, and use their disagreement as a proxy for predictive uncertainty. This is computationally cheap, does not require architectural changes, and has been shown to produce better-calibrated uncertainty than many more complex Bayesian approaches on tabular regression problems.</p>

<p>The current 5-member ensemble results are:</p>

<table>
  <thead>
    <tr>
      <th>Model</th>
      <th>Test MAE</th>
      <th>OOD MAE</th>
      <th>Test σ</th>
      <th>OOD σ</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>A ensemble</td>
      <td>0.1123</td>
      <td>0.1172</td>
      <td>0.0086</td>
      <td>0.0212</td>
    </tr>
    <tr>
      <td>C ensemble</td>
      <td>0.1155</td>
      <td>0.1293</td>
      <td>0.0129</td>
      <td>0.0258</td>
    </tr>
  </tbody>
</table>

<p>Predictive spread does rise on OOD inputs for both models — the right qualitative behavior. But the uncertainty-error correlation is weak and inconsistent: <code class="language-plaintext highlighter-rouge">-0.0087</code> on test for Model A, <code class="language-plaintext highlighter-rouge">0.2458</code> on OOD for Model C. This means the ensembles are useful as heuristics but cannot be described as calibrated in the sense of Kuleshov, Fenner, and Ermon <a href="#references">[17]</a>, where calibration requires that stated confidence intervals actually contain the true value at the stated frequency.</p>

<h3 id="active-learning">Active Learning</h3>

<p>The active learning workflow follows the standard uncertainty-guided acquisition approach: at each round, evaluate ensemble uncertainty across the full parameter grid, run the direct solver on the highest-uncertainty configuration, add that sample to the training set, and retrain. This connects to the broader active learning literature summarized by Settles <a href="#references">[18]</a> and to recent work on active learning for scientific simulation by Lookman et al. <a href="#references">[19]</a>.</p>

<p>The shipped comparison uses one acquisition seed, 4 initial training designs, and one round adding 2 more designs — a deliberately reduced budget, reported honestly as a pilot rather than a full study.</p>

<p>Results at this budget:</p>

<table>
  <thead>
    <tr>
      <th>Model</th>
      <th>Test MAE (active)</th>
      <th>Test MAE (passive)</th>
      <th>OOD MAE (active)</th>
      <th>OOD MAE (passive)</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>A</td>
      <td>0.1273</td>
      <td>0.1330</td>
      <td>0.1320</td>
      <td>0.1249</td>
    </tr>
    <tr>
      <td>B</td>
      <td>0.1300</td>
      <td>0.1374</td>
      <td>0.1440</td>
      <td>0.1293</td>
    </tr>
    <tr>
      <td>C</td>
      <td>0.1308</td>
      <td>0.1388</td>
      <td>0.1362</td>
      <td>0.1300</td>
    </tr>
  </tbody>
</table>

<p>Active acquisition improves in-domain test MAE for all three models. It <em>hurts</em> OOD MAE for all three. And the interaction between physics-informed losses and active learning is essentially neutral: Model C’s test-gain advantage over Model B from active acquisition is only <code class="language-plaintext highlighter-rouge">+0.0003</code>.</p>

<p>This is a genuine null result. It suggests the two mechanisms — physics regularization and intelligent data collection — address different aspects of the problem without compounding. Whether this holds at larger acquisition budgets and more seeds is an open question and a primary motivation for the paper.</p>

<figure class="neon-post-figure">
  <img src="/images/blog/neon/passive_vs_active_test_ood.png" alt="Passive vs active learning curves." />
  <figcaption>Passive versus uncertainty-guided acquisition at reduced budget. Active acquisition helps in-domain and hurts OOD across all three model families.</figcaption>
</figure>

<hr />

<h2 id="inverse-design-when-better-accuracy-does-not-mean-better-designs">Inverse Design: When Better Accuracy Does Not Mean Better Designs</h2>

<p>The inverse design workflow in Neon is deliberately simple: evaluate a dense grid of slab parameters with the surrogate, rank candidates by predicted target proximity, and rerun the top candidates with the direct solver. This follows the spirit of Malkiel et al.’s surrogate-guided design screening <a href="#references">[20]</a>, with the important addition that all reported design objectives come from direct solver reevaluation, never from the surrogate itself.</p>

<p>The A/B/C design comparison produces an unexpected result:</p>

<table>
  <thead>
    <tr>
      <th>Model</th>
      <th>Best Direct Objective</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>A (baseline)</td>
      <td>0.4732</td>
    </tr>
    <tr>
      <td>B (current hybrid)</td>
      <td>0.1653</td>
    </tr>
    <tr>
      <td>C (enhanced hybrid)</td>
      <td>0.4238</td>
    </tr>
  </tbody>
</table>

<p>Model B — which has <em>worse</em> held-out MAE than Model C — produces the worst design candidate. Model A and Model C both find better designs. This decoupling of surrogate accuracy from design utility is not unique to Neon. Garnett <a href="#references">[21]</a> discusses the general problem of acquisition functions in Bayesian optimization that optimize for prediction accuracy rather than design objectives, and similar disconnects have been noted in materials discovery contexts by Pyzer-Knapp et al. <a href="#references">[22]</a>.</p>

<p>The uncertainty-aware ranking using ensemble disagreement as a conservative acquisition criterion nudges the best Model C candidate from <code class="language-plaintext highlighter-rouge">0.5462</code> (single-model ranking) to <code class="language-plaintext highlighter-rouge">0.5364</code> (ensemble-conservative ranking) — a small improvement, but in the right direction. More importantly, it demonstrates that uncertainty estimates are at least directionally useful for design ranking even when they are not fully calibrated for error prediction.</p>

<hr />

<h2 id="what-is-still-not-solved">What Is Still Not Solved</h2>

<p>Honest accounting of what Neon has not solved is as important as reporting what it has.</p>

<p><strong>The OOD problem is unsolved.</strong> No combination of physics losses, ensemble uncertainty, or active learning in Neon’s current formulation reliably improves OOD generalization over the simple baseline. This is consistent with theoretical arguments in the distribution shift literature — Quinonero-Candela et al. <a href="#references">[23]</a> — that generalization beyond the training distribution requires either structural inductive biases that match the test distribution, or explicit out-of-distribution data during training. Neither is present in Neon’s current setup.</p>

<p><strong>The Ceviche cross-check is unresolved.</strong> A corrected $E_z$-to-$E_z$ comparison still yields a field magnitude correlation of <code class="language-plaintext highlighter-rouge">0.8737</code>. This is documented and tracked, not closed.</p>

<p><strong>The active learning study is a pilot.</strong> One seed, one acquisition round, 3-member ensembles. The broader question — whether uncertainty-guided acquisition produces qualitatively different training distributions that improve OOD behavior at larger budgets — requires the multi-seed, multi-round study described in the paper.</p>

<p><strong>The physics losses are still reduced.</strong> The centerline residual is 1D, not 2D. The boundary and source penalties apply to cropped background windows, not the full domain. Extending these to full-domain constraints — or to a coarse-solver-plus-learned-correction formulation as explored by Bar-Sinai et al. <a href="#references">[24]</a> in fluid dynamics — is the natural next step.</p>

<hr />

<h2 id="why-this-direction-matters">Why This Direction Matters</h2>

<p>Most surrogate modeling papers in photonics are asking: <em>how accurate is our model?</em> Neon is asking something harder: <em>does this training pipeline produce a model you can actually trust?</em></p>

<p>Those are different questions. Accuracy on a held-out test set tells you how well the model interpolates within the training distribution. Trust requires knowing how the model behaves at the boundary of that distribution, what the uncertainty estimates actually mean, whether design objectives derived from the model match direct simulation verification, and whether the physics constraints are doing genuine work or just adding complexity.</p>

<p>The answer Neon gives to these questions is mixed, carefully documented, and I think more useful than a clean positive result would have been. The source-aware physics term helps. The boundary-aware term barely does. Active learning improves in-domain accuracy and hurts OOD robustness at small budgets. Better surrogate MAE does not guarantee better design ranking. Ensemble spread rises on OOD inputs but is not calibrated.</p>

<p>That is what an honest benchmark looks like.</p>

<hr />

<h2 id="what-comes-next-the-paper">What Comes Next: The Paper</h2>

<p>A paper is now in preparation:</p>

<p><em>Toward Trustworthy Surrogate Models for Electromagnetic Simulation: A Systematic Evaluation of Physics-Informed Training, Uncertainty, and Active Learning on a Controlled Benchmark</em></p>

<p>The paper extends the active learning study to multiple seeds and larger acquisition budgets, adds proper calibration curves for the ensemble uncertainty, investigates the Ceviche discrepancy, and formalizes the A/B/C comparison results. The central argument is the one this post has been building toward: the relevant question for simulation-driven surrogate modeling is not accuracy but trustworthiness, and answering it requires the kind of controlled, ablation-driven evaluation that most papers in this space do not currently do.</p>

<hr />

<h2 id="neons-model">Neon’s Model</h2>

<p>The codebase is live at <a href="https://github.com/Herr-Professor/Neon">https://github.com/Herr-Professor/Neon</a>.</p>

<p>The trained Neon model — the best Model C checkpoint from the benchmark study — is available at <a href="https://huggingface.co/Herrprofessor/Neon">https://huggingface.co/Herrprofessor/Neon</a>. The full benchmark checkpoint bundle including ensembles and evaluation summaries is at <a href="https://huggingface.co/Herrprofessor/neon-slab-models">https://huggingface.co/Herrprofessor/neon-slab-models</a>. The slab datasets used for training are at <a href="https://huggingface.co/datasets/Herrprofessor/Neon-Slab-Datasets">https://huggingface.co/datasets/Herrprofessor/Neon-Slab-Datasets</a>.</p>

<p>The model takes dielectric slab parameters and returns optical response predictions in milliseconds:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">neon</span> <span class="kn">import</span> <span class="n">Neon</span>

<span class="n">model</span> <span class="o">=</span> <span class="n">Neon</span><span class="p">.</span><span class="n">from_pretrained</span><span class="p">()</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">model</span><span class="p">.</span><span class="n">predict</span><span class="p">(</span><span class="n">thickness</span><span class="o">=</span><span class="mf">0.30</span><span class="p">,</span> <span class="n">epsilon_real</span><span class="o">=</span><span class="mf">2.25</span><span class="p">,</span> <span class="n">wavelength</span><span class="o">=</span><span class="mf">0.80</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
<span class="c1"># {"transmission": 0.87, "reflection": 0.09, "intensity": 1.31}
</span></code></pre></div></div>

<p>It is not a general photonics model. It covers one geometry class: a rectangular dielectric slab at normal incidence in vacuum, within the parameter ranges described in the repository. Inputs outside that range will trigger a warning. For researchers working with this class of problem — as a fast screener, a baseline comparison, or a reproducibility tool for the paper results — it is a real, usable predictor. For anything else, use the direct solver.</p>

<hr />

<h2 id="references">References</h2>

<p><a name="references"></a></p>

<p>[1] Peurifoy, J., Shen, Y., Jing, L., Yang, Y., Cano-Renteria, F., DeLacy, B. G., … &amp; Soljačić, M. (2018). Nanophotonic particle simulation and inverse design using artificial neural networks. <em>Science Advances</em>, 4(6), eaar4206.</p>

<p>[2] Oskooi, A. F., Roundy, D., Ibanescu, M., Bermel, P., Joannopoulos, J. D., &amp; Johnson, S. G. (2010). Meep: A flexible free-software package for electromagnetic simulations by the FDTD method. <em>Computer Physics Communications</em>, 181(3), 687–702.</p>

<p>[3] Lanteri, S., Scheid, C., &amp; Viquerat, J. (2013). Analysis of a generalized dispersive model coupled to a DGTD method with application to nanophotonics. <em>SIAM Journal on Scientific Computing</em>, 39(3), A831–A859. See also: <a href="https://diogenes.inria.fr/">https://diogenes.inria.fr/</a></p>

<p>[4] Liu, Z., Zhu, D., Rodrigues, S. P., Lee, K. T., &amp; Cai, W. (2018). Generative model for the inverse design of metasurfaces. <em>Nano Letters</em>, 18(10), 6570–6576.</p>

<p>[5] Wiecha, P. R., Arbouet, A., Girard, C., &amp; Muskens, O. L. (2021). Deep learning in nano-photonics: overcoming the computational bottleneck for electromagnetic inverse design using neural networks. <em>Photonics Research</em>, 9(5), B182–B202.</p>

<p>[6] So, S., Mun, J., &amp; Rho, J. (2020). Simultaneous inverse design of materials and structures via deep learning: Demonstration of dipole resonance engineering using core–shell nanoparticles. <em>ACS Applied Materials &amp; Interfaces</em>, 11(24), 24264–24268.</p>

<p>[7] Raissi, M., Perdikaris, P., &amp; Karniadakis, G. E. (2019). Physics-informed neural networks: A deep learning framework for solving forward and inverse problems involving nonlinear partial differential equations. <em>Journal of Computational Physics</em>, 378, 686–707.</p>

<p>[8] Bérenger, J. P. (1994). A perfectly matched layer for the absorption of electromagnetic waves. <em>Journal of Computational Physics</em>, 114(2), 185–200.</p>

<p>[9] Chew, W. C., &amp; Weedon, W. H. (1994). A 3D perfectly matched medium from modified Maxwell’s equations with stretched coordinates. <em>Microwave and Optical Technology Letters</em>, 7(13), 599–604.</p>

<p>[10] Born, M., &amp; Wolf, E. (1999). <em>Principles of Optics: Electromagnetic Theory of Propagation, Interference and Diffraction of Light</em> (7th ed.). Cambridge University Press.</p>

<p>[11] Hughes, T. W., Minkov, M., Williamson, I. A., &amp; Fan, S. (2019). Adjoint method and inverse design for nonlinear nanophotonic devices. <em>ACS Photonics</em>, 5(12), 4781–4787. See also: Minkov, M., Williamson, I. A., Andreani, L. C., Gerace, D., Lou, B., Song, A. Y., … &amp; Fan, S. (2020). Inverse design of photonic crystals through automatic differentiation. <em>ACS Photonics</em>, 7(7), 1729–1741.</p>

<p>[12] Krishnapriyan, A., Gholami, A., Zhe, S., Kirby, R., &amp; Mahoney, M. W. (2021). Characterizing possible failure modes in physics-informed neural networks. <em>Advances in Neural Information Processing Systems</em>, 34, 26548–26560.</p>

<p>[13] Wang, S., Teng, Y., &amp; Perdikaris, P. (2021). Understanding and mitigating gradient flow pathologies in physics-informed neural networks. <em>SIAM Journal on Scientific Computing</em>, 43(5), A3055–A3081.</p>

<p>[14] Lagaris, I. E., Likas, A., &amp; Fotiadis, D. I. (1998). Artificial neural networks for solving ordinary and partial differential equations. <em>IEEE Transactions on Neural Networks</em>, 9(5), 987–1000.</p>

<p>[15] Rathore, P., Lei, W., Frangella, Z., Lu, L., &amp; Udell, M. (2024). Challenges in training PINNs: A loss landscape perspective. <em>arXiv preprint arXiv:2402.01868</em>.</p>

<p>[16] Lakshminarayanan, B., Pritzel, A., &amp; Blundell, C. (2017). Simple and scalable predictive uncertainty estimation using deep ensembles. <em>Advances in Neural Information Processing Systems</em>, 30.</p>

<p>[17] Kuleshov, V., Fenner, N., &amp; Ermon, S. (2018). Accurate uncertainties for deep learning using calibrated regression. <em>International Conference on Machine Learning</em>, 2796–2804.</p>

<p>[18] Settles, B. (2009). Active learning literature survey. <em>University of Wisconsin–Madison Department of Computer Sciences</em>, Technical Report 1648.</p>

<p>[19] Lookman, T., Balachandran, P. V., Xue, D., &amp; Yuan, R. (2019). Active learning in materials science with emphasis on adaptive sampling in experimental design for efficiency. <em>npj Computational Materials</em>, 5(1), 21.</p>

<p>[20] Malkiel, I., Mrejen, M., Nagler, A., Arieli, U., Wolf, L., &amp; Suchowski, H. (2018). Plasmonic nanostructure design and characterization via deep learning. <em>Light: Science &amp; Applications</em>, 7(1), 60.</p>

<p>[21] Garnett, R. (2023). <em>Bayesian Optimization</em>. Cambridge University Press.</p>

<p>[22] Pyzer-Knapp, E. O., Li, K., &amp; Aspuru-Guzik, A. (2015). Learning from the Harvard Clean Energy Project: The use of neural networks to accelerate materials discovery. <em>Advanced Functional Materials</em>, 25(41), 6495–6502.</p>

<p>[23] Quiñonero-Candela, J., Sugiyama, M., Schwaighofer, A., &amp; Lawrence, N. D. (Eds.). (2009). <em>Dataset Shift in Machine Learning</em>. MIT Press.</p>

<p>[24] Bar-Sinai, Y., Hoyer, S., Hickey, J., &amp; Brenner, M. P. (2019). Learning data-driven discretizations for partial differential equations. <em>Proceedings of the National Academy of Sciences</em>, 116(31), 15344–15349.</p>]]></content><author><name>Farouq Oguntoye</name><email>farouqoguntoye05@gmail.com</email></author><category term="neon" /><category term="computational photonics" /><category term="surrogate modeling" /><category term="numerical methods" /><category term="physics-informed machine learning" /><category term="uncertainty quantification" /><summary type="html"><![CDATA[A detailed account of Neon — a scalar Helmholtz solver and ML research platform built to answer one question honestly: does this training pipeline produce a surrogate model you can actually trust?]]></summary></entry><entry><title type="html">Nanophotonics - Light at the Edge of the Invisible</title><link href="https://herr-professor.github.io/blog/nanophotonics/" rel="alternate" type="text/html" title="Nanophotonics - Light at the Edge of the Invisible" /><published>2026-03-22T00:00:00+00:00</published><updated>2026-03-22T00:00:00+00:00</updated><id>https://herr-professor.github.io/blog/nanophotonics</id><content type="html" xml:base="https://herr-professor.github.io/blog/nanophotonics/"><![CDATA[<style>
  .feature-post {
    width: 100%;
  }

  .feature-post .page__inner-wrap {
    width: 100%;
  }

  .feature-post .page__content,
  .feature-post .page__meta,
  .feature-post .page__share {
    width: 100%;
  }

  .feature-post .page__content {
    margin: 0;
  }

  .feature-post .page__content h2 {
    border-bottom: 0;
    padding-bottom: 0;
  }

  .feature-post .page__meta,
  .feature-post .page__share,
  .feature-post .page__related {
    max-width: 1100px;
    margin-left: auto;
    margin-right: auto;
    padding-left: 8vw;
    padding-right: 8vw;
  }

  .nano-post {
    --bg: #05080f;
    --surface: #0a0f1e;
    --surface2: #0f1628;
    --accent: #4af4c8;
    --accent2: #a78bfa;
    --accent3: #f472b6;
    --text: #e8eaf2;
    --muted: #7a8299;
    --line: rgba(74, 244, 200, 0.15);
    position: relative;
    background: var(--bg);
    color: var(--text);
    font-family: "Cormorant Garamond", serif;
    font-size: 20px;
    line-height: 1.75;
    margin: -2em calc(50% - 50vw) 0;
    width: 100vw;
    overflow-x: hidden;
  }

  .nano-post::before {
    content: "";
    position: fixed;
    inset: 0;
    background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 512 512' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.75' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.04'/%3E%3C/svg%3E");
    pointer-events: none;
    z-index: 1;
    opacity: 0.35;
  }

  .nano-post * {
    box-sizing: border-box;
  }

  .nano-post a {
    color: inherit;
  }

  .nano-post .hero {
    position: relative;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    padding: 0 8vw 7vh;
    overflow: hidden;
  }

  .nano-post .hero-canvas {
    position: absolute;
    inset: 0;
    z-index: 0;
  }

  .nano-post .hero-meta {
    position: relative;
    z-index: 2;
  }

  .nano-post .hero-label {
    font-family: "DM Mono", monospace;
    font-size: 11px;
    letter-spacing: 0.25em;
    text-transform: uppercase;
    color: var(--accent);
    margin-bottom: 1.5rem;
    opacity: 0;
    animation: fadeUp 1s 0.3s forwards;
  }

  .nano-post .hero h1 {
    font-family: "Syne", sans-serif;
    font-weight: 800;
    font-size: clamp(3rem, 9vw, 8rem);
    line-height: 0.92;
    letter-spacing: -0.03em;
    margin: 0;
    opacity: 0;
    animation: fadeUp 1s 0.5s forwards;
  }

  .nano-post .hero h1 em {
    font-style: italic;
    font-weight: 400;
    color: var(--accent);
    font-family: "Cormorant Garamond", serif;
    font-size: 1.15em;
  }

  .nano-post .hero-sub {
    font-style: italic;
    font-size: clamp(1.1rem, 2.5vw, 1.6rem);
    color: var(--muted);
    margin-top: 2rem;
    max-width: 55ch;
    opacity: 0;
    animation: fadeUp 1s 0.7s forwards;
  }

  .nano-post .hero-divider {
    width: 60px;
    height: 1px;
    background: var(--accent);
    margin: 2.5rem 0 1rem;
    opacity: 0;
    animation: fadeUp 1s 0.9s forwards;
  }

  .nano-post .hero-byline {
    font-family: "DM Mono", monospace;
    font-size: 11px;
    letter-spacing: 0.15em;
    color: var(--muted);
    opacity: 0;
    animation: fadeUp 1s 1.1s forwards;
  }

  .nano-post .article {
    max-width: 1100px;
    margin: 0 auto;
    padding: 0 8vw;
    position: relative;
    z-index: 2;
  }

  .nano-post .opener {
    padding: 8vh 0 4vh;
    border-top: 1px solid var(--line);
    margin-top: 6vh;
  }

  .nano-post .opener blockquote {
    font-size: clamp(1.5rem, 3.5vw, 2.4rem);
    font-weight: 300;
    font-style: italic;
    line-height: 1.4;
    color: var(--text);
    position: relative;
    padding-left: 2.5rem;
    border-left: 2px solid var(--accent);
    max-width: 38ch;
    margin: 0;
  }

  .nano-post .section {
    padding: 6vh 0;
    border-top: 1px solid var(--line);
  }

  .nano-post .section-label {
    font-family: "DM Mono", monospace;
    font-size: 10px;
    letter-spacing: 0.3em;
    text-transform: uppercase;
    color: var(--accent);
    margin-bottom: 1.5rem;
    display: flex;
    align-items: center;
    gap: 1rem;
  }

  .nano-post .section-label::after {
    content: "";
    flex: 1;
    height: 1px;
    background: var(--line);
    max-width: 80px;
  }

  .nano-post .section h2 {
    font-family: "Syne", sans-serif;
    font-weight: 700;
    font-size: clamp(1.6rem, 4vw, 2.8rem);
    line-height: 1.1;
    letter-spacing: -0.02em;
    margin-bottom: 2rem;
  }

  .nano-post .section h2 span {
    color: var(--accent2);
  }

  .nano-post .section p {
    font-size: clamp(1rem, 1.8vw, 1.2rem);
    color: #c9ccdb;
    line-height: 1.85;
    margin-bottom: 1.4rem;
    max-width: 68ch;
  }

  .nano-post .section p strong {
    color: var(--text);
    font-weight: 600;
  }

  .nano-post .cards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 1.5px;
    margin: 3rem 0;
    background: var(--line);
    border: 1px solid var(--line);
  }

  .nano-post .card {
    background: var(--surface);
    padding: 2rem 1.8rem;
    position: relative;
    overflow: hidden;
    transition: background 0.3s;
  }

  .nano-post .card:hover { background: var(--surface2); }

  .nano-post .card::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 2px;
    background: linear-gradient(90deg, var(--accent), transparent);
    opacity: 0;
    transition: opacity 0.3s;
  }

  .nano-post .card:hover::before { opacity: 1; }

  .nano-post .card-num {
    font-family: "DM Mono", monospace;
    font-size: 10px;
    letter-spacing: 0.2em;
    color: var(--accent);
    margin-bottom: 0.75rem;
  }

  .nano-post .card h3 {
    font-family: "Syne", sans-serif;
    font-weight: 700;
    font-size: 1.1rem;
    margin-bottom: 0.75rem;
    letter-spacing: -0.01em;
  }

  .nano-post .card p {
    font-size: 0.92rem !important;
    line-height: 1.65 !important;
    color: var(--muted) !important;
    margin: 0 !important;
    max-width: none !important;
  }

  .nano-post .callout {
    background: var(--surface);
    border: 1px solid var(--line);
    border-left: 3px solid var(--accent2);
    padding: 2rem 2.5rem;
    margin: 3rem 0;
    position: relative;
  }

  .nano-post .callout-head {
    font-family: "DM Mono", monospace;
    font-size: 10px;
    letter-spacing: 0.25em;
    text-transform: uppercase;
    color: var(--accent2);
    margin-bottom: 0.8rem;
  }

  .nano-post .callout p {
    font-size: 1rem !important;
    color: #b0b4c8 !important;
    margin: 0 !important;
    max-width: none !important;
  }

  .nano-post .spectrum {
    margin: 3rem 0;
    padding: 2rem;
    background: var(--surface);
    border: 1px solid var(--line);
  }

  .nano-post .spectrum-label {
    font-family: "DM Mono", monospace;
    font-size: 10px;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--muted);
    margin-bottom: 1.5rem;
  }

  .nano-post .spectrum-bar {
    height: 28px;
    border-radius: 2px;
    background: linear-gradient(90deg,
      #7b2fff 0%,
      #4f5bff 8%,
      #4af4c8 20%,
      #6aff6a 32%,
      #faff4a 45%,
      #ff9a2f 58%,
      #ff4747 72%,
      #cc2020 85%,
      #880000 100%
    );
    position: relative;
  }

  .nano-post .spectrum-ticks {
    display: flex;
    justify-content: space-between;
    margin-top: 0.75rem;
    font-family: "DM Mono", monospace;
    font-size: 9px;
    color: var(--muted);
    letter-spacing: 0.05em;
  }

  .nano-post .nano-region {
    position: absolute;
    top: -36px;
    left: 0%;
    width: 72%;
    height: 28px;
    border: 1px dashed rgba(74, 244, 200, 0.4);
    border-bottom: none;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .nano-post .nano-region span {
    font-family: "DM Mono", monospace;
    font-size: 9px;
    color: var(--accent);
    letter-spacing: 0.12em;
    background: var(--surface);
    padding: 0 6px;
    white-space: nowrap;
  }

  .nano-post .stat-row {
    display: flex;
    gap: 3rem;
    flex-wrap: wrap;
    margin: 3rem 0;
    padding: 2.5rem 0;
    border-top: 1px solid var(--line);
    border-bottom: 1px solid var(--line);
  }

  .nano-post .stat {
    flex: 1;
    min-width: 150px;
  }

  .nano-post .stat-num {
    font-family: "Syne", sans-serif;
    font-size: clamp(2.5rem, 5vw, 4rem);
    font-weight: 800;
    line-height: 1;
    letter-spacing: -0.04em;
    background: linear-gradient(135deg, var(--accent), var(--accent2));
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
  }

  .nano-post .stat-label {
    font-family: "DM Mono", monospace;
    font-size: 10px;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--muted);
    margin-top: 0.5rem;
  }

  .nano-post .app-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1.5px;
    background: var(--line);
    border: 1px solid var(--line);
    margin: 3rem 0;
  }

  .nano-post .app-cell {
    background: var(--surface);
    padding: 2.2rem 2rem;
    transition: background 0.3s;
    cursor: default;
  }

  .nano-post .app-cell:hover { background: var(--surface2); }

  .nano-post .app-icon {
    font-size: 2rem;
    margin-bottom: 1rem;
    display: block;
  }

  .nano-post .app-cell h3 {
    font-family: "Syne", sans-serif;
    font-size: 1rem;
    font-weight: 700;
    letter-spacing: -0.01em;
    margin-bottom: 0.6rem;
    color: var(--text);
  }

  .nano-post .app-cell p {
    font-size: 0.88rem !important;
    color: var(--muted) !important;
    line-height: 1.65 !important;
    margin: 0 !important;
    max-width: none !important;
  }

  .nano-post .timeline {
    margin: 3rem 0;
    position: relative;
    padding-left: 2rem;
  }

  .nano-post .timeline::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.5rem;
    bottom: 0;
    width: 1px;
    background: linear-gradient(to bottom, var(--accent), transparent);
  }

  .nano-post .timeline-item {
    position: relative;
    margin-bottom: 2rem;
    padding-left: 1.5rem;
  }

  .nano-post .timeline-item::before {
    content: "";
    position: absolute;
    left: -2rem;
    top: 0.55rem;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--accent);
    box-shadow: 0 0 10px var(--accent);
  }

  .nano-post .timeline-year {
    font-family: "DM Mono", monospace;
    font-size: 10px;
    letter-spacing: 0.2em;
    color: var(--accent);
    margin-bottom: 0.3rem;
  }

  .nano-post .timeline-title {
    font-family: "Syne", sans-serif;
    font-weight: 700;
    font-size: 1rem;
    margin-bottom: 0.3rem;
  }

  .nano-post .timeline-desc {
    font-size: 0.9rem;
    color: var(--muted);
    line-height: 1.6;
    max-width: 55ch;
  }

  .nano-post .refs {
    list-style: none;
    display: grid;
    gap: 1rem;
    margin-top: 2rem;
    padding: 0;
  }

  .nano-post .refs li {
    padding: 1rem 1.2rem;
    border: 1px solid var(--line);
    background: var(--surface);
    font-size: 0.95rem;
    line-height: 1.6;
    color: #c9ccdb;
  }

  .nano-post .refs a {
    color: var(--accent);
    text-decoration: none;
  }

  .nano-post .refs a:hover {
    text-decoration: underline;
  }

  .nano-post .article-footer {
    border-top: 1px solid var(--line);
    padding: 5vh 0 8vh;
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
    flex-wrap: wrap;
    gap: 2rem;
  }

  .nano-post .footer-sig {
    font-style: italic;
    font-size: 1.4rem;
    color: var(--muted);
  }

  .nano-post .footer-tag {
    font-family: "DM Mono", monospace;
    font-size: 10px;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--accent);
  }

  .nano-post .wave {
    padding: 2rem 0 0;
    overflow: hidden;
    height: 4px;
    background: linear-gradient(90deg, transparent, var(--accent), var(--accent2), var(--accent3), transparent);
    margin: 4vh 0;
    opacity: 0.4;
  }

  @media (max-width: 600px) {
    .nano-post {
      font-size: 18px;
    }

    .nano-post .app-grid {
      grid-template-columns: 1fr;
    }

    .feature-post .page__meta,
    .feature-post .page__share,
    .feature-post .page__related {
      padding-left: 1.5rem;
      padding-right: 1.5rem;
    }
  }

  @keyframes fadeUp {
    from { opacity: 0; transform: translateY(24px); }
    to { opacity: 1; transform: translateY(0); }
  }

  .nano-post .reveal {
    opacity: 0;
    transform: translateY(20px);
    transition: opacity 0.8s ease, transform 0.8s ease;
  }

  .nano-post .reveal.visible {
    opacity: 1;
    transform: translateY(0);
  }

  .feature-post {
    width: auto;
  }

  .feature-post .page__inner-wrap,
  .feature-post .page__content,
  .feature-post .page__meta,
  .feature-post .page__share {
    width: auto;
    max-width: none;
  }

  .nano-post {
    --bg: transparent;
    --surface: #ffffff;
    --surface2: #f7f8fa;
    --accent: #2563eb;
    --accent2: #0f766e;
    --accent3: #7c3aed;
    --text: #1f2937;
    --muted: #6b7280;
    --line: rgba(15, 23, 42, 0.12);
    background: transparent;
    color: var(--text);
    font-family: inherit;
    font-size: 1rem;
    line-height: 1.8;
    margin: 0;
    width: auto;
    overflow: visible;
  }

  .nano-post::before,
  .nano-post .hero-canvas,
  .nano-post .hero-label,
  .nano-post .hero-divider,
  .nano-post .hero-byline,
  .nano-post .wave,
  .nano-post .article-footer {
    display: none;
  }

  .nano-post .hero,
  .nano-post .article {
    max-width: none;
    padding: 0;
  }

  .nano-post .hero {
    min-height: 0;
    display: block;
    margin-bottom: 2rem;
  }

  .nano-post .hero h1,
  .nano-post .hero h1 em,
  .nano-post .section h2,
  .nano-post .card h3,
  .nano-post .timeline-title,
  .nano-post .app-cell h3 {
    font-family: inherit;
    color: var(--text);
  }

  .nano-post .hero h1 {
    font-size: clamp(2rem, 5vw, 3rem);
    line-height: 1.15;
    letter-spacing: -0.03em;
    opacity: 1;
    animation: none;
  }

  .nano-post .hero h1 em {
    font-style: normal;
    font-weight: inherit;
    font-size: inherit;
  }

  .nano-post .hero-sub,
  .nano-post .section p,
  .nano-post .timeline-desc,
  .nano-post .app-cell p,
  .nano-post .card p,
  .nano-post .callout p,
  .nano-post .refs li {
    color: var(--text);
    font-style: normal;
    opacity: 1;
    animation: none;
  }

  .nano-post .opener,
  .nano-post .section {
    border-top: 1px solid var(--line);
    padding: 2rem 0;
    margin-top: 0;
  }

  .nano-post .opener blockquote {
    color: var(--text);
    font-size: 1.35rem;
    border-left-color: var(--accent);
    max-width: 42rem;
  }

  .nano-post .section-label,
  .nano-post .callout-head,
  .nano-post .spectrum-label,
  .nano-post .stat-label,
  .nano-post .timeline-year,
  .nano-post .card-num {
    color: var(--muted);
  }

  .nano-post .section-label::after,
  .nano-post .timeline::before {
    background: var(--line);
  }

  .nano-post .cards,
  .nano-post .app-grid {
    gap: 1rem;
    background: transparent;
    border: 0;
  }

  .nano-post .card,
  .nano-post .callout,
  .nano-post .spectrum,
  .nano-post .app-cell,
  .nano-post .refs li {
    background: var(--surface);
    border: 1px solid #e5e7eb;
    box-shadow: none;
  }

  .nano-post .card:hover,
  .nano-post .app-cell:hover {
    background: var(--surface);
  }

  .nano-post .card::before {
    display: none;
  }

  .nano-post .callout {
    border-left: 4px solid var(--accent);
  }

  .nano-post .spectrum-bar {
    border-radius: 6px;
  }

  .nano-post .stat-row {
    padding: 1.75rem 0;
    gap: 2rem;
    border-color: var(--line);
  }

  .nano-post .stat-num {
    background: none;
    color: var(--accent);
    -webkit-text-fill-color: initial;
  }

  .nano-post .timeline-item::before {
    background: var(--accent);
    box-shadow: none;
  }

  .nano-post .refs {
    padding-left: 1.2rem;
  }

  .nano-post .refs li {
    margin-bottom: 0.8rem;
  }

  .nano-post .reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
</style>

<article class="nano-post">
  <main class="article">
    <div class="opener reveal">
      <blockquote>
        "Light is not merely what we see by - it is one of matter's most versatile messengers, and nanophotonics is about learning how to intercept, compress, and redirect that message at extraordinarily small scales."
      </blockquote>
    </div>

    <section class="section reveal">
      <p class="section-label">01 - Introduction</p>
      <h2>What is <span>Nanophotonics</span>?</h2>
      <p>
        Nanophotonics, sometimes called nano-optics, is the study and manipulation of light using structures measured in nanometers, typically from a few nanometers up to roughly the wavelength scale. A human hair is about 80,000 nanometers wide. Nanophotonics works in a regime so small that ordinary far-field optical intuition starts to fail.
      </p>
      <p>
        Classical optics explains reflection, refraction, focusing, and image formation with remarkable power. But when optical structures shrink toward or below the wavelength of light, geometry, material response, near-field coupling, and sometimes quantum effects begin to dominate. The result is a different design space entirely: one in which light can be confined more tightly, routed more precisely, and coupled more efficiently to matter than conventional lenses and mirrors allow.
      </p>
      <p>
        This is the territory of nanophotonics. It sits at the intersection of electromagnetism, materials science, nanofabrication, and quantum engineering. Researchers in the field build surfaces, cavities, particles, and waveguides that can squeeze optical fields into deep-subwavelength volumes, guide photons through patterned chips, and tailor how emitters absorb or release light.
      </p>

      <div class="callout reveal">
        <p class="callout-head">Key Concept - The Diffraction Limit</p>
        <p>In conventional far-field optics, the <strong>diffraction limit</strong> prevents light from being focused to an arbitrarily small spot. For visible wavelengths, that usually means a best-case focal size on the order of a few hundred nanometers. Nanophotonics gets around this not by violating Maxwell's equations, but by exploiting near-field coupling, plasmonic confinement, resonant nanostructures, and engineered materials.</p>
      </div>
    </section>

    <section class="section reveal">
      <p class="section-label">02 - The Physics</p>
      <h2>The Mechanisms <span>Beneath the Surface</span></h2>
      <p>
        Nanophotonics is not one trick or one material platform. It is a collection of physical mechanisms that let researchers manipulate electromagnetic fields beyond the reach of conventional optics.
      </p>

      <div class="spectrum">
        <p class="spectrum-label">Electromagnetic spectrum - common nanophotonic operating range</p>
        <div style="position: relative; margin-bottom: 50px;">
          <div class="nano-region"><span>Typical nanophotonic range (UV to near-IR)</span></div>
          <div class="spectrum-bar"></div>
        </div>
        <div class="spectrum-ticks">
          <span>Gamma</span>
          <span>X-ray</span>
          <span>UV</span>
          <span>Visible</span>
          <span>Near-IR</span>
          <span>Mid-IR</span>
          <span>Microwave</span>
          <span>Radio</span>
        </div>
      </div>

      <div class="cards">
        <div class="card">
          <p class="card-num">MECHANISM 01</p>
          <h3>Surface Plasmon Resonance</h3>
          <p>At a metal surface, light can drive collective oscillations of electrons known as plasmons. In metallic nanoparticles and nanogaps, these resonances can generate intense local fields and confinement well below the diffraction limit, which is why plasmonics is central to nanoscale sensing and spectroscopy.</p>
        </div>
        <div class="card">
          <p class="card-num">MECHANISM 02</p>
          <h3>Photonic Bandgaps and Crystal Engineering</h3>
          <p>Photonic crystals are periodic dielectric structures that shape how light propagates. By engineering a photonic bandgap, researchers can block certain wavelengths, create compact cavities, and guide light through patterned defects with high precision and, in well-designed structures, low loss.</p>
        </div>
        <div class="card">
          <p class="card-num">MECHANISM 03</p>
          <h3>Near-Field Optics</h3>
          <p>Very close to a source or surface, light behaves differently from the propagating waves familiar from ordinary imaging. Near-field optical techniques can resolve features well below the diffraction limit, with 10-20 nm resolution common in advanced implementations and even finer performance possible in specialized systems.</p>
        </div>
        <div class="card">
          <p class="card-num">MECHANISM 04</p>
          <h3>Mie Resonances in Dielectrics</h3>
          <p>High-index dielectric nanoparticles can support strong resonances without the absorption penalty of metals. Silicon and titanium-dioxide resonators, for example, can shape electric and magnetic optical responses simultaneously, making them attractive for metasurfaces, imaging components, and low-loss nanophotonic devices.</p>
        </div>
        <div class="card">
          <p class="card-num">MECHANISM 05</p>
          <h3>Quantum Confinement</h3>
          <p>When semiconductors shrink to nanocrystal dimensions, electronic energy levels become quantized. In quantum dots, the emission wavelength can be tuned by size, composition, and structure, which is why they are useful for displays, lasers, imaging probes, and single-photon platforms.</p>
        </div>
        <div class="card">
          <p class="card-num">MECHANISM 06</p>
          <h3>Metamaterials and Metasurfaces</h3>
          <p>Metamaterials use carefully patterned subwavelength structures to create optical responses not found in ordinary bulk materials. Their two-dimensional cousins, metasurfaces, can replace bulky optics with flat devices that focus, steer, or shape light on a surface only hundreds of nanometers thick.</p>
        </div>
      </div>
    </section>

    <div class="stat-row reveal">
      <div class="stat">
        <div class="stat-num">1-10 nm</div>
        <div class="stat-label">Light confinement reported in plasmonic nanogaps</div>
      </div>
      <div class="stat">
        <div class="stat-num">10-20 nm</div>
        <div class="stat-label">A representative near-field optical imaging scale</div>
      </div>
      <div class="stat">
        <div class="stat-num">&gt;100 GHz</div>
        <div class="stat-label">Bandwidth demonstrated in advanced nanophotonic modulators</div>
      </div>
      <div class="stat">
        <div class="stat-num">1987</div>
        <div class="stat-label">Foundational year for photonic bandgap proposals</div>
      </div>
    </div>

    <section class="section reveal">
      <p class="section-label">03 - Brief History</p>
      <h2>A Field Born <span>From Curiosity</span></h2>
      <p>
        Nanophotonics did not arrive in a single leap. It emerged as theory, microscopy, nanofabrication, and semiconductor processing gradually converged to make nanoscale optical structures both understandable and manufacturable.
      </p>

      <div class="timeline reveal">
        <div class="timeline-item">
          <p class="timeline-year">1873</p>
          <p class="timeline-title">Abbe Diffraction Limit</p>
          <p class="timeline-desc">Ernst Abbe formalizes the resolution limit of classical optical microscopy, establishing the barrier later generations would spend decades trying to work around.</p>
        </div>
        <div class="timeline-item">
          <p class="timeline-year">1908</p>
          <p class="timeline-title">Mie Scattering Theory</p>
          <p class="timeline-desc">Gustav Mie derives exact solutions for the scattering of electromagnetic waves by spherical particles, laying mathematical foundations that still underpin nanoparticle optics.</p>
        </div>
        <div class="timeline-item">
          <p class="timeline-year">1974</p>
          <p class="timeline-title">Discovery of SERS</p>
          <p class="timeline-desc">Surface-enhanced Raman scattering reveals that rough metallic surfaces can amplify local fields dramatically, foreshadowing the power of plasmonic confinement.</p>
        </div>
        <div class="timeline-item">
          <p class="timeline-year">1981</p>
          <p class="timeline-title">Scanning Tunneling Microscopy</p>
          <p class="timeline-desc">Atomic-scale imaging becomes practical, making the nanoscale experimentally tangible rather than purely theoretical.</p>
        </div>
        <div class="timeline-item">
          <p class="timeline-year">1987</p>
          <p class="timeline-title">Photonic Bandgap Proposals</p>
          <p class="timeline-desc">Eli Yablonovitch and Sajeev John independently publish seminal papers arguing that structured dielectrics can control the optical density of states and localize light in powerful new ways.</p>
        </div>
        <div class="timeline-item">
          <p class="timeline-year">1998</p>
          <p class="timeline-title">Extraordinary Optical Transmission</p>
          <p class="timeline-desc">Thomas Ebbesen and colleagues show that metallic films pierced with subwavelength hole arrays can transmit far more light than classical aperture theory predicts, energizing plasmonics.</p>
        </div>
        <div class="timeline-item">
          <p class="timeline-year">2000s</p>
          <p class="timeline-title">Quantum Dots Go Commercial</p>
          <p class="timeline-desc">Quantum-dot materials move from laboratory research into displays, imaging tools, and light-emitting technologies, proving that nanoscale optical engineering can scale into real products.</p>
        </div>
        <div class="timeline-item">
          <p class="timeline-year">2010s to Present</p>
          <p class="timeline-title">Metalenses, Silicon Photonics, Integrated Optics</p>
          <p class="timeline-desc">Flat optics, photonic chips, compact modulators, and nanostructured sensors move from demonstration to deployment in data links, imaging systems, sensing platforms, and advanced computation research.</p>
        </div>
      </div>
    </section>

    <section class="section reveal">
      <p class="section-label">04 - Real-World Impact</p>
      <h2>Where Nanophotonics <span>Meets the World</span></h2>
      <p>
        Nanophotonics is no longer just a laboratory discipline. It is increasingly a platform technology: one that shows up quietly inside devices for communication, imaging, sensing, and information processing.
      </p>

      <div class="app-grid reveal">
        <div class="app-cell">
          <span class="app-icon">🔬</span>
          <h3>Medical Diagnostics and Biosensing</h3>
          <p>Plasmonic and nanophotonic biosensors can detect tiny refractive-index changes and weak spectroscopic signals, making them promising for compact diagnostic systems. The long-term appeal is obvious: highly sensitive detection in devices far smaller than conventional benchtop optical instruments.</p>
        </div>
        <div class="app-cell">
          <span class="app-icon">💻</span>
          <h3>Optical Interconnects and Computing</h3>
          <p>Silicon photonics is already replacing some electrical interconnects in bandwidth-hungry environments. Beyond communication, research prototypes in optical and photonic neural computing have reported throughput from the tens to hundreds of tera-operations per second, though the practical comparison to electronic systems still depends strongly on task and architecture.</p>
        </div>
        <div class="app-cell">
          <span class="app-icon">🌞</span>
          <h3>Solar Energy Harvesting</h3>
          <p>Nanostructured surfaces and resonators can trap and recycle light inside thin photovoltaic layers, increasing effective absorption without simply making the device thicker. That matters most for lightweight or flexible solar technologies, where material thickness is expensive.</p>
        </div>
        <div class="app-cell">
          <span class="app-icon">📷</span>
          <h3>Flat Optics and Metalenses</h3>
          <p>Metasurface lenses can focus and shape light in an ultrathin format, offering an alternative to the thick stacks of curved glass used in conventional optics. They are especially attractive where size, weight, and integration matter, such as compact cameras, augmented reality hardware, and miniature imaging systems.</p>
        </div>
        <div class="app-cell">
          <span class="app-icon">🔐</span>
          <h3>Quantum Communication</h3>
          <p>Nanophotonic cavities and waveguides can strengthen the interaction between single photons and quantum emitters. That makes them relevant to quantum repeaters, on-chip quantum optics, and quantum key distribution, where the goal is not magical invulnerability but information-theoretically secure protocols implemented with carefully engineered hardware.</p>
        </div>
        <div class="app-cell">
          <span class="app-icon">🚗</span>
          <h3>LiDAR and Autonomous Sensing</h3>
          <p>Solid-state beam steering based on nanophotonic optical phased arrays could eventually replace bulkier moving-part LiDAR assemblies. If those systems mature, they offer a path toward smaller, faster, and potentially more manufacturable sensing stacks.</p>
        </div>
      </div>
    </section>

    <section class="section reveal">
      <p class="section-label">05 - Open Challenges</p>
      <h2>What Remains <span>Unsolved</span></h2>
      <p>
        For all its promise, nanophotonics still faces hard physical and engineering limits.
      </p>
      <p>
        <strong>Ohmic loss in metals</strong> remains a central problem for plasmonics. The same free electrons that make metallic confinement possible also dissipate energy as heat, which is a serious penalty for long propagation distances and low-power devices.
      </p>
      <p>
        <strong>Fabrication precision and scalability</strong> are equally important. Many high-performance devices demand feature sizes in the tens of nanometers or below. That is feasible in research settings, but reproducible, high-yield, low-cost manufacturing is much harder.
      </p>
      <p>
        <strong>Integration with electronics</strong> is one of the field's great commercial opportunities and one of its messiest engineering challenges. Efficient coupling, thermal management, packaging, and co-design with electronics all matter as much as the optical device itself.
      </p>
      <p>
        <strong>Quantum coherence</strong> remains delicate. Nanophotonic quantum devices are highly sensitive to disorder, charge noise, surface defects, and thermal fluctuations, which makes room-temperature, scalable quantum photonic hardware a difficult target.
      </p>

      <div class="callout reveal">
        <p class="callout-head">Frontier Watch - Topological Photonics</p>
        <p>Topological photonics is often presented as a route to defect-immune transport, and it is an exciting direction. But the strongest version of that claim is not settled. Recent experiments on valley-Hall photonic waveguides have shown that topological design can improve robustness in some cases while still suffering measurable backscattering and propagation loss. In other words: promising, but not a free pass around absorption, fabrication disorder, or all defect classes.</p>
      </div>
    </section>

    <section class="section reveal">
      <p class="section-label">06 - What Comes Next</p>
      <h2>The Future <span>Is Photonic</span></h2>
      <p>
        The broad direction is clear even if the timeline is not: more of the functions once handled by bulky optics or electrical wiring are moving into compact photonic structures patterned directly onto chips and surfaces.
      </p>
      <p>
        <strong>Photonic neural and analog processors</strong> are a compelling example. Several research systems now report very high throughput and energy efficiency in specialized workloads, suggesting that optical hardware may become an important complement to electronic accelerators in bandwidth-intensive tasks.
      </p>
      <p>
        <strong>Nano-optomechanics</strong> is another frontier, coupling optical fields to mechanical motion so strongly that tiny resonators can be cooled, measured, and controlled at or near the quantum regime. That could matter for sensing, transduction, and hybrid quantum systems.
      </p>
      <p>
        <strong>Active metasurfaces</strong> are moving beyond static flat optics. By combining nanostructures with tunable materials, researchers are building surfaces that can steer beams, refocus, or reconfigure their optical function dynamically.
      </p>
      <p>
        The bolder historical claim is still worth making carefully: if the twentieth century was shaped by mastering electrons in semiconductors, part of the twenty-first may be shaped by mastering photons in nanostructures.
      </p>
    </section>

    <section class="section reveal">
      <p class="section-label">07 - Selected References</p>
      <h2>Where These Ideas <span>Come From</span></h2>
      <p>
        This essay is written as a high-level science article rather than a technical review, but the key claims above were tightened against foundational and recent primary sources.
      </p>

      <ul class="refs">
        <li>Eli Yablonovitch, "Inhibited Spontaneous Emission in Solid-State Physics and Electronics" (1987), <a href="https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.58.2059">Physical Review Letters</a>.</li>
        <li>Sajeev John, "Strong localization of photons in certain disordered dielectric superlattices" (1987), <a href="https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.58.2486">Physical Review Letters</a>.</li>
        <li>Thomas W. Ebbesen et al., "Extraordinary optical transmission through sub-wavelength hole arrays" (1998), <a href="https://www.nature.com/articles/35570">Nature</a>.</li>
        <li>Sara Ek et al., "Slow-light-enhanced gain in active photonic crystal waveguides" (2014), <a href="https://www.nature.com/articles/ncomms6039">Nature Communications</a>.</li>
        <li>Thomas Barczyk et al., "Observation of strong backscattering in valley-Hall photonic topological interface modes" (2023), <a href="https://www.nature.com/articles/s41566-023-01189-x">Nature Photonics</a>.</li>
        <li>Xing Lin et al., "11 TOPS photonic convolutional accelerator for optical neural networks" (2021), <a href="https://www.nature.com/articles/s41586-020-03063-0">Nature</a>.</li>
        <li>Cheng Guo et al., "Scalable photonic reservoir computing for parallel machine learning tasks" (2025), <a href="https://www.nature.com/articles/s41467-025-67983-z">Nature Communications</a>.</li>
        <li>Guilherme Almeida et al., "InP colloidal quantum dots for visible and near-infrared photonics" (2023), <a href="https://www.nature.com/articles/s41578-023-00596-4">Nature Reviews Materials</a>.</li>
      </ul>
    </section>

  </main>
</article>

<script>
  (function () {
    const canvas = document.getElementById("heroCanvas");
    if (!canvas) return;
    const ctx = canvas.getContext("2d");

    function resize() {
      canvas.width = canvas.offsetWidth;
      canvas.height = canvas.offsetHeight;
    }

    resize();
    window.addEventListener("resize", resize);

    const particles = Array.from({ length: 120 }, () => ({
      x: Math.random() * canvas.width,
      y: Math.random() * canvas.height,
      vx: (Math.random() - 0.5) * 0.3,
      vy: (Math.random() - 0.5) * 0.3,
      r: Math.random() * 1.5 + 0.3,
      alpha: Math.random() * 0.6 + 0.1,
      color: Math.random() > 0.6 ? "#4af4c8" : Math.random() > 0.5 ? "#a78bfa" : "#f472b6"
    }));

    const beams = Array.from({ length: 6 }, () => ({
      x: Math.random() * canvas.width,
      y: Math.random() * canvas.height,
      angle: Math.random() * Math.PI * 2,
      speed: Math.random() * 0.4 + 0.2,
      length: Math.random() * 80 + 40,
      alpha: Math.random() * 0.3 + 0.05
    }));

    function draw() {
      ctx.clearRect(0, 0, canvas.width, canvas.height);

      const grad = ctx.createRadialGradient(
        canvas.width * 0.5, canvas.height * 0.4, 0,
        canvas.width * 0.5, canvas.height * 0.4, canvas.width * 0.7
      );
      grad.addColorStop(0, "rgba(10,20,50,0.98)");
      grad.addColorStop(1, "rgba(5,8,15,0.98)");
      ctx.fillStyle = grad;
      ctx.fillRect(0, 0, canvas.width, canvas.height);

      beams.forEach((beam) => {
        beam.x += Math.cos(beam.angle) * beam.speed;
        beam.y += Math.sin(beam.angle) * beam.speed;
        if (beam.x < -100 || beam.x > canvas.width + 100 || beam.y < -100 || beam.y > canvas.height + 100) {
          beam.x = Math.random() * canvas.width;
          beam.y = Math.random() * canvas.height;
          beam.angle = Math.random() * Math.PI * 2;
        }
        ctx.save();
        ctx.globalAlpha = beam.alpha;
        ctx.strokeStyle = "#4af4c8";
        ctx.lineWidth = 1;
        ctx.beginPath();
        ctx.moveTo(beam.x, beam.y);
        ctx.lineTo(beam.x + Math.cos(beam.angle) * beam.length, beam.y + Math.sin(beam.angle) * beam.length);
        ctx.stroke();
        ctx.restore();
      });

      particles.forEach((particle) => {
        particle.x += particle.vx;
        particle.y += particle.vy;
        if (particle.x < 0) particle.x = canvas.width;
        if (particle.x > canvas.width) particle.x = 0;
        if (particle.y < 0) particle.y = canvas.height;
        if (particle.y > canvas.height) particle.y = 0;

        ctx.beginPath();
        ctx.arc(particle.x, particle.y, particle.r, 0, Math.PI * 2);
        ctx.fillStyle = particle.color;
        ctx.globalAlpha = particle.alpha;
        ctx.fill();
        ctx.globalAlpha = 1;
      });

      ctx.globalAlpha = 0.04;
      ctx.strokeStyle = "#4af4c8";
      ctx.lineWidth = 0.5;
      for (let i = 0; i < particles.length; i += 1) {
        for (let j = i + 1; j < particles.length; j += 1) {
          const dx = particles[i].x - particles[j].x;
          const dy = particles[i].y - particles[j].y;
          const dist = Math.sqrt(dx * dx + dy * dy);
          if (dist < 90) {
            ctx.beginPath();
            ctx.moveTo(particles[i].x, particles[i].y);
            ctx.lineTo(particles[j].x, particles[j].y);
            ctx.stroke();
          }
        }
      }
      ctx.globalAlpha = 1;

      requestAnimationFrame(draw);
    }

    draw();

    const reveals = document.querySelectorAll(".nano-post .reveal");
    const observer = new IntersectionObserver((entries) => {
      entries.forEach((entry) => {
        if (entry.isIntersecting) {
          entry.target.classList.add("visible");
          observer.unobserve(entry.target);
        }
      });
    }, { threshold: 0.08 });

    reveals.forEach((element) => observer.observe(element));
  }());
</script>]]></content><author><name>Farouq Oguntoye</name><email>farouqoguntoye05@gmail.com</email></author><category term="nanophotonics" /><category term="optics" /><category term="quantum photonics" /><category term="materials science" /><summary type="html"><![CDATA[How humanity learned to bend, trap, and reshape light at scales far below the width of a human hair, and why that matters for sensing, computing, imaging, and quantum technology.]]></summary></entry><entry><title type="html">Optical Neural Networks - Where the Matmul Is the Hardware</title><link href="https://herr-professor.github.io/blog/optical-neural-networks/" rel="alternate" type="text/html" title="Optical Neural Networks - Where the Matmul Is the Hardware" /><published>2026-03-22T00:00:00+00:00</published><updated>2026-03-22T00:00:00+00:00</updated><id>https://herr-professor.github.io/blog/optical-neural-networks</id><content type="html" xml:base="https://herr-professor.github.io/blog/optical-neural-networks/"><![CDATA[<style>
  @import url("https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500&family=Space+Grotesk:wght@400;500;700&display=swap");

  .feature-post {
    width: 100%;
  }

  .feature-post .page__inner-wrap {
    width: 100%;
  }

  .feature-post .page__content,
  .feature-post .page__meta,
  .feature-post .page__share {
    width: 100%;
  }

  .feature-post .page__content {
    margin: 0;
  }

  .feature-post .page__content h2 {
    border-bottom: 0;
    padding-bottom: 0;
  }

  .feature-post .page__meta,
  .feature-post .page__share,
  .feature-post .page__related {
    max-width: 1180px;
    margin-left: auto;
    margin-right: auto;
    padding-left: 4vw;
    padding-right: 4vw;
  }

  .onn-post {
    --bg: #060708;
    --bg2: #101114;
    --surface: #f4efe7;
    --surface-alt: #ece6dd;
    --surface-soft: #d9e7fb;
    --surface-warm: #f8ebcd;
    --text: #191816;
    --text-soft: #55524c;
    --ink: #f3efe8;
    --ink-soft: #b9b2a8;
    --line: rgba(255, 255, 255, 0.12);
    --line-dark: rgba(25, 24, 22, 0.12);
    --blue: #2d7ac8;
    --blue-soft: #d7e7fa;
    --green: #2d7a2c;
    --green-soft: #edf7e7;
    --gold: #8b6a17;
    --gold-soft: #fbf1d5;
    --red: #aa4335;
    --red-soft: #faece8;
    --shadow: 0 24px 80px rgba(0, 0, 0, 0.24);
    position: relative;
    margin: -2em calc(50% - 50vw) 0;
    width: 100vw;
    background:
      radial-gradient(circle at 20% 0%, rgba(45, 122, 200, 0.2), transparent 30%),
      radial-gradient(circle at 85% 10%, rgba(139, 106, 23, 0.18), transparent 24%),
      linear-gradient(180deg, #08090a 0%, #070708 20%, #0d0f12 100%);
    color: var(--ink);
    overflow-x: hidden;
  }

  .onn-post * {
    box-sizing: border-box;
  }

  .onn-post a {
    color: inherit;
  }

  .onn-post::before {
    content: "";
    position: fixed;
    inset: 0;
    background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 280 280' xmlns='http://www.w3.org/2000/svg'%3E%3Cdefs%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.78' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3C/defs%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.06'/%3E%3C/svg%3E");
    opacity: 0.2;
    pointer-events: none;
    z-index: 1;
  }

  .onn-post .hero,
  .onn-post .article {
    position: relative;
    z-index: 2;
  }

  .onn-post .hero {
    max-width: 1280px;
    margin: 0 auto;
    padding: 7rem 4vw 2.5rem;
  }

  .onn-post .hero-label,
  .onn-post .kicker,
  .onn-post .tab-chip,
  .onn-post .ref-index,
  .onn-post .mini-label,
  .onn-post .metric-label {
    font-family: "IBM Plex Mono", monospace;
    letter-spacing: 0.12em;
    text-transform: uppercase;
  }

  .onn-post .hero-label {
    display: inline-flex;
    align-items: center;
    gap: 0.75rem;
    color: #d8d2c8;
    font-size: 0.72rem;
  }

  .onn-post .hero-label::before {
    content: "";
    width: 32px;
    height: 1px;
    background: rgba(255, 255, 255, 0.35);
  }

  .onn-post h1,
  .onn-post h2,
  .onn-post h3,
  .onn-post h4,
  .onn-post p,
  .onn-post li,
  .onn-post table {
    font-family: "Space Grotesk", sans-serif;
  }

  .onn-post .hero h1 {
    font-size: clamp(3rem, 8vw, 6.8rem);
    line-height: 0.95;
    letter-spacing: -0.05em;
    margin: 1rem 0 1.25rem;
    max-width: 11ch;
  }

  .onn-post .hero h1 span {
    color: #f7d486;
  }

  .onn-post .hero-sub {
    max-width: 60rem;
    font-size: clamp(1.1rem, 2vw, 1.45rem);
    line-height: 1.7;
    color: #d0c9be;
    margin: 0 0 2rem;
  }

  .onn-post .hero-note {
    max-width: 72rem;
    background: rgba(247, 239, 232, 0.07);
    border: 1px solid rgba(255, 255, 255, 0.14);
    border-radius: 22px;
    padding: 1rem 1.1rem;
    color: #c8c1b7;
    font-size: 0.98rem;
    line-height: 1.7;
    backdrop-filter: blur(10px);
  }

  .onn-post .hero-note strong {
    color: #f6f1e9;
  }

  .onn-post .article {
    max-width: 1280px;
    margin: 0 auto;
    padding: 0 4vw 4rem;
  }

  .onn-post .tabs-shell {
    position: sticky;
    top: 4.4rem;
    z-index: 6;
    margin: 0 auto 2rem;
    padding-top: 0.4rem;
    background: linear-gradient(180deg, rgba(6, 7, 8, 0.96), rgba(6, 7, 8, 0.86) 82%, rgba(6, 7, 8, 0));
    backdrop-filter: blur(10px);
  }

  .onn-post .tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 0.8rem;
    padding-bottom: 1rem;
  }

  .onn-post .tab {
    appearance: none;
    border: 1px solid rgba(255, 255, 255, 0.2);
    background: rgba(6, 7, 8, 0.8);
    color: #cfc9c0;
    border-radius: 18px;
    min-height: 4.5rem;
    padding: 0.95rem 1.2rem;
    min-width: min(290px, calc(50% - 0.4rem));
    text-align: center;
    font-family: "Space Grotesk", sans-serif;
    font-size: clamp(1rem, 2vw, 1.12rem);
    font-weight: 700;
    line-height: 1.15;
    cursor: pointer;
    transition: border-color 0.2s ease, color 0.2s ease, background 0.2s ease, transform 0.2s ease;
  }

  .onn-post .tab:hover,
  .onn-post .tab:focus-visible {
    color: #f5f1ea;
    border-color: rgba(255, 255, 255, 0.38);
    transform: translateY(-1px);
    outline: none;
  }

  .onn-post .tab.is-active {
    color: #11100e;
    background: linear-gradient(180deg, #f7f2ea, #e9dfd0);
    border-color: rgba(255, 255, 255, 0.6);
    box-shadow: 0 18px 40px rgba(0, 0, 0, 0.24);
  }

  .onn-post .tab span {
    display: block;
  }

  .onn-post .panel {
    display: none;
    padding: 1.3rem 0 2rem;
  }

  .onn-post .panel.is-active {
    display: block;
  }

  .onn-post .section-intro {
    max-width: 72rem;
    margin: 0 0 2rem;
  }

  .onn-post .kicker {
    color: #9e988f;
    font-size: 0.82rem;
    margin: 0 0 1rem;
  }

  .onn-post .section-intro h2 {
    margin: 0 0 0.8rem;
    font-size: clamp(2rem, 4vw, 3.25rem);
    letter-spacing: -0.04em;
    line-height: 1.02;
  }

  .onn-post .section-intro p {
    margin: 0;
    color: #cac3b8;
    font-size: clamp(1rem, 1.75vw, 1.2rem);
    line-height: 1.75;
  }

  .onn-post .grid,
  .onn-post .stats-grid,
  .onn-post .callout-grid,
  .onn-post .architecture-grid {
    display: grid;
    gap: 1.4rem;
  }

  .onn-post .grid.two,
  .onn-post .stats-grid.two,
  .onn-post .callout-grid.two,
  .onn-post .architecture-grid.two {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .onn-post .grid.three,
  .onn-post .stats-grid.three {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .onn-post .card,
  .onn-post .wide-card,
  .onn-post .note,
  .onn-post .bandwidth,
  .onn-post .table-card,
  .onn-post .reference-card,
  .onn-post .diagram-card {
    background: var(--surface);
    color: var(--text);
    border-radius: 24px;
    border: 1px solid rgba(255, 255, 255, 0.06);
    box-shadow: var(--shadow);
  }

  .onn-post .card,
  .onn-post .note,
  .onn-post .bandwidth,
  .onn-post .reference-card,
  .onn-post .diagram-card {
    padding: 1.6rem 1.7rem;
  }

  .onn-post .wide-card,
  .onn-post .table-card {
    padding: 1.7rem 1.8rem;
  }

  .onn-post .card h3,
  .onn-post .wide-card h3,
  .onn-post .note h3,
  .onn-post .table-card h3,
  .onn-post .reference-card h3,
  .onn-post .diagram-card h3 {
    margin: 0 0 0.65rem;
    font-size: clamp(1.25rem, 2vw, 1.65rem);
    line-height: 1.15;
    letter-spacing: -0.03em;
  }

  .onn-post .card p,
  .onn-post .wide-card p,
  .onn-post .note p,
  .onn-post .diagram-card p,
  .onn-post .reference-card p,
  .onn-post .caption {
    margin: 0 0 0.85rem;
    color: var(--text-soft);
    font-size: 1rem;
    line-height: 1.75;
  }

  .onn-post .card p:last-child,
  .onn-post .wide-card p:last-child,
  .onn-post .note p:last-child,
  .onn-post .reference-card p:last-child,
  .onn-post .diagram-card p:last-child {
    margin-bottom: 0;
  }

  .onn-post .mini-label {
    color: #6f6b66;
    font-size: 0.72rem;
    margin: 0 0 0.9rem;
  }

  .onn-post .pill-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.65rem;
    margin-top: 1rem;
  }

  .onn-post .pill {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    min-height: 2.15rem;
    padding: 0.2rem 0.85rem;
    border-radius: 999px;
    font-family: "Space Grotesk", sans-serif;
    font-size: 0.95rem;
    font-weight: 700;
  }

  .onn-post .pill.good {
    color: var(--green);
    background: var(--green-soft);
  }

  .onn-post .pill.warn {
    color: var(--gold);
    background: var(--gold-soft);
  }

  .onn-post .pill.bad {
    color: var(--red);
    background: var(--red-soft);
  }

  .onn-post .pill.blue {
    color: var(--blue);
    background: var(--blue-soft);
  }

  .onn-post .code {
    margin-top: 1rem;
    padding: 1rem 1.1rem;
    border: 1px solid var(--line-dark);
    border-radius: 18px;
    background: rgba(255, 255, 255, 0.42);
    color: #36322c;
    font-family: "IBM Plex Mono", monospace;
    font-size: 0.98rem;
    line-height: 1.75;
    overflow-x: auto;
  }

  .onn-post .compare {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1.4rem;
    margin: 1.8rem 0;
  }

  .onn-post .highlight {
    margin-top: 1.4rem;
    padding: 1.15rem 1.2rem;
    border-radius: 18px;
    background: var(--surface-soft);
    border-left: 4px solid var(--blue);
    color: #44576f;
    font-size: 1rem;
    line-height: 1.75;
  }

  .onn-post .highlight strong {
    color: #2d4059;
  }

  .onn-post .flow {
    display: grid;
    gap: 1rem;
    margin-top: 1.3rem;
  }

  .onn-post .flow-row {
    display: flex;
    align-items: stretch;
    gap: 0.9rem;
    flex-wrap: wrap;
  }

  .onn-post .flow-node {
    flex: 1 1 12rem;
    min-width: 11rem;
    padding: 1rem 1rem 0.9rem;
    border-radius: 20px;
    border: 1px solid var(--line-dark);
    background: rgba(255, 255, 255, 0.56);
  }

  .onn-post .flow-node strong {
    display: block;
    color: var(--text);
    font-size: 1.35rem;
    line-height: 1.2;
    margin-bottom: 0.25rem;
  }

  .onn-post .flow-node span {
    color: var(--text-soft);
    font-size: 0.98rem;
    line-height: 1.55;
  }

  .onn-post .flow-arrow {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 2rem;
    font-size: 2rem;
    color: #8e877b;
  }

  .onn-post .badge-card {
    padding: 1.5rem 1.55rem;
    border-radius: 24px;
    background: var(--surface);
    color: var(--text);
    box-shadow: var(--shadow);
  }

  .onn-post .metric {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
  }

  .onn-post .metric-value {
    color: var(--green);
    font-size: clamp(2.3rem, 5vw, 3.7rem);
    line-height: 0.95;
    font-weight: 700;
    letter-spacing: -0.05em;
  }

  .onn-post .metric-value.gold {
    color: var(--gold);
  }

  .onn-post .metric-value.blue {
    color: var(--blue);
  }

  .onn-post .metric-label {
    color: #67625b;
    font-size: 0.72rem;
  }

  .onn-post .metric-copy {
    color: var(--text-soft);
    font-size: 1rem;
    line-height: 1.6;
  }

  .onn-post .bars {
    display: grid;
    gap: 1rem;
    margin-top: 1.3rem;
  }

  .onn-post .bar-row {
    display: grid;
    grid-template-columns: 18rem 1fr 10rem;
    gap: 1rem;
    align-items: center;
  }

  .onn-post .bar-row strong,
  .onn-post .bar-row span {
    color: var(--text-soft);
    font-size: 1rem;
  }

  .onn-post .bar-track {
    position: relative;
    height: 0.95rem;
    border-radius: 999px;
    background: rgba(25, 24, 22, 0.12);
    overflow: hidden;
  }

  .onn-post .bar-fill {
    position: absolute;
    inset: 0 auto 0 0;
    height: 100%;
    border-radius: inherit;
  }

  .onn-post .bar-fill.blue {
    background: linear-gradient(90deg, #6fb2ef, var(--blue));
  }

  .onn-post .bar-fill.gold {
    background: linear-gradient(90deg, #e0b65c, #c48a16);
  }

  .onn-post .bar-fill.green {
    background: linear-gradient(90deg, #6bd4b0, #1fb483);
  }

  .onn-post .bar-value {
    text-align: right;
    color: var(--text);
    font-weight: 700;
  }

  .onn-post .architecture-tabs {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 0.8rem;
    margin: 0 0 1.4rem;
  }

  .onn-post .subtab {
    appearance: none;
    border: 1px solid rgba(255, 255, 255, 0.16);
    background: rgba(8, 8, 9, 0.7);
    color: #d0c8be;
    border-radius: 18px;
    padding: 0.95rem 1.2rem;
    font-family: "Space Grotesk", sans-serif;
    font-size: 1rem;
    font-weight: 700;
    cursor: pointer;
  }

  .onn-post .subtab.is-active {
    color: #12110f;
    background: linear-gradient(180deg, #f6f1ea, #e8dfd3);
  }

  .onn-post .subpanel {
    display: none;
  }

  .onn-post .subpanel.is-active {
    display: block;
  }

  .onn-post .diagram {
    margin-top: 1.2rem;
    padding: 1.5rem 1rem 0.8rem;
    border-radius: 20px;
    border: 1px solid var(--line-dark);
    background: linear-gradient(180deg, #f6f8fc, #f1f4f8);
    overflow-x: auto;
  }

  .onn-post .diagram svg {
    width: 100%;
    min-width: 780px;
    height: auto;
    display: block;
  }

  .onn-post .steps {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1.2rem;
    margin-top: 1rem;
  }

  .onn-post .step {
    padding: 1.2rem 1.2rem 1rem;
    border: 1px solid var(--line-dark);
    border-radius: 20px;
    background: rgba(255, 255, 255, 0.5);
  }

  .onn-post .step-tag {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 2rem;
    padding: 0.15rem 0.8rem;
    border-radius: 999px;
    font-weight: 700;
    font-size: 0.95rem;
  }

  .onn-post .step-tag.blue {
    color: var(--blue);
    background: var(--blue-soft);
  }

  .onn-post .step-tag.gold {
    color: var(--gold);
    background: var(--gold-soft);
  }

  .onn-post .step-tag.green {
    color: var(--green);
    background: var(--green-soft);
  }

  .onn-post .step h4 {
    margin: 0.75rem 0 0.55rem;
    font-size: 1.2rem;
    line-height: 1.2;
    letter-spacing: -0.03em;
  }

  .onn-post .step p {
    margin: 0;
    color: var(--text-soft);
    font-size: 1rem;
    line-height: 1.7;
  }

  .onn-post table {
    width: 100%;
    border-collapse: collapse;
    font-size: 1rem;
    color: var(--text);
  }

  .onn-post th,
  .onn-post td {
    padding: 1rem 0.9rem;
    border-bottom: 1px solid rgba(25, 24, 22, 0.12);
    vertical-align: top;
    text-align: left;
  }

  .onn-post th {
    color: #55514b;
    font-size: 0.95rem;
    font-weight: 700;
  }

  .onn-post tbody tr:last-child td {
    border-bottom: 0;
  }

  .onn-post .references {
    display: grid;
    gap: 1rem;
    margin-top: 1.5rem;
  }

  .onn-post .references a {
    color: var(--blue);
    text-decoration: none;
  }

  .onn-post .references a:hover {
    text-decoration: underline;
  }

  .onn-post .footer-note {
    margin-top: 2rem;
    color: #a69e92;
    font-size: 0.92rem;
    line-height: 1.75;
  }

  @media (max-width: 1100px) {
    .onn-post .grid.two,
    .onn-post .grid.three,
    .onn-post .stats-grid.two,
    .onn-post .stats-grid.three,
    .onn-post .callout-grid.two,
    .onn-post .architecture-grid.two,
    .onn-post .compare,
    .onn-post .steps {
      grid-template-columns: 1fr;
    }

    .onn-post .bar-row {
      grid-template-columns: 1fr;
    }
  }

  @media (max-width: 900px) {
    .onn-post .tabs-shell {
      top: 3.6rem;
    }

    .onn-post .tab {
      min-width: calc(50% - 0.4rem);
      min-height: 4.25rem;
      font-size: 0.98rem;
    }

    .onn-post .flow-row {
      gap: 0.6rem;
    }

    .onn-post .flow-arrow {
      min-width: 100%;
      transform: rotate(90deg);
      font-size: 1.7rem;
      line-height: 1;
      min-height: 1rem;
    }
  }

  @media (max-width: 700px) {
    .onn-post .hero {
      padding-top: 5.8rem;
    }

    .onn-post .tab {
      min-width: 100%;
      text-align: left;
    }

    .onn-post .card,
    .onn-post .note,
    .onn-post .bandwidth,
    .onn-post .reference-card,
    .onn-post .diagram-card,
    .onn-post .wide-card,
    .onn-post .table-card,
    .onn-post .badge-card {
      padding-left: 1.2rem;
      padding-right: 1.2rem;
    }

    .onn-post th,
    .onn-post td {
      padding-left: 0.45rem;
      padding-right: 0.45rem;
      font-size: 0.94rem;
    }
  }

  .feature-post {
    width: auto;
  }

  .feature-post .page__inner-wrap,
  .feature-post .page__content,
  .feature-post .page__meta,
  .feature-post .page__share {
    width: auto;
    max-width: none;
  }

  .onn-post {
    --surface: #ffffff;
    --surface-alt: #f8fafc;
    --surface-soft: #eff6ff;
    --surface-warm: #fef3c7;
    --text: #1f2937;
    --text-soft: #4b5563;
    --ink: #1f2937;
    --ink-soft: #6b7280;
    --line: rgba(15, 23, 42, 0.12);
    --line-dark: rgba(15, 23, 42, 0.12);
    background: transparent;
    color: var(--text);
    margin: 0;
    width: auto;
    overflow: visible;
  }

  .onn-post::before {
    display: none;
  }

  .onn-post h1,
  .onn-post h2,
  .onn-post h3,
  .onn-post h4,
  .onn-post p,
  .onn-post li,
  .onn-post table,
  .onn-post .tab,
  .onn-post .subtab,
  .onn-post .flow-node strong,
  .onn-post .flow-node span {
    font-family: inherit;
  }

  .onn-post .hero,
  .onn-post .article {
    max-width: none;
    padding-left: 0;
    padding-right: 0;
  }

  .onn-post .hero {
    padding-top: 0;
    padding-bottom: 2rem;
  }

  .onn-post .hero-label,
  .onn-post .kicker,
  .onn-post .mini-label,
  .onn-post .metric-label {
    color: var(--ink-soft);
  }

  .onn-post .hero h1 {
    color: var(--text);
    font-size: clamp(2.2rem, 5vw, 3.2rem);
    line-height: 1.08;
    max-width: 14ch;
  }

  .onn-post .hero h1 span {
    color: #1d4ed8;
  }

  .onn-post .hero-sub,
  .onn-post .section-intro p,
  .onn-post .metric-copy,
  .onn-post .caption,
  .onn-post .footer-note,
  .onn-post .card p,
  .onn-post .wide-card p,
  .onn-post .note p,
  .onn-post .reference-card p,
  .onn-post .diagram-card p {
    color: var(--text-soft);
  }

  .onn-post .hero-note,
  .onn-post .highlight {
    background: #eff6ff;
    border-color: #bfdbfe;
    color: var(--text-soft);
    backdrop-filter: none;
  }

  .onn-post .highlight strong,
  .onn-post .hero-note strong {
    color: var(--text);
  }

  .onn-post .tabs-shell {
    position: static;
    top: auto;
    background: transparent;
    backdrop-filter: none;
    padding-top: 0;
    margin-bottom: 1.5rem;
  }

  .onn-post .tab,
  .onn-post .subtab {
    background: #ffffff;
    color: var(--text-soft);
    border-color: #e5e7eb;
    box-shadow: none;
  }

  .onn-post .tab:hover,
  .onn-post .tab:focus-visible,
  .onn-post .subtab:hover,
  .onn-post .subtab:focus-visible {
    color: var(--text);
    border-color: #cbd5e1;
    transform: none;
  }

  .onn-post .tab.is-active {
    background: #111827;
    color: #ffffff;
    border-color: #111827;
    box-shadow: none;
  }

  .onn-post .subtab.is-active {
    background: #f3f4f6;
    color: #111827;
    border-color: #d1d5db;
  }

  .onn-post .card,
  .onn-post .wide-card,
  .onn-post .note,
  .onn-post .bandwidth,
  .onn-post .table-card,
  .onn-post .reference-card,
  .onn-post .diagram-card,
  .onn-post .badge-card {
    background: #ffffff;
    color: var(--text);
    border: 1px solid #e5e7eb;
    box-shadow: none;
  }

  .onn-post .code,
  .onn-post .flow-node,
  .onn-post .step,
  .onn-post .diagram {
    background: #f8fafc;
    border-color: #e5e7eb;
    color: var(--text);
  }

  .onn-post .bar-track {
    background: #e5e7eb;
  }

  .onn-post .bar-row strong,
  .onn-post .bar-row span,
  .onn-post th {
    color: var(--text-soft);
  }

  .onn-post .references a {
    color: #1d4ed8;
  }
</style>

<article class="onn-post">
  <main class="article">
    <div class="section-intro" style="margin-bottom: 1.5rem;">
      <p>
        Strip away the optics jargon and the cleanest mental model is this: an optical neural network offloads some linear algebra into a physical system where light propagation performs the transform. The interesting engineering question is not whether photons are fast. It is where the digital-analog boundaries, calibration loops, and programmability costs move.
      </p>
    </div>

    <div class="hero-note" style="margin-bottom: 1.5rem;">
      <strong>Scope.</strong> This post focuses on current inference-oriented ONN hardware, especially coherent Mach-Zehnder-interferometer meshes and diffractive optical systems. Several performance figures below come from different papers and counting conventions, so any GPU comparison is directional rather than apples-to-apples.
    </div>

    <div class="tabs-shell">
      <div class="tabs" role="tablist" aria-label="Optical neural network sections">
        <button class="tab is-active" type="button" role="tab" aria-selected="true" aria-controls="onn-panel-0" id="onn-tab-0" data-panel="0">
          <span>0 — mental</span>
          <span>model</span>
        </button>
        <button class="tab" type="button" role="tab" aria-selected="false" aria-controls="onn-panel-1" id="onn-tab-1" data-panel="1">
          <span>1 — forward</span>
          <span>pass</span>
        </button>
        <button class="tab" type="button" role="tab" aria-selected="false" aria-controls="onn-panel-2" id="onn-tab-2" data-panel="2">
          <span>2 —</span>
          <span>architectures</span>
        </button>
        <button class="tab" type="button" role="tab" aria-selected="false" aria-controls="onn-panel-3" id="onn-tab-3" data-panel="3">
          <span>3 — weights &amp;</span>
          <span>training</span>
        </button>
        <button class="tab" type="button" role="tab" aria-selected="false" aria-controls="onn-panel-4" id="onn-tab-4" data-panel="4">
          <span>4 — perf</span>
          <span>numbers</span>
        </button>
        <button class="tab" type="button" role="tab" aria-selected="false" aria-controls="onn-panel-5" id="onn-tab-5" data-panel="5">
          <span>5 —</span>
          <span>tradeoffs</span>
        </button>
      </div>
    </div>

    <section class="panel is-active" id="onn-panel-0" role="tabpanel" aria-labelledby="onn-tab-0">
      <div class="section-intro">
        <p class="kicker">00 / Mental Model</p>
        <h2>Where the linear map becomes physical</h2>
        <p>
          An ONN is not “PyTorch, but with lasers.” The more accurate picture is that some learned linear transforms are compiled into a physical scattering network. In a coherent MZI mesh, phase shifters and beam splitters implement a programmable optical transform. In a passive diffractive network, the geometry of stacked phase masks does the work. Either way, the weights are no longer fetched from HBM on every inference.
        </p>
      </div>

      <div class="compare">
        <div class="wide-card">
          <p class="mini-label">GPU forward pass</p>
          <h3>Load weights, run kernels, write activations</h3>
          <p>
            The dominant systems story is data movement: weights come out of HBM, are staged closer to arithmetic units, a fused kernel runs, then activations go back to memory. The bottleneck is often memory bandwidth and orchestration more than multiply-add itself.
          </p>
          <div class="code"># each layer: data movement + compute
y = relu(x @ W + b)
# W is a tensor loaded from memory</div>
        </div>

        <div class="wide-card">
          <p class="mini-label">ONN forward pass</p>
          <h3>Encode, propagate, detect</h3>
          <p>
            The optical core applies a programmed physical transform to an encoded optical field. For coherent meshes that transform is typically unitary or built from unitary blocks plus amplitude control. For diffractive systems it is set by the masks or metasurfaces in the beam path.
          </p>
          <div class="code"># weights live in optical elements
y = detect(propagate(encode(x)))
# "loading weights" means setting phases or fabricating masks</div>
        </div>
      </div>

      <div class="highlight">
        <strong>Key systems insight.</strong> For the optical linear stage, the model parameters are embodied in hardware state rather than streamed from HBM on each inference. That shifts the bottleneck toward modulators, photodetectors, ADC/DAC precision, calibration, and control electronics.
      </div>

      <div class="table-card" style="margin-top: 1.5rem;">
        <h3>Where this fits in a modern ML stack</h3>
        <table>
          <thead>
            <tr>
              <th>Stack layer</th>
              <th>Status in an ONN deployment</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>Your inference harness</td>
              <td>Mostly unchanged. You still batch, schedule, validate, and monitor requests in software.</td>
            </tr>
            <tr>
              <td>Model parameter artifacts</td>
              <td>Compiled to phase settings, mask states, or other hardware control values instead of only tensor checkpoints.</td>
            </tr>
            <tr>
              <td>Linear layers</td>
              <td>Candidate for optical execution.</td>
            </tr>
            <tr>
              <td>Nonlinearities and control logic</td>
              <td>Usually electronic today, although some recent chips integrate limited optical nonlinear functions.</td>
            </tr>
          </tbody>
        </table>
      </div>
    </section>

    <section class="panel" id="onn-panel-1" role="tabpanel" aria-labelledby="onn-tab-1">
      <div class="section-intro">
        <p class="kicker">01 / Execution Model</p>
        <h2>The fast path is optical. The tax is at the boundaries.</h2>
        <p>
          End-to-end ONN inference is best understood as a domain-crossing pipeline. Digital inputs have to be encoded into optical amplitude or phase, the optical network applies its linear transform, and the result is measured back into the electrical domain. The optical segment is the part people find exciting. The converters are where a lot of the practical pain lives.
        </p>
      </div>

      <div class="wide-card">
        <h3>Inference pipeline</h3>
        <div class="flow">
          <div class="flow-row">
            <div class="flow-node">
              <strong>Input data</strong>
              <span>Digital features, token embeddings, sensor values, or image patches.</span>
            </div>
            <div class="flow-arrow">→</div>
            <div class="flow-node">
              <strong>DAC + modulator</strong>
              <span>Encode values into optical phase, amplitude, wavelength channels, or time bins.</span>
            </div>
            <div class="flow-arrow">→</div>
            <div class="flow-node">
              <strong>Optical propagation</strong>
              <span>Beam splitters, phase shifters, waveguides, or diffractive masks apply the learned linear map.</span>
            </div>
            <div class="flow-arrow">→</div>
            <div class="flow-node">
              <strong>Photodetector + ADC</strong>
              <span>Measure intensity or interference outputs and bring them back to digital logic.</span>
            </div>
            <div class="flow-arrow">→</div>
            <div class="flow-node">
              <strong>Output logits</strong>
              <span>Now you can apply thresholding, softmax, routing, or the next hybrid stage.</span>
            </div>
          </div>
        </div>

        <div class="highlight">
          <strong>Practical bottleneck.</strong> Recent integrated photonic accelerator work explicitly includes TX/RX electronics, DACs, driver circuits, photodetectors, TIAs, and ADCs as core system components. For current mixed-signal ONNs, converter precision and interface overhead often dominate the usable accuracy budget more than the underlying optics itself.
        </div>
      </div>

      <div class="grid two" style="margin-top: 1.5rem;">
        <div class="card">
          <p class="mini-label">What the optical core computes</p>
          <h3>A structured linear transform</h3>
          <p>
            In an MZI mesh, the optical field evolution is a matrix transform built from interferometers and phase shifts. In the cleanest setting that is a unitary matrix. General dense real-valued layers usually need extra decomposition steps, diagonal scaling, or hybrid surrounding circuitry.
          </p>
        </div>
        <div class="card">
          <p class="mini-label">What still stays hard</p>
          <h3>Nonlinear activation layers</h3>
          <p>
            ReLU, softmax, masking, and many control-heavy operations are still typically executed in electronics. Some chips now integrate optical nonlinearities, but that is not yet the dominant deployment model. For many systems, every deep layer still pays an optical-electrical round-trip.
          </p>
        </div>
      </div>
    </section>

    <section class="panel" id="onn-panel-2" role="tabpanel" aria-labelledby="onn-tab-2">
      <div class="section-intro">
        <p class="kicker">02 / Architectures</p>
        <h2>The backend choice changes everything</h2>
        <p>
          “Optical neural network” names a family of hardware strategies, not a single design. The two most useful buckets for a systems reader are programmable coherent meshes and diffractive free-space systems. There is also a middle zone of reconfigurable diffractive processors that trade away some efficiency or compactness to recover programmability.
        </p>
      </div>

      <div class="architecture-tabs" role="tablist" aria-label="ONN architectures">
        <button class="subtab is-active" type="button" role="tab" aria-selected="true" aria-controls="onn-arch-mzi" id="onn-arch-tab-mzi" data-subpanel="mzi">
          Silicon photonics (MZI mesh)
        </button>
        <button class="subtab" type="button" role="tab" aria-selected="false" aria-controls="onn-arch-d2nn" id="onn-arch-tab-d2nn" data-subpanel="d2nn">
          Free-space diffractive (D²NN)
        </button>
        <button class="subtab" type="button" role="tab" aria-selected="false" aria-controls="onn-arch-reconfig" id="onn-arch-tab-reconfig" data-subpanel="reconfig">
          Reconfigurable diffractive
        </button>
      </div>

      <div class="subpanel is-active" id="onn-arch-mzi" role="tabpanel" aria-labelledby="onn-arch-tab-mzi">
        <div class="wide-card">
          <p class="mini-label">Programmable coherent photonics</p>
          <h3>MZI meshes are the tunable matmul kernel</h3>
          <p>
            Shen et al. showed a programmable nanophotonic processor with 56 Mach-Zehnder interferometers for vowel recognition, and the Clements design formalized a compact mesh that can implement arbitrary linear transforms across channels with better robustness to loss than earlier layouts.
          </p>
          <div class="diagram">
            <svg viewBox="0 0 900 290" aria-hidden="true">
              <defs>
                <marker id="onn-arrow" markerWidth="12" markerHeight="12" refX="9" refY="6" orient="auto">
                  <path d="M0,0 L12,6 L0,12 z" fill="#2d7ac8"></path>
                </marker>
              </defs>
              <text x="450" y="34" text-anchor="middle" fill="#2d7ac8" font-size="24" font-family="Space Grotesk, sans-serif" font-weight="700">MZI mesh → optical linear transform</text>
              <line x1="40" y1="95" x2="180" y2="95" stroke="#2d7ac8" stroke-width="4" marker-end="url(#onn-arrow)"></line>
              <line x1="40" y1="200" x2="180" y2="200" stroke="#2d7ac8" stroke-width="4" marker-end="url(#onn-arrow)"></line>
              <rect x="180" y="58" width="140" height="175" rx="18" fill="#dceafb" stroke="#2d7ac8" stroke-width="1.5"></rect>
              <path d="M200 95 C235 95, 235 200, 270 200" fill="none" stroke="#8dc2f3" stroke-width="2.3" stroke-dasharray="7 6"></path>
              <path d="M200 200 C235 200, 235 95, 270 95" fill="none" stroke="#8dc2f3" stroke-width="2.3" stroke-dasharray="7 6"></path>
              <text x="250" y="150" text-anchor="middle" fill="#12538d" font-size="26" font-family="Space Grotesk, sans-serif" font-weight="700">MZI</text>
              <text x="250" y="182" text-anchor="middle" fill="#2d7ac8" font-size="18" font-family="IBM Plex Mono, monospace">θ₁</text>
              <line x1="320" y1="95" x2="425" y2="95" stroke="#2d7ac8" stroke-width="4" marker-end="url(#onn-arrow)"></line>
              <line x1="320" y1="200" x2="425" y2="200" stroke="#2d7ac8" stroke-width="4" marker-end="url(#onn-arrow)"></line>
              <rect x="425" y="58" width="140" height="175" rx="18" fill="#dceafb" stroke="#2d7ac8" stroke-width="1.5"></rect>
              <path d="M445 95 C480 95, 480 200, 515 200" fill="none" stroke="#8dc2f3" stroke-width="2.3" stroke-dasharray="7 6"></path>
              <path d="M445 200 C480 200, 480 95, 515 95" fill="none" stroke="#8dc2f3" stroke-width="2.3" stroke-dasharray="7 6"></path>
              <text x="495" y="150" text-anchor="middle" fill="#12538d" font-size="26" font-family="Space Grotesk, sans-serif" font-weight="700">MZI</text>
              <text x="495" y="182" text-anchor="middle" fill="#2d7ac8" font-size="18" font-family="IBM Plex Mono, monospace">θ₂</text>
              <line x1="565" y1="95" x2="670" y2="95" stroke="#2d7ac8" stroke-width="4" marker-end="url(#onn-arrow)"></line>
              <line x1="565" y1="200" x2="670" y2="200" stroke="#2d7ac8" stroke-width="4" marker-end="url(#onn-arrow)"></line>
              <rect x="670" y="58" width="140" height="175" rx="18" fill="#dceafb" stroke="#2d7ac8" stroke-width="1.5"></rect>
              <path d="M690 95 C725 95, 725 200, 760 200" fill="none" stroke="#8dc2f3" stroke-width="2.3" stroke-dasharray="7 6"></path>
              <path d="M690 200 C725 200, 725 95, 760 95" fill="none" stroke="#8dc2f3" stroke-width="2.3" stroke-dasharray="7 6"></path>
              <text x="740" y="150" text-anchor="middle" fill="#12538d" font-size="26" font-family="Space Grotesk, sans-serif" font-weight="700">MZI</text>
              <text x="740" y="182" text-anchor="middle" fill="#2d7ac8" font-size="18" font-family="IBM Plex Mono, monospace">θ₃</text>
              <line x1="810" y1="95" x2="870" y2="95" stroke="#2d7ac8" stroke-width="4" marker-end="url(#onn-arrow)"></line>
              <line x1="810" y1="200" x2="870" y2="200" stroke="#2d7ac8" stroke-width="4" marker-end="url(#onn-arrow)"></line>
              <text x="42" y="78" fill="#12538d" font-size="20" font-family="IBM Plex Mono, monospace">x₀</text>
              <text x="42" y="222" fill="#12538d" font-size="20" font-family="IBM Plex Mono, monospace">x₁</text>
              <text x="842" y="78" fill="#12538d" font-size="20" font-family="IBM Plex Mono, monospace">y₀</text>
              <text x="842" y="222" fill="#12538d" font-size="20" font-family="IBM Plex Mono, monospace">y₁</text>
              <text x="450" y="274" text-anchor="middle" fill="#7b7a75" font-size="19" font-family="Space Grotesk, sans-serif">Phase shifters are programmable; the mesh is reconfigurable at runtime.</text>
            </svg>
          </div>
        </div>

        <div class="grid two" style="margin-top: 1.5rem;">
          <div class="card">
            <p class="mini-label">Why people like it</p>
            <h3>Runtime programmability</h3>
            <p>
              “Deploying weights” means programming phase shifters or related control elements. That makes MZI hardware closer to a tunable accelerator than a fab-time-fixed optical circuit.
            </p>
          </div>
          <div class="card">
            <p class="mini-label">The catch</p>
            <h3>Calibration and scale</h3>
            <p>
              Phase noise, crosstalk, drift, and control complexity grow with chip size. The physics is elegant. The control plane is where scaling gets difficult.
            </p>
          </div>
        </div>
      </div>

      <div class="subpanel" id="onn-arch-d2nn" role="tabpanel" aria-labelledby="onn-arch-tab-d2nn">
        <div class="wide-card">
          <p class="mini-label">Passive free-space optics</p>
          <h3>D²NNs are optical inference burned into geometry</h3>
          <p>
            Lin et al. introduced diffractive deep neural networks as stacks of passive diffractive layers that collectively implement learned functions at the speed of light. Once those layers are physically made, the base design behaves much more like a write-once inference artifact than a reprogrammable chip.
          </p>
          <div class="diagram">
            <svg viewBox="0 0 900 280" aria-hidden="true">
              <defs>
                <marker id="onn-arrow-2" markerWidth="12" markerHeight="12" refX="9" refY="6" orient="auto">
                  <path d="M0,0 L12,6 L0,12 z" fill="#2d7ac8"></path>
                </marker>
              </defs>
              <text x="450" y="34" text-anchor="middle" fill="#2d7ac8" font-size="24" font-family="Space Grotesk, sans-serif" font-weight="700">D²NN — passive diffractive inference</text>
              <text x="46" y="135" fill="#2d7ac8" font-size="20" font-family="Space Grotesk, sans-serif" font-weight="700">Input</text>
              <text x="46" y="165" fill="#7b7a75" font-size="18" font-family="Space Grotesk, sans-serif">image or field</text>
              <line x1="110" y1="130" x2="180" y2="130" stroke="#2d7ac8" stroke-width="4" marker-end="url(#onn-arrow-2)"></line>
              <g>
                <rect x="180" y="45" width="42" height="165" rx="8" fill="#b7d7fb" stroke="#2d7ac8" stroke-width="1.4"></rect>
                <rect x="330" y="45" width="42" height="165" rx="8" fill="#b7d7fb" stroke="#2d7ac8" stroke-width="1.4"></rect>
                <rect x="480" y="45" width="42" height="165" rx="8" fill="#b7d7fb" stroke="#2d7ac8" stroke-width="1.4"></rect>
                <rect x="630" y="45" width="42" height="165" rx="8" fill="#b7d7fb" stroke="#2d7ac8" stroke-width="1.4"></rect>
              </g>
              <g stroke="#8fc1f3" stroke-width="2">
                <line x1="222" y1="92" x2="330" y2="130"></line>
                <line x1="222" y1="130" x2="330" y2="130"></line>
                <line x1="222" y1="168" x2="330" y2="130"></line>
                <line x1="372" y1="92" x2="480" y2="130"></line>
                <line x1="372" y1="130" x2="480" y2="130"></line>
                <line x1="372" y1="168" x2="480" y2="130"></line>
                <line x1="522" y1="92" x2="630" y2="130"></line>
                <line x1="522" y1="130" x2="630" y2="130"></line>
                <line x1="522" y1="168" x2="630" y2="130"></line>
                <line x1="672" y1="92" x2="770" y2="130"></line>
                <line x1="672" y1="130" x2="770" y2="130"></line>
                <line x1="672" y1="168" x2="770" y2="130"></line>
              </g>
              <rect x="770" y="78" width="42" height="104" rx="10" fill="#d8edb8" stroke="#6d9a2a" stroke-width="1.4"></rect>
              <text x="182" y="238" fill="#2d7ac8" font-size="18" font-family="IBM Plex Mono, monospace">L1</text>
              <text x="332" y="238" fill="#2d7ac8" font-size="18" font-family="IBM Plex Mono, monospace">L2</text>
              <text x="482" y="238" fill="#2d7ac8" font-size="18" font-family="IBM Plex Mono, monospace">L3</text>
              <text x="632" y="238" fill="#2d7ac8" font-size="18" font-family="IBM Plex Mono, monospace">L4</text>
              <text x="828" y="112" fill="#6d9a2a" font-size="18" font-family="Space Grotesk, sans-serif">class 0</text>
              <text x="828" y="145" fill="#6d9a2a" font-size="18" font-family="Space Grotesk, sans-serif">class 1 … N</text>
            </svg>
          </div>
        </div>

        <div class="highlight">
          <strong>Important distinction.</strong> The classic D²NN story is passive and largely fixed after fabrication. Reprogrammable spatial-light-modulator or metasurface variants exist, but the base architecture is much closer to ROM than to hot-reloaded GPU weights.
        </div>

        <div class="grid two" style="margin-top: 1.5rem;">
          <div class="card">
            <p class="mini-label">Why it is attractive</p>
            <h3>Huge parallelism in free space</h3>
            <p>
              Light diffracts across many spatial degrees of freedom at once, so a single optical pass can process large fields in parallel.
            </p>
          </div>
          <div class="card">
            <p class="mini-label">Why it is limiting</p>
            <h3>One mask stack, one deployed function</h3>
            <p>
              If the weights are embodied in fabricated masks, model updates are no longer a software deployment problem. They become a hardware replacement problem.
            </p>
          </div>
        </div>
      </div>

      <div class="subpanel" id="onn-arch-reconfig" role="tabpanel" aria-labelledby="onn-arch-tab-reconfig">
        <div class="wide-card">
          <p class="mini-label">Middle ground</p>
          <h3>Reconfigurable diffractive processors recover flexibility</h3>
          <p>
            This is the compromise architecture. Instead of a permanently fixed diffractive stack, the optical processor uses reconfigurable elements, such as digital-coding metasurfaces or other optoelectronic control planes, to support different models or tasks. Zhou et al. reported a reconfigurable diffractive processing unit with millions of neurons and adaptive training to compensate system errors.
          </p>
          <div class="pill-row">
            <span class="pill good">✓ more flexible than passive D²NN</span>
            <span class="pill warn">~ more control overhead</span>
            <span class="pill warn">~ still hybrid, not purely passive</span>
          </div>
        </div>
      </div>
    </section>

    <section class="panel" id="onn-panel-3" role="tabpanel" aria-labelledby="onn-tab-3">
      <div class="section-intro">
        <p class="kicker">03 / Weights &amp; Training</p>
        <h2>Weights are no longer just tensors</h2>
        <p>
          The most unintuitive part for systems engineers is that “model weights” can map to phase settings, mask geometries, or other physical control states. That changes deployment, versioning, evaluation, and reproducibility. It also changes how carefully you have to talk about training: offline simulation is common, but it is no longer the only story.
        </p>
      </div>

      <div class="wide-card">
        <p class="mini-label">What a weight means in a coherent ONN</p>
        <h3>A compiled physical configuration</h3>
        <p>
          In an MZI-based design, a learned matrix is decomposed into interferometer parameters and phase values. In a diffractive design, the “weights” are the transmissive or phase profile of each layer. That means deployment artifacts often include both a model checkpoint and a hardware-programming representation.
        </p>
        <div class="code"># Conceptually, one MZI is a tunable 2x2 block
def mzi(theta, phi):
    # beam splitter + phase shift
    return U(theta, phi)

# Full optical layer = product of many such blocks
# "Loading weights" = setting phases and calibration state</div>
      </div>

      <div class="table-card" style="margin-top: 1.5rem;">
        <h3>Common deployment workflow today</h3>
        <div class="steps">
          <div class="step">
            <span class="step-tag blue">step 1</span>
            <h4>Train or co-train a differentiable optical model</h4>
            <p>
              The common path is still digital optimization in PyTorch, JAX, or custom simulators that model the optical layer and its hardware constraints.
            </p>
          </div>
          <div class="step">
            <span class="step-tag gold">step 2</span>
            <h4>Compile to hardware parameters</h4>
            <p>
              For coherent meshes this can involve decompositions such as Clements-style parameterization plus any diagonal scaling and hardware-aware clipping.
            </p>
          </div>
          <div class="step">
            <span class="step-tag green">step 3</span>
            <h4>Program or fabricate the optical system</h4>
            <p>
              You send voltages to phase shifters, configure a reconfigurable optical front-end, or physically realize a fixed mask stack.
            </p>
          </div>
        </div>

        <div class="highlight">
          <strong>Correction to a common oversimplification.</strong> It is no longer accurate to say ONN training is always offline simulation followed by one-way programming. Pai et al. experimentally demonstrated in-situ backpropagation on a silicon photonic neural network, and Bandyopadhyay et al. showed forward-only in-situ training on a fully integrated chip. Offline compilation is common. It is not the only training mode anymore.
        </div>
      </div>

      <div class="table-card" style="margin-top: 1.5rem;">
        <h3>What this means for evaluation and reproducibility</h3>
        <table>
          <thead>
            <tr>
              <th>Factor</th>
              <th>GPU assumption</th>
              <th>ONN reality</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>Model artifact</td>
              <td>Tensor checkpoint</td>
              <td>Tensor checkpoint plus compiled phase or mask state and calibration metadata</td>
            </tr>
            <tr>
              <td>Numeric precision</td>
              <td>Bit-defined formats like fp32, bf16, int8</td>
              <td>Mixed-signal, often single-digit effective bits at system level</td>
            </tr>
            <tr>
              <td>Runtime determinism</td>
              <td>Close to bit-exact for fixed seeds and kernels</td>
              <td>Affected by drift, noise, bias settings, device mismatch, and readout error</td>
            </tr>
            <tr>
              <td>Calibration</td>
              <td>Usually not part of model versioning</td>
              <td>Operationally important and may change output quality over time</td>
            </tr>
            <tr>
              <td>Eval thresholds</td>
              <td>Exact-match and narrow tolerances are common</td>
              <td>Statistical tolerances and repeated measurements are often more defensible</td>
            </tr>
          </tbody>
        </table>
      </div>
    </section>

    <section class="panel" id="onn-panel-4" role="tabpanel" aria-labelledby="onn-tab-4">
      <div class="section-intro">
        <p class="kicker">04 / Performance</p>
        <h2>The numbers are impressive, but the units need adult supervision</h2>
        <p>
          ONN papers often report outstanding latency and energy-efficiency numbers, but comparing them directly to GPUs is tricky because precision, sparsity assumptions, workload shape, and system boundary definitions vary. The right way to read the field is: optical linear algebra can be extraordinarily efficient, but end-to-end usefulness still depends on control electronics and deployment fit.
        </p>
      </div>

      <div class="stats-grid two">
        <div class="badge-card">
          <div class="metric">
            <span class="metric-label">Taichi chiplet (Science 2024)</span>
            <span class="metric-value">160 TOPS/W</span>
            <span class="metric-copy">Reported energy efficiency for a large-scale diffractive-interference hybrid photonic chiplet with millions-of-neurons capability.</span>
          </div>
        </div>
        <div class="badge-card">
          <div class="metric">
            <span class="metric-label">PACE system</span>
            <span class="metric-value blue">2.38–4.21 TOPS/W</span>
            <span class="metric-copy">Reported system-level efficiency for a 64 × 64 integrated photonic accelerator, depending on whether laser power is included.</span>
          </div>
        </div>
        <div class="badge-card">
          <div class="metric">
            <span class="metric-label">FICONN (Nature Photonics 2024)</span>
            <span class="metric-value blue">410 ps</span>
            <span class="metric-copy">Demonstrated latency for a three-layer fully integrated coherent optical neural network.</span>
          </div>
        </div>
        <div class="badge-card">
          <div class="metric">
            <span class="metric-label">PACE system</span>
            <span class="metric-value gold">7.61 bits</span>
            <span class="metric-copy">Average bit accuracy reported for a 64 × 64 integrated photonic accelerator system.</span>
          </div>
        </div>
      </div>

      <div class="table-card" style="margin-top: 1.5rem;">
        <h3>Read each number by its system boundary</h3>
        <p>
          This is the part that trips people up. ONN papers, integrated mixed-signal accelerator papers, and vendor GPU spec sheets are usually not measuring the same thing. So compare them as architectural signals, not as interchangeable benchmark rows.
        </p>
        <table>
          <thead>
            <tr>
              <th>System</th>
              <th>Reported number</th>
              <th>What to remember</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>Taichi chiplet</td>
              <td>160 TOPS/W</td>
              <td>Paper-reported efficiency for a specialized photonic chiplet architecture optimized around optical computing.</td>
            </tr>
            <tr>
              <td>PACE 64 × 64 accelerator</td>
              <td>2.38 TOPS/W including lasers, 4.21 TOPS/W excluding lasers</td>
              <td>Integrated mixed-signal system number, not just an isolated optical core.</td>
            </tr>
            <tr>
              <td>FICONN</td>
              <td>410 ps latency</td>
              <td>Latency number on a compact fully integrated coherent ONN, useful for understanding the speed floor of the optical path.</td>
            </tr>
            <tr>
              <td>H100 SXM</td>
              <td>Up to 1,979 TFLOPS BF16/FP16 with sparsity, 3.35 TB/s HBM, up to 700 W</td>
              <td>Vendor peak spec for a general-purpose GPU. This is the machine you already know, but it is not a like-for-like paper boundary.</td>
            </tr>
          </tbody>
        </table>
      </div>

      <div class="bandwidth" style="margin-top: 1.5rem;">
        <h3>Why people keep saying ONNs dodge the memory wall</h3>
        <div class="code"># GPU intuition
flops = 2 * N * M
bytes = N * M * dtype_size   # weight traffic
arithmetic_intensity = flops / bytes

# ONN intuition for the optical linear map
# weights are embodied in phase settings / optical structure
# per-inference weight traffic is reduced or eliminated at the optical stage
# the bottleneck shifts to modulator rate, photodetector chain, ADC/DAC, and control I/O</div>
        <p class="caption">
          The claim is directionally right for the optical linear layer, but it should be phrased carefully. End-to-end ONN systems still rely on electronics, control paths, and often repeated domain conversions.
        </p>
      </div>
    </section>

    <section class="panel" id="onn-panel-5" role="tabpanel" aria-labelledby="onn-tab-5">
      <div class="section-intro">
        <p class="kicker">05 / Tradeoffs</p>
        <h2>Strong in narrow places, weak in exactly the places LLMs care about</h2>
        <p>
          The honest assessment is that ONNs are compelling when you can exploit fast, energy-efficient linear transforms with limited need for online updates and with a tolerance for mixed-signal imperfection. They are much less compelling when you need deep stacks of nonlinear layers, exact reproducibility, or massive reprogrammable parameter counts.
        </p>
      </div>

      <div class="table-card">
        <h3>Engineering verdict</h3>
        <table>
          <thead>
            <tr>
              <th>Dimension</th>
              <th>Verdict</th>
              <th>Why it matters</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>Energy per linear op</td>
              <td><span class="pill good">✓ strong win</span></td>
              <td>Optical propagation is passive or nearly passive compared with electronic MAC arrays.</td>
            </tr>
            <tr>
              <td>Latency for linear inference</td>
              <td><span class="pill good">✓ win</span></td>
              <td>The optical core is extremely fast; integrated systems have already demonstrated sub-nanosecond class latency in small networks.</td>
            </tr>
            <tr>
              <td>Precision and reproducibility</td>
              <td><span class="pill bad">× loss</span></td>
              <td>Noise, converter limits, drift, and calibration state make exact-match expectations harder to defend.</td>
            </tr>
            <tr>
              <td>Programmability</td>
              <td><span class="pill warn">~ depends</span></td>
              <td>MZI meshes are reconfigurable; passive diffractive networks are much closer to hardware-fused models.</td>
            </tr>
            <tr>
              <td>Nonlinear depth</td>
              <td><span class="pill bad">× loss</span></td>
              <td>Hybrid optical-electronic round-trips are still the default for many architectures.</td>
            </tr>
            <tr>
              <td>Model size scaling</td>
              <td><span class="pill bad">× loss</span></td>
              <td>Even impressive photonic demonstrations remain far below the parameter counts and memory footprints of frontier LLMs.</td>
            </tr>
            <tr>
              <td>Training</td>
              <td><span class="pill warn">~ partial</span></td>
              <td>In-situ training exists in research prototypes, but training is not yet the field’s easiest or most mature deployment story.</td>
            </tr>
            <tr>
              <td>Inference-only, fixed-function tasks</td>
              <td><span class="pill good">✓ best fit</span></td>
              <td>Classification, signal processing, and front-end sensing pipelines are where ONNs look most deployable today.</td>
            </tr>
          </tbody>
        </table>
      </div>

      <div class="highlight" style="margin-top: 1.5rem;">
        <strong>Deployment answer today.</strong> ONNs look most plausible for latency-critical or energy-sensitive inference where the linear transform dominates and the model changes slowly. They are not a general drop-in replacement for LLM training, online fine-tuning, or giant dynamically updated models.
      </div>

      <div class="reference-card" style="margin-top: 1.5rem;">
        <p class="mini-label">Selected primary sources</p>
        <h3>Research behind the claims in this explainer</h3>
        <div class="references">
          <p><a href="https://www.nature.com/articles/nphoton.2017.93">Shen et al. (Nature Photonics, 2017)</a> demonstrated a programmable nanophotonic processor with 56 MZIs for optical neural inference.</p>
          <p><a href="https://arxiv.org/abs/1603.08788">Clements et al. (2016)</a> described a compact universal interferometer mesh used heavily in programmable photonics.</p>
          <p><a href="https://pubmed.ncbi.nlm.nih.gov/37104594/">Pai et al. (Science, 2023)</a> experimentally realized in-situ backpropagation on a silicon photonic neural network.</p>
          <p><a href="https://www.nature.com/articles/s41566-024-01567-z">Bandyopadhyay et al. (Nature Photonics, 2024)</a> demonstrated a fully integrated coherent optical neural network with forward-only in-situ training and 410 ps latency.</p>
          <p><a href="https://pubmed.ncbi.nlm.nih.gov/38603505/">Xu et al. (Science, 2024)</a> reported the Taichi photonic chiplet with 160 TOPS/W and millions-of-neurons capability.</p>
          <p><a href="https://www.nature.com/articles/s41566-021-00796-w">Zhou et al. (Nature Photonics, 2021)</a> reported a reconfigurable diffractive processing unit with adaptive training and millions of neurons.</p>
          <p><a href="https://arxiv.org/abs/1804.08711">Lin et al. (Science, 2018 preprint / related DOI)</a> introduced diffractive deep neural networks as passive optical inference stacks.</p>
          <p><a href="https://www.nature.com/articles/s41928-022-00719-9">Liu et al. (Nature Electronics, 2022)</a> demonstrated a programmable diffractive deep neural network based on a digital-coding metasurface array.</p>
          <p><a href="https://www.nature.com/articles/s41586-025-08786-6">An integrated large-scale photonic accelerator with ultralow latency</a> reported a 64 × 64 photonic accelerator system with 7.61-bit average accuracy and explicit TX/RX electronics in the system architecture.</p>
          <p><a href="https://www.nvidia.com/en-gb/data-center/h100/">NVIDIA H100 official specifications</a> are used only as a modern GPU orientation point for memory bandwidth and tensor-throughput scale.</p>
        </div>
      </div>
    </section>
  </main>
</article>

<script>
  (function () {
    const panels = Array.from(document.querySelectorAll(".onn-post .panel"));
    const tabs = Array.from(document.querySelectorAll(".onn-post .tab"));
    const subpanels = Array.from(document.querySelectorAll(".onn-post .subpanel"));
    const subtabs = Array.from(document.querySelectorAll(".onn-post .subtab"));

    function activatePanel(id) {
      panels.forEach((panel) => {
        const isActive = panel.id === "onn-panel-" + id;
        panel.classList.toggle("is-active", isActive);
      });

      tabs.forEach((tab) => {
        const isActive = tab.dataset.panel === id;
        tab.classList.toggle("is-active", isActive);
        tab.setAttribute("aria-selected", String(isActive));
        tab.tabIndex = isActive ? 0 : -1;
      });
    }

    function activateSubpanel(id) {
      subpanels.forEach((panel) => {
        const isActive = panel.id === "onn-arch-" + id;
        panel.classList.toggle("is-active", isActive);
      });

      subtabs.forEach((tab) => {
        const isActive = tab.dataset.subpanel === id;
        tab.classList.toggle("is-active", isActive);
        tab.setAttribute("aria-selected", String(isActive));
        tab.tabIndex = isActive ? 0 : -1;
      });
    }

    tabs.forEach((tab) => {
      tab.addEventListener("click", () => activatePanel(tab.dataset.panel));
      tab.addEventListener("keydown", (event) => {
        if (event.key !== "ArrowRight" && event.key !== "ArrowLeft") return;
        event.preventDefault();
        const direction = event.key === "ArrowRight" ? 1 : -1;
        const index = tabs.indexOf(tab);
        const next = tabs[(index + direction + tabs.length) % tabs.length];
        next.focus();
        activatePanel(next.dataset.panel);
      });
    });

    subtabs.forEach((tab) => {
      tab.addEventListener("click", () => activateSubpanel(tab.dataset.subpanel));
      tab.addEventListener("keydown", (event) => {
        if (event.key !== "ArrowRight" && event.key !== "ArrowLeft") return;
        event.preventDefault();
        const direction = event.key === "ArrowRight" ? 1 : -1;
        const index = subtabs.indexOf(tab);
        const next = subtabs[(index + direction + subtabs.length) % subtabs.length];
        next.focus();
        activateSubpanel(next.dataset.subpanel);
      });
    });
  })();
</script>]]></content><author><name>Farouq Oguntoye</name><email>farouqoguntoye05@gmail.com</email></author><category term="optical neural networks" /><category term="silicon photonics" /><category term="photonic computing" /><category term="machine learning systems" /><summary type="html"><![CDATA[A systems-engineer’s map of optical neural networks: what the optical core actually computes, how MZI meshes and diffractive systems differ, where training and calibration fit, and where the real engineering tradeoffs show up.]]></summary></entry></feed>