Skip to content

Optics — Photonic Stochastic Computing

Simulated photonic SC layer using laser interference for bitstream generation. Photonic SC uses physical randomness (laser phase noise) instead of LFSR pseudo-randomness, giving truly uncorrelated bitstreams.

Theory

Two coherent laser beams with phase noise φ produce interference intensity:

I = I₁ + I₂ + 2√(I₁I₂) cos(φ)

Normalized: I_norm = 0.5 + 0.5 * cos(φ) where φ ~ Uniform(0, 2π).

Bitstream generation: a bit is 1 if the interference intensity falls below the input probability. This maps naturally to photonic hardware where a photodetector and comparator produce the output bit.

Components

  • PhotonicBitstreamLayer — Multi-channel photonic SC layer.
Parameter Default Meaning
n_channels (required) Number of independent optical channels
laser_power 1.0 SNR control (reserved for future noise model)

Methods:

  • simulate_interference(length) — Generate intensity patterns of shape (n_channels, length)
  • forward(input_probs, length) — Generate bitstreams where P(bit=1) ≈ input_prob per channel

Usage

from sc_neurocore.optics.photonic_layer import PhotonicBitstreamLayer
import numpy as np

layer = PhotonicBitstreamLayer(n_channels=4)

# Generate photonic bitstreams
probs = np.array([0.2, 0.4, 0.6, 0.8])
bitstreams = layer.forward(probs, length=10000)
print(f"Measured rates: {bitstreams.mean(axis=1)}")
# ≈ [0.20, 0.40, 0.60, 0.80]

# Raw interference pattern
intensity = layer.simulate_interference(length=1000)
print(f"Intensity range: [{intensity.min():.3f}, {intensity.max():.3f}]")

sc_neurocore.optics.photonic_layer

PhotonicBitstreamLayer dataclass

Simulates a Photonic Stochastic Computing Layer. Uses Phase Noise (Laser Interference) to generate bitstreams.

Source code in src/sc_neurocore/optics/photonic_layer.py
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
@dataclass
class PhotonicBitstreamLayer:
    """
    Simulates a Photonic Stochastic Computing Layer.
    Uses Phase Noise (Laser Interference) to generate bitstreams.
    """

    n_channels: int
    laser_power: float = 1.0  # SNR control

    def simulate_interference(self, length: int) -> np.ndarray[Any, Any]:
        """
        Simulates the interference of two laser beams with phase noise.
        I = I1 + I2 + 2*sqrt(I1*I2)*cos(phi)
        """
        # Phase noise phi: Wiener process or random uniform
        phi = np.random.uniform(0, 2 * np.pi, (self.n_channels, length))

        # Normalized intensity
        intensity = 0.5 + 0.5 * np.cos(phi)

        return intensity

    def forward(
        self, input_probs: np.ndarray[Any, Any], length: int = 1024
    ) -> np.ndarray[Any, Any]:
        """
        Generates bitstreams where '1' occurs if interference intensity < input_prob.
        """
        input_probs = np.asarray(input_probs)
        if input_probs.shape[0] != self.n_channels:
            raise ValueError(
                f"Input shape {input_probs.shape} does not match n_channels={self.n_channels}"
            )

        # input_probs: (n_channels,)
        intensities = self.simulate_interference(length)

        # Thresholding
        bits = (intensities < input_probs[:, None]).astype(np.uint8)

        return bits

simulate_interference(length)

Simulates the interference of two laser beams with phase noise. I = I1 + I2 + 2sqrt(I1I2)*cos(phi)

Source code in src/sc_neurocore/optics/photonic_layer.py
23
24
25
26
27
28
29
30
31
32
33
34
def simulate_interference(self, length: int) -> np.ndarray[Any, Any]:
    """
    Simulates the interference of two laser beams with phase noise.
    I = I1 + I2 + 2*sqrt(I1*I2)*cos(phi)
    """
    # Phase noise phi: Wiener process or random uniform
    phi = np.random.uniform(0, 2 * np.pi, (self.n_channels, length))

    # Normalized intensity
    intensity = 0.5 + 0.5 * np.cos(phi)

    return intensity

forward(input_probs, length=1024)

Generates bitstreams where '1' occurs if interference intensity < input_prob.

Source code in src/sc_neurocore/optics/photonic_layer.py
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
def forward(
    self, input_probs: np.ndarray[Any, Any], length: int = 1024
) -> np.ndarray[Any, Any]:
    """
    Generates bitstreams where '1' occurs if interference intensity < input_prob.
    """
    input_probs = np.asarray(input_probs)
    if input_probs.shape[0] != self.n_channels:
        raise ValueError(
            f"Input shape {input_probs.shape} does not match n_channels={self.n_channels}"
        )

    # input_probs: (n_channels,)
    intensities = self.simulate_interference(length)

    # Thresholding
    bits = (intensities < input_probs[:, None]).astype(np.uint8)

    return bits