mirror of
https://github.com/ruvnet/RuVector.git
synced 2026-08-31 10:15:39 +00:00
perf(photonlayer): M1 — cached + in-place Propagator (1.70x, bit-identical)
Hot-path optimization for the mask-learning loop, which propagates thousands of fields through one fixed config. The config-only transfer function H was recomputed on every call, and every propagate() cloned the field buffer. - Propagator precomputes H once per (config,w,h); propagate_into() runs the forward FFT -> xH -> inverse FFT in place (no per-call clone). - Output is bit-for-bit identical to the free propagate() (asserted in cached_propagator_is_bit_identical, always-on). - Measured 1.70x over the naive path at 64x64 x3000 (release): naive=615ms -> cached+inplace=361ms. Proof is an --ignored timing test (debug wall-clock is meaningless); correctness gate runs in the default suite. Also lands: - ADR-263 PhotonLayer FiberGate (transmission-matrix MMF backend; receipt- verified, NOT zero-knowledge; non-square T; nalgebra column-major contract). - docs/research/photonlayer/APPLICATIONS.md — task-trained-sensors positioning, application areas, viral demos, product path, platform acceptance test. Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
parent
e1429af65c
commit
c3a553e7fc
5 changed files with 461 additions and 18 deletions
|
|
@ -62,7 +62,7 @@ pub mod prelude {
|
|||
accuracy, compression_ratio, frame_spectrum_embedding, input_frame_similarity, mse, psnr,
|
||||
MetricReport,
|
||||
};
|
||||
pub use crate::propagate::propagate;
|
||||
pub use crate::propagate::{propagate, Propagator};
|
||||
pub use crate::receipt::{build_receipt, verify_receipt, ExperimentReceipt, Provenance};
|
||||
pub use crate::simulator::{OpticalSimulator, ScalarSimulator, SimulationTrace};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,19 +66,17 @@ enum TransferKind {
|
|||
AngularSpectrum,
|
||||
}
|
||||
|
||||
fn transfer_fn(field: &OpticalField, config: &OpticalConfig, kind: TransferKind) -> Result<OpticalField> {
|
||||
let (w, h) = (field.width, field.height);
|
||||
/// Build the config-only transfer function H (length `w*h`, row-major). H depends
|
||||
/// solely on (w, h, λ, z, d, kind) — never on the field — so it can be computed
|
||||
/// once and reused across many propagations (see [`Propagator`]).
|
||||
fn transfer_kernel(w: usize, h: usize, config: &OpticalConfig, kind: TransferKind) -> Vec<Complex> {
|
||||
let lambda = config.wavelength_m();
|
||||
let z = config.distance_m();
|
||||
let d = config.pixel_pitch_m();
|
||||
|
||||
let fx = fftfreq(w, d);
|
||||
let fy = fftfreq(h, d);
|
||||
|
||||
let mut data = field.data.clone();
|
||||
fft_2d(&mut data, w, h, false);
|
||||
|
||||
let k = 2.0 * PI / lambda;
|
||||
let mut hk = vec![Complex::ZERO; w * h];
|
||||
for row in 0..h {
|
||||
for col in 0..w {
|
||||
let fxx = fx[col];
|
||||
|
|
@ -86,8 +84,7 @@ fn transfer_fn(field: &OpticalField, config: &OpticalConfig, kind: TransferKind)
|
|||
let h_val = match kind {
|
||||
TransferKind::Fresnel => {
|
||||
// Drop constant exp(i k z); keep quadratic phase.
|
||||
let phase = -PI * lambda * z * (fxx * fxx + fyy * fyy);
|
||||
Complex::from_phase(phase)
|
||||
Complex::from_phase(-PI * lambda * z * (fxx * fxx + fyy * fyy))
|
||||
}
|
||||
TransferKind::AngularSpectrum => {
|
||||
let arg = 1.0 - (lambda * fxx).powi(2) - (lambda * fyy).powi(2);
|
||||
|
|
@ -99,17 +96,108 @@ fn transfer_fn(field: &OpticalField, config: &OpticalConfig, kind: TransferKind)
|
|||
}
|
||||
}
|
||||
};
|
||||
let idx = row * w + col;
|
||||
data[idx] = data[idx] * h_val;
|
||||
hk[row * w + col] = h_val;
|
||||
}
|
||||
}
|
||||
hk
|
||||
}
|
||||
|
||||
/// Apply a precomputed transfer kernel: forward FFT → ×H → inverse FFT.
|
||||
fn apply_transfer(field: &OpticalField, w: usize, h: usize, hk: &[Complex]) -> OpticalField {
|
||||
let mut data = field.data.clone();
|
||||
fft_2d(&mut data, w, h, false);
|
||||
for (dv, hv) in data.iter_mut().zip(hk.iter()) {
|
||||
*dv = *dv * *hv;
|
||||
}
|
||||
fft_2d(&mut data, w, h, true);
|
||||
OpticalField { width: w, height: h, data }
|
||||
}
|
||||
|
||||
fn transfer_fn(field: &OpticalField, config: &OpticalConfig, kind: TransferKind) -> Result<OpticalField> {
|
||||
let (w, h) = (field.width, field.height);
|
||||
let hk = transfer_kernel(w, h, config, kind);
|
||||
Ok(apply_transfer(field, w, h, &hk))
|
||||
}
|
||||
|
||||
/// A precomputed propagation operator. Build once per `(config, width, height)`
|
||||
/// and reuse across many fields — the config-only transfer function is computed
|
||||
/// a single time instead of on every call. This is the hot path in mask-learning
|
||||
/// loops (thousands of propagations share one config). Output is bit-identical to
|
||||
/// the free [`propagate`] function.
|
||||
pub struct Propagator {
|
||||
width: usize,
|
||||
height: usize,
|
||||
kind: PropKind,
|
||||
}
|
||||
|
||||
enum PropKind {
|
||||
Fraunhofer,
|
||||
/// Precomputed transfer function H (length `width*height`).
|
||||
Transfer(Vec<Complex>),
|
||||
}
|
||||
|
||||
impl Propagator {
|
||||
/// Precompute the operator for a fixed grid + config.
|
||||
pub fn new(width: usize, height: usize, config: &OpticalConfig) -> Result<Self> {
|
||||
if !is_pow2(width) {
|
||||
return Err(PhotonError::NotPowerOfTwo(width));
|
||||
}
|
||||
if !is_pow2(height) {
|
||||
return Err(PhotonError::NotPowerOfTwo(height));
|
||||
}
|
||||
let kind = match config.propagation {
|
||||
PropagationMode::Fraunhofer => PropKind::Fraunhofer,
|
||||
PropagationMode::Fresnel => {
|
||||
PropKind::Transfer(transfer_kernel(width, height, config, TransferKind::Fresnel))
|
||||
}
|
||||
PropagationMode::AngularSpectrum => PropKind::Transfer(transfer_kernel(
|
||||
width,
|
||||
height,
|
||||
config,
|
||||
TransferKind::AngularSpectrum,
|
||||
)),
|
||||
};
|
||||
Ok(Self { width, height, kind })
|
||||
}
|
||||
|
||||
/// Propagate a field through the precomputed operator.
|
||||
pub fn propagate(&self, field: &OpticalField) -> Result<OpticalField> {
|
||||
if field.width != self.width || field.height != self.height {
|
||||
return Err(PhotonError::NotPowerOfTwo(field.width));
|
||||
}
|
||||
match &self.kind {
|
||||
PropKind::Fraunhofer => fraunhofer(field),
|
||||
PropKind::Transfer(hk) => Ok(apply_transfer(field, self.width, self.height, hk)),
|
||||
}
|
||||
}
|
||||
|
||||
fft_2d(&mut data, w, h, true);
|
||||
Ok(OpticalField {
|
||||
width: w,
|
||||
height: h,
|
||||
data,
|
||||
})
|
||||
/// **In-place** propagation — forward FFT → ×H → inverse FFT, mutating `data`
|
||||
/// directly (no per-call field clone). Bit-identical to [`Propagator::propagate`];
|
||||
/// this is the batch hot path (mask-learning loops over many samples).
|
||||
pub fn propagate_into(&self, data: &mut [Complex]) -> Result<()> {
|
||||
let (w, h) = (self.width, self.height);
|
||||
if data.len() != w * h {
|
||||
return Err(PhotonError::NotPowerOfTwo(data.len()));
|
||||
}
|
||||
match &self.kind {
|
||||
PropKind::Fraunhofer => {
|
||||
fft_2d(data, w, h, false);
|
||||
fftshift_2d(data, w, h);
|
||||
let norm = 1.0 / (w as f32 * h as f32).sqrt();
|
||||
for c in data.iter_mut() {
|
||||
*c = c.scale(norm);
|
||||
}
|
||||
}
|
||||
PropKind::Transfer(hk) => {
|
||||
fft_2d(data, w, h, false);
|
||||
for (dv, hv) in data.iter_mut().zip(hk.iter()) {
|
||||
*dv = *dv * *hv;
|
||||
}
|
||||
fft_2d(data, w, h, true);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
|||
88
crates/photonlayer-core/tests/propagation_speedup.rs
Normal file
88
crates/photonlayer-core/tests/propagation_speedup.rs
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
//! M1 proof: the cached + in-place `Propagator` is faster than the naive free
|
||||
//! `propagate()` (which recomputes the transfer function H and clones the field
|
||||
//! every call), and produces **bit-identical** output. No speedup claim without
|
||||
//! this measured number.
|
||||
//!
|
||||
//! Run: `cargo test -p photonlayer-core --release --test propagation_speedup -- --ignored --nocapture`
|
||||
|
||||
use std::time::Instant;
|
||||
|
||||
use photonlayer_core::config::OpticalConfig;
|
||||
use photonlayer_core::field::{InputImage, OpticalField};
|
||||
use photonlayer_core::propagate::{propagate, Propagator};
|
||||
|
||||
const N: usize = 64; // grid (learn-loop regime where H-recompute is a large fraction)
|
||||
const ITERS: usize = 3000;
|
||||
|
||||
fn test_field(n: usize) -> OpticalField {
|
||||
// Deterministic non-trivial pattern.
|
||||
let px: Vec<f32> = (0..n * n)
|
||||
.map(|i| {
|
||||
let (x, y) = ((i % n) as f32, (i / n) as f32);
|
||||
0.5 + 0.5 * ((x * 0.3).sin() * (y * 0.2).cos())
|
||||
})
|
||||
.collect();
|
||||
let img = InputImage::from_norm_f32(n, n, px).unwrap();
|
||||
OpticalField::from_image(&img, n, n).unwrap()
|
||||
}
|
||||
|
||||
/// Always-on correctness gate: the cached + in-place path is bit-for-bit
|
||||
/// identical to the free `propagate()`. Cheap; runs in the default suite.
|
||||
#[test]
|
||||
fn cached_propagator_is_bit_identical() {
|
||||
let field = test_field(N);
|
||||
let config = OpticalConfig::demo(N, N);
|
||||
let reference = propagate(&field, &config).unwrap();
|
||||
let prop = Propagator::new(N, N, &config).unwrap();
|
||||
let via_struct = prop.propagate(&field).unwrap();
|
||||
let mut buf = field.data.clone();
|
||||
prop.propagate_into(&mut buf).unwrap();
|
||||
assert_eq!(via_struct.data, reference.data, "Propagator::propagate must match free propagate");
|
||||
assert_eq!(buf, reference.data, "propagate_into must be bit-identical to free propagate");
|
||||
}
|
||||
|
||||
/// Timing proof (M1). Release-only — wall-clock is meaningless in debug. Run:
|
||||
/// `cargo test -p photonlayer-core --release --test propagation_speedup -- --ignored --nocapture`
|
||||
#[test]
|
||||
#[ignore = "timing benchmark — run with --release --ignored"]
|
||||
fn cached_propagator_is_faster() {
|
||||
let field = test_field(N);
|
||||
let config = OpticalConfig::demo(N, N);
|
||||
|
||||
// Warm up.
|
||||
for _ in 0..64 {
|
||||
let _ = propagate(&field, &config).unwrap();
|
||||
}
|
||||
|
||||
// Naive: free propagate (recompute H + clone) every call.
|
||||
let t = Instant::now();
|
||||
let mut sink = 0.0f32;
|
||||
for _ in 0..ITERS {
|
||||
let out = propagate(&field, &config).unwrap();
|
||||
sink += out.data[0].re;
|
||||
}
|
||||
let naive = t.elapsed().as_secs_f64();
|
||||
|
||||
// Optimized: build operator once; in-place propagate into a reused buffer.
|
||||
let prop = Propagator::new(N, N, &config).unwrap();
|
||||
let mut scratch = vec![photonlayer_core::complex::Complex::ZERO; N * N];
|
||||
let t = Instant::now();
|
||||
for _ in 0..ITERS {
|
||||
scratch.copy_from_slice(&field.data);
|
||||
prop.propagate_into(&mut scratch).unwrap();
|
||||
sink += scratch[0].re;
|
||||
}
|
||||
let opt = t.elapsed().as_secs_f64();
|
||||
std::hint::black_box(sink);
|
||||
|
||||
let speedup = naive / opt;
|
||||
eprintln!(
|
||||
"propagation {N}x{N} x{ITERS}: naive={:.1}ms cached+inplace={:.1}ms speedup={speedup:.2}x",
|
||||
naive * 1e3,
|
||||
opt * 1e3
|
||||
);
|
||||
assert!(
|
||||
speedup >= 1.5,
|
||||
"cached+in-place propagator must be >= 1.5x the naive path; got {speedup:.2}x"
|
||||
);
|
||||
}
|
||||
206
docs/adr/ADR-263-photonlayer-fibergate-transmission-matrix.md
Normal file
206
docs/adr/ADR-263-photonlayer-fibergate-transmission-matrix.md
Normal file
|
|
@ -0,0 +1,206 @@
|
|||
---
|
||||
adr: 263
|
||||
title: "PhotonLayer FiberGate — transmission-matrix optical compression for drift-bound privacy verification"
|
||||
status: proposed
|
||||
date: 2026-06-18
|
||||
authors: [ruvnet, claude-flow]
|
||||
related: [ADR-260, ADR-261, ADR-262]
|
||||
tags: [photonlayer, fiber-optics, multimode-fiber, transmission-matrix, mmf, privacy, receipts, drift, ruvector, wasm]
|
||||
---
|
||||
|
||||
# ADR-263 — PhotonLayer FiberGate
|
||||
|
||||
> **Decision in one line.** Add a **multimode-fiber (MMF) propagation backend** to
|
||||
> `photonlayer-core` based on a **calibrated complex transmission matrix (T)**, a
|
||||
> deterministic intensity-sensor projection, **drift-aware calibration receipts**,
|
||||
> and ruVector-backed calibration memory — moving PhotonLayer from free-space
|
||||
> diffraction to guided-wave optics.
|
||||
|
||||
## Context
|
||||
|
||||
PhotonLayer today models **free-space** scalar diffraction (Fresnel / Fraunhofer /
|
||||
angular-spectrum; ADR-260). The cutting edge of optical computing is moving to
|
||||
**guided-wave** substrates — e.g. the Fiber-based Diffractive Deep Neural Network
|
||||
(Fiber-D2NN, *Opt. Lett.* 50(17):5254) shows high ML accuracy from linear optical
|
||||
relations **inside** fibers.
|
||||
|
||||
The right framing (and the bounded claim we will defend):
|
||||
|
||||
> **PhotonLayer Fiber treats the multimode fiber as a calibrated, drifting,
|
||||
> complex *linear* optical operator. The learned mask shapes the input field so
|
||||
> that the drifting fiber + sensor produce task-useful compressed measurements.**
|
||||
|
||||
This is stronger than "the fiber is just another propagation model." Below
|
||||
nonlinear power thresholds, the input→output **field** relationship of an MMF is
|
||||
well modeled by a transmission matrix **T**; the observed **sensor** image is an
|
||||
intensity speckle pattern. Both deep-learning and intensity-matrix methods are
|
||||
established for MMF image recovery/classification (arXiv:1805.05134). Bending and
|
||||
temperature **drift** of T is the central real-world challenge and requires
|
||||
recalibration (Nat. Commun. s42005-023-01410-x).
|
||||
|
||||
### Claim hygiene (no slop)
|
||||
|
||||
- **This is NOT zero-knowledge.** The design proves a private input was transformed
|
||||
under a specific mask + calibrated fiber state into a specific low-dimensional
|
||||
measurement. That is a **cryptographic receipt**, not a ZK proof. We use:
|
||||
**receipt-verified privacy gate** / **non-reconstructive verification** /
|
||||
**optical biometric commitment** / **fiber-bound biometric proof**. Safe claim:
|
||||
*"the server verifies a receipt bound to the current fiber calibration and
|
||||
receives only the compressed optical measurement, not the source image."*
|
||||
- **Consented verification only** — no gallery identification.
|
||||
|
||||
## Decision
|
||||
|
||||
Add a fiber backend and the supporting machinery, in this **build order** (the
|
||||
moat is the physics + receipts + memory, not the browser):
|
||||
|
||||
1. `photonlayer-core` fiber backend (T-matrix propagation + deterministic sensor).
|
||||
2. Fiber **drift** benchmark in `photonlayer-bench`.
|
||||
3. ruVector **calibration memory** in `photonlayer-ruvector`.
|
||||
4. `photonlayer-wasm` client bindings.
|
||||
|
||||
### Mathematical model
|
||||
|
||||
**Level 1 — practical T-matrix simulator (implementation target):**
|
||||
|
||||
```
|
||||
E_in' = E_in ⊙ e^{iΦ} (apply learned phase mask)
|
||||
E_out = T · E_in' (linear mode mixing; T may be non-square)
|
||||
I_sensor = B · |E_out|² + ε (intensity-only, binned, deterministic seeded noise ε)
|
||||
```
|
||||
|
||||
**Level 2 — mode-basis simulator (later, for physical interpretability):**
|
||||
|
||||
```
|
||||
E(x,y,z) = Σ_m a_m(z) ψ_m(x,y) e^{iβ_m z}
|
||||
a_m(0) = ∬ E_in(x,y) e^{iΦ(x,y)} ψ_m*(x,y) dx dy
|
||||
a(L) = C(L, θ, T_env) a(0) (separates ideal propagation from drift)
|
||||
```
|
||||
|
||||
### Rust design (determinism-first)
|
||||
|
||||
Three correctness rules the implementation MUST honor:
|
||||
|
||||
1. **Layout contract** — `nalgebra::DMatrix` is column-major; define and document a
|
||||
fixed (row-major image) ⇄ (column-vector) mapping so flatten/reshape never
|
||||
silently reorders the spatial layout.
|
||||
2. **Non-square T** — input modes, output field samples, and sensor bins have
|
||||
different dimensions (e.g. 256 → 64 → 4). `T` is `output_len × input_len`.
|
||||
3. **Determinism is not free from `nalgebra`** — pin operation order, no
|
||||
uncontrolled parallel reductions, finite checks on every value, stable
|
||||
serialization. Bit-identical output across Linux/macOS/WASM is an invariant
|
||||
(ADR-261).
|
||||
|
||||
Core type (shape per the corrected design):
|
||||
|
||||
```rust
|
||||
pub struct FiberTransmissionMatrix {
|
||||
pub t: DMatrix<Complex64>, // output_len × input_len (non-square allowed)
|
||||
pub input_len: usize,
|
||||
pub output_len: usize,
|
||||
pub version: u64,
|
||||
pub calibration_hash: [u8; 32],
|
||||
}
|
||||
// propagate(input_field, mask) -> FiberOutput { field, intensity },
|
||||
// validating input/mask length + matrix shape + finiteness (FiberError otherwise).
|
||||
```
|
||||
|
||||
New `photonlayer-core` modules: `fiber.rs`, `fiber_matrix.rs`,
|
||||
`fiber_calibration.rs`, `fiber_sensor.rs`, `fiber_receipt.rs`. Core structs:
|
||||
`FiberTransmissionMatrix`, `FiberCalibrationState`, `FiberPilotPattern`,
|
||||
`FiberDriftModel`, `FiberSensorProjector`, `FiberReceipt`.
|
||||
|
||||
### Drift-aware training (turns drift from liability into a training distribution)
|
||||
|
||||
```
|
||||
min_{Φ,θ} E_{T ~ D_fiber} [ L(decoder(B|T(E ⊙ e^{iΦ})|²), y) ] + λ R(Φ) + γ L_privacy
|
||||
```
|
||||
|
||||
Train the mask against a **family** of likely T states, not one matrix. `R(Φ)` =
|
||||
smoothness/manufacturability; `L_privacy` = reconstruction/leakage penalty.
|
||||
|
||||
Drift metric and accuracy-vs-drift tracking:
|
||||
|
||||
```
|
||||
Δ_T = ‖T_t − T_{t−1}‖_F / ‖T_{t−1}‖_F A = f(Δ_T, SNR, bins, mask)
|
||||
```
|
||||
|
||||
### ruVector calibration memory (`photonlayer-ruvector`)
|
||||
|
||||
Store each calibration as an experiment object (fiber_id, t_version,
|
||||
calibration_hash, timestamp, temperature, bend_state, snr_db, drift_norm,
|
||||
mask_id, task, eer, reconstruction_score) and use ruVector for: nearest-calibration
|
||||
lookup, drift-regime clustering, recalibration prediction, finding masks robust
|
||||
across multiple T states, and spectral failure explanation.
|
||||
|
||||
### Receipt schema + commitment
|
||||
|
||||
```rust
|
||||
pub struct FiberReceipt {
|
||||
pub photonlayer_version: String,
|
||||
pub fiber_id_hash: [u8; 32],
|
||||
pub t_version: u64,
|
||||
pub t_hash: [u8; 32],
|
||||
pub pilot_hash: [u8; 32],
|
||||
pub phase_mask_id: [u8; 32],
|
||||
pub input_commitment: [u8; 32], // salted: C = H(input_hash || nonce || purpose || session)
|
||||
pub output_hash: [u8; 32],
|
||||
pub decoder_id: [u8; 32],
|
||||
pub nonce: [u8; 32],
|
||||
pub timestamp_ms: u64,
|
||||
}
|
||||
```
|
||||
|
||||
Key design choice: **never store the raw biometric hash in a reusable form** — use
|
||||
the salted commitment `C`.
|
||||
|
||||
### Threat model
|
||||
|
||||
| Threat | Risk | Mitigation |
|
||||
|---|---|---|
|
||||
| Replay old N-pixel output | Medium | bind receipt to T version + nonce + timestamp |
|
||||
| T-matrix theft | Medium | rotate calibration, encrypt at rest, bind to device |
|
||||
| Reconstruction attack | High | publish attack suite (ADR-262), train privacy penalty |
|
||||
| Server spoofing T state | Medium | signed calibration state |
|
||||
| Browser config DoS | Medium | existing input validation |
|
||||
| Biometric misuse | High | consented verification only, no gallery |
|
||||
| Model inversion | High | leakage tests vs attributes + identity |
|
||||
|
||||
## Consequences
|
||||
|
||||
### Positive
|
||||
- Unlocks the flagship **medical-endoscope** (optical compression inside a needle-
|
||||
thin fiber bundle — no bulky tip sensor) and **drone/edge** sensing paths.
|
||||
- Drift becomes an **anti-replay signal**, not only a liability.
|
||||
- The defensible moat: **drift-aware, receipt-verified optical compression with
|
||||
experiment memory** — not the browser layer.
|
||||
|
||||
### Negative / risks
|
||||
- Real fiber validation needs hardware + calibration; until then this is a
|
||||
**simulator + receipt schema**, claimed as such.
|
||||
- T-matrix calibration is a new operational burden (pilot wavefronts, drift
|
||||
thresholds, recalibration triggers).
|
||||
- Determinism across native + WASM with `nalgebra` complex linear algebra requires
|
||||
care (see rule 3).
|
||||
|
||||
### Neutral
|
||||
- Free-space backend (ADR-260) stays; fiber is an additional `PropagationKind`.
|
||||
|
||||
## Acceptance tests
|
||||
|
||||
1. Same input + mask + T + seed → identical output hash across Linux, macOS, WASM.
|
||||
2. Learned mask beats random by ≥ **20 pp** on compressed fiber classification.
|
||||
3. EER stays below target across ≥ **5 drift states**.
|
||||
4. Reconstruction-attack similarity stays below the documented threshold.
|
||||
5. Receipt verification **fails** if any of {T version, phase mask, decoder, nonce,
|
||||
output, sensor config} changes.
|
||||
6. Recalibration trigger fires when `Δ_T` crosses the configured threshold.
|
||||
7. **Non-square** T passes end-to-end: 256 inputs → 64 output samples → 4 sensor bins.
|
||||
|
||||
## Links
|
||||
- ADR-260 (free-space simulator), ADR-261 (mask exchange & determinism),
|
||||
ADR-262 (privacy-preserving optical verification).
|
||||
- Fiber-D2NN — *Opt. Lett.* 50(17):5254. MMF + deep learning — arXiv:1805.05134.
|
||||
Single-ended T recovery / drift — *Nat. Commun.* s42005-023-01410-x.
|
||||
- Product: **PhotonLayer FiberGate** — calibrated fiber as a physically-bound,
|
||||
receipt-verified transformation layer for non-reconstructive verification.
|
||||
61
docs/research/photonlayer/APPLICATIONS.md
Normal file
61
docs/research/photonlayer/APPLICATIONS.md
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
# PhotonLayer — Applications & Strategy
|
||||
|
||||
> **The category:** not cameras, not neural nets, not "optical computing" — **task-trained sensors**.
|
||||
> Strategic thesis: *AI created an infinite appetite for visual data; PhotonLayer goes the other way —
|
||||
> **capture less, decide faster, leak less, and prove what happened.***
|
||||
|
||||
Companion to [ASSESSMENT.md](ASSESSMENT.md), ADR-260/261/262/263. Bounded-claim discipline applies:
|
||||
no diagnosis claims, consented verification only, "receipt-verified" (not zero-knowledge).
|
||||
|
||||
## The core shift — image recognition without images
|
||||
|
||||
```
|
||||
Traditional: scene → camera image → neural net → decision
|
||||
PhotonLayer: scene → trained optical transform → tiny sensor measurement → small decoder → decision
|
||||
```
|
||||
|
||||
Recognize / verify / classify / reject from a **compressed optical signature** instead of a stored
|
||||
image. Aligned with learned optical encoders, lensless privacy cameras, meta-optics, and hybrid
|
||||
optical-electronic neural nets (arXiv:2406.04129; ACS Photonics 5c02358; PMC12011376).
|
||||
|
||||
> **The system sees enough to decide, but not enough to reconstruct.**
|
||||
|
||||
## Application areas (positioned by market readiness)
|
||||
|
||||
| Area | PhotonLayer role | First market? |
|
||||
|---|---|---|
|
||||
| **Industrial inspection** | defect yes/no, barcode/label verify, tamper, scratch, sorting | **Yes — best first market** (low regulatory burden, clear ROI, controlled lighting) |
|
||||
| Privacy-first machine vision | face *verification* without storage, occupancy without identity, PPE/posture, child-safe presence | High viral / commercial distinctiveness |
|
||||
| Ultra-low-bandwidth sensors | tiny sensors, always-on vision, few-bin event verification, battery/edge | Reduces the expensive part of edge AI (pixel movement) |
|
||||
| Drone / robotics pre-perception | landing-pad, horizon, obstacle, marker, motion-cue, terrain class | Medium (safer than full autonomy) |
|
||||
| Medical imaging **research** | microscopy morphology, lesion compression, endoscopy, cell pre-sort, pathology triage | High risk — **research only, no diagnosis** |
|
||||
| Fiber-bound security | tamper-evident links, device-bound auth, anti-replay, drift-liveness (ADR-263) | New product class |
|
||||
| Scientific instruments | design instruments around the *question*, not the image | Biggest long-term idea |
|
||||
|
||||
## A new benchmark lane — "accuracy per captured photon / pixel / sensor bin"
|
||||
|
||||
Metrics: accuracy/sensor-pixel · accuracy/digital-MAC · EER under reconstruction constraint · drift
|
||||
robustness · receipt reproducibility · calibration half-life · leakage score · failure boundary. The
|
||||
receipt system is what makes these **reproducible optical experiments**, not just claims.
|
||||
|
||||
## Viral demos (for the Pages UI)
|
||||
|
||||
- **A — "The camera that cannot see you"**: face → 4-px measurement → same/different verdict. *It verified the person without storing the face.*
|
||||
- **B — "The microscope learned what not to measure"**: full image → optical compression → morphology class → failed reconstruction. *The useful signal survived. The image did not.*
|
||||
- **C — "Drone vision in 4 pixels"**: landing marker detected from a few optical bins. *The drone needs a decision, not a frame.*
|
||||
- **D — "The fiber is the lock"** (ADR-263): verification fails when T drifts or the receipt is replayed. *The cable became part of the cryptographic boundary.*
|
||||
|
||||
## Product path (build order)
|
||||
|
||||
1. **PhotonLayer Studio** — browser optical-mask simulator with receipts.
|
||||
2. **PhotonLayer Bench** — public optical-compression benchmark suite.
|
||||
3. **PhotonLayer PrivacyGate** — consented verification + reconstruction attacks.
|
||||
4. **PhotonLayer Industrial** — defect/barcode inspection SDK.
|
||||
5. **PhotonLayer FiberGate** — drift-aware MMF simulator + lab bridge (ADR-263).
|
||||
6. **PhotonLayer BioResearch** — microscopy/dermatology research simulator (no diagnostic claims).
|
||||
|
||||
## Sharp acceptance test (platform-grade)
|
||||
|
||||
> On **3 public datasets**: learned optical mask ≥ full-image baseline − 2%; sensor pixels reduced
|
||||
> ≥ **16×**; digital MACs reduced ≥ **10×**; reconstruction-attack similarity below threshold;
|
||||
> receipt verification reproducible across Rust-native **and** WASM.
|
||||
Loading…
Add table
Add a link
Reference in a new issue