the pytorch code is totally broken.
the old numba code seems to be ok. rewrite using the full spectrum calculations
import numpy as np
import matplotlib.pyplot as plt
from tqdm import tqdm
from numba import njit, prange
"""
Quantum-Inspired 2D Reflection and Transmission Simulation Using Wave Interference (Accelerated)
This version includes:
- Numba for accelerating wavelet summation
- tqdm progress bar for monitoring processing time
- Soft tonemapping (gamma correction) instead of Reinhard
- Simulation of both reflected and transmitted wavefields
- Full spectral calculations over visible wavelengths (RGB)
- Wavelength dispersion by adjusting emission phase speed for each wavelength
Tested on Apple Silicon using CPU-based acceleration.
"""
surface_y = 0
global_spotlight_angle_deg = 45
cone_half_angle_deg = 10
num_rays = 32
wavelengths = [0.45, 0.55, 0.65] # Blue, Green, Red (in microns)
gamma = 1/2.2 # gamma correction for perceptual tonemapping
refractive_indices = [1.52, 1.50, 1.48] # simulate dispersion (n varies with wavelength)
spotlight_angle_rad = np.radians(global_spotlight_angle_deg)
cone_half_angle_rad = np.radians(cone_half_angle_deg)
electron_x = np.linspace(-20, 20, 400)
electron_y = surface_y
obs_x = np.linspace(-20, 20, 400)
obs_y = np.linspace(-20, 20, 400)
obs_X, obs_Y = np.meshgrid(obs_x, obs_y)
angles = np.linspace(
spotlight_angle_rad - cone_half_angle_rad,
spotlight_angle_rad + cone_half_angle_rad,
num_rays
)
@njit(parallel=True)
def compute_field(k, n, electron_x, obs_X, obs_Y, angles, surface_y):
field_real = np.zeros(obs_X.shape, dtype=np.float64)
field_imag = np.zeros(obs_X.shape, dtype=np.float64)
for i in prange(len(angles)):
phase = k * n * (electron_x * np.cos(theta)) # phase shift with refractive index
for j in range(len(electron_x)):
for xi in range(obs_X.shape[0]):
for yi in range(obs_X.shape[1]):
dy = obs_Y[xi, yi] - surface_y
r = np.sqrt(dx**2 + dy**2)
val = (1/r) * np.exp(1j * (k * n * r + p)) # wave speed affected by medium
field_real[xi, yi] += val.real
field_imag[xi, yi] += val.imag
return field_real + 1j * field_imag
rgb_image = np.zeros((*obs_X.shape, 3))
print(“Computing wave fields across RGB wavelengths with dispersion…”)
for i in range(3):
wavelength = wavelengths[i]
n = refractive_indices[i] # wavelength-dependent refractive index
k = 2 * np.pi / wavelength
field = compute_field(k, n, electron_x, obs_X, obs_Y, angles, surface_y)
intensity = np.abs(field)**2
#intensity = intensity / np.max(intensity) # normalize each channel
rgb_image[:, :, i] = np.log1p(intensity) #intensity ** gamma # gamma correction
rgb_image /= rgb_image.max()
if rgb_image.shape[0] == 1:
rgb_image = rgb_image.repeat(3, 1, 1)
rgb_image = np.clip(rgb_image, 0, 1)
plt.figure(figsize=(12, 8))
plt.imshow(rgb_image, extent=(-20, 20, -20, 20), origin=‘lower’, aspect=‘auto’)
plt.title(“Emergent Reflection & Transmission with Spectral Dispersion”)
plt.xlabel(“x-position”)
plt.ylabel(“y-position”)
ray_origin_x = -15
ray_origin_y = 15
for theta in angles:
dx = np.sin(theta) * 8 # longer and rotated 90°
dy = -np.cos(theta) * 8 # longer and rotated 90°
plt.arrow(ray_origin_x, ray_origin_y, dx, dy,
head_width=0.4, head_length=0.7, fc=‘cyan’, ec=‘cyan’, alpha=0.7)
plt.axhline(surface_y, color=‘cyan’, linestyle=’—’, label=‘Surface (Electrons)’)
plt.legend()
plt.show()