mirror of
https://github.com/allaunthefox/SilverSight.git
synced 2026-08-20 13:17:28 +00:00
exp(bosonic): continuous interpolation experiment for regime transition
Testing λ(p) = exp(-p²/N) to remove hard p≥5 regime switch. - ryser_continuous.py: unified estimator skeleton - test_lambda_interpolation.py: smooth transition verification Build: 2987 jobs, 0 errors
This commit is contained in:
parent
5d248d7702
commit
93c6b0a691
3 changed files with 124 additions and 0 deletions
23
experiments/bosonic_continuous/README.md
Normal file
23
experiments/bosonic_continuous/README.md
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
# Bosonic Continuous Interpolation Experiment
|
||||||
|
|
||||||
|
Testing a unified Monte Carlo estimator without regime switching.
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
Replace hard p≥5 cutoff with continuous λ(p) interpolation:
|
||||||
|
```
|
||||||
|
λ(p) = exp(-p²/N)
|
||||||
|
Q(p) = λ(p) Q_bos + (1-λ(p)) Q_fact
|
||||||
|
```
|
||||||
|
|
||||||
|
## Structure
|
||||||
|
- `kernel/ryser_continuous.py` — Unified permanent estimator
|
||||||
|
- `kernel/mode_sampler.py` — Mode sampling kernel
|
||||||
|
- `tests/test_lambda_interpolation.py` — Verify continuity
|
||||||
|
|
||||||
|
## Key Change
|
||||||
|
Remove:
|
||||||
|
```python
|
||||||
|
if p >= 5: distinguishable_k()
|
||||||
|
```
|
||||||
|
|
||||||
|
Replace with single estimator using Ryser permanent for all p ≤ 6.
|
||||||
59
experiments/bosonic_continuous/kernel/ryser_continuous.py
Normal file
59
experiments/bosonic_continuous/kernel/ryser_continuous.py
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Unified Ryser-based Monte Carlo estimator for bosonic permanental distributions.
|
||||||
|
No regime switching — single estimator for all p ≤ 6.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import math
|
||||||
|
from typing import List
|
||||||
|
|
||||||
|
def ryser_permanent(matrix: List[List[complex]]) -> complex:
|
||||||
|
"""Compute permanent using Ryser's formula."""
|
||||||
|
p = len(matrix)
|
||||||
|
if p == 0:
|
||||||
|
return 1.0
|
||||||
|
# Generate all subsets via bitmask
|
||||||
|
total = 0j
|
||||||
|
for mask in range(1, 1 << p):
|
||||||
|
sign = (-1) ** (p - bin(mask).count("1"))
|
||||||
|
prod = 1.0
|
||||||
|
for row in matrix:
|
||||||
|
s = 0.0
|
||||||
|
for j in range(p):
|
||||||
|
if mask & (1 << j):
|
||||||
|
s += row[j].real # Use real part for simplicity
|
||||||
|
prod *= s
|
||||||
|
total += sign * prod
|
||||||
|
return total
|
||||||
|
|
||||||
|
def lambda_interpolation(p: int, N: int) -> float:
|
||||||
|
"""Continuous interpolation parameter.
|
||||||
|
|
||||||
|
λ(p) = exp(-p²/N)
|
||||||
|
λ → 1 as p² << N (weak interference, fully bosonic)
|
||||||
|
λ → 0 as p² >> N (strong interference, factorized)
|
||||||
|
"""
|
||||||
|
return math.exp(-p * p / N)
|
||||||
|
|
||||||
|
def unified_bosonic_estimator(U: List[List[complex]], p: int, samples: int = 1000) -> dict:
|
||||||
|
"""Single estimator for all photon numbers.
|
||||||
|
|
||||||
|
Returns distribution histogram using continuous λ(p) weighting.
|
||||||
|
"""
|
||||||
|
N = len(U)
|
||||||
|
lam = lambda_interpolation(p, N)
|
||||||
|
|
||||||
|
# Monte Carlo sampling
|
||||||
|
results = {}
|
||||||
|
for _ in range(samples):
|
||||||
|
# Sample modes (simplified)
|
||||||
|
S = [j % N for j in range(p)] # Placeholder
|
||||||
|
M = [[U[S[i]][j] for j in range(p)] for i in range(p)]
|
||||||
|
perm = ryser_permanent(M)
|
||||||
|
w = abs(perm) ** 2
|
||||||
|
|
||||||
|
# Apply λ(p) weighting
|
||||||
|
weighted = lam * w + (1 - lam) * sum(abs(U[i][j])**2 for i in range(N) for j in range(N)) / (N * N)
|
||||||
|
results[str(S)] = weighted
|
||||||
|
|
||||||
|
return {"histogram": results, "lambda": lam, "p": p, "N": N}
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Test lambda interpolation for bosonic Monte Carlo regime transition.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import math
|
||||||
|
import sys
|
||||||
|
sys.path.insert(0, "/home/allaun/SilverSight/experiments/bosonic_continuous/kernel")
|
||||||
|
|
||||||
|
def test_lambda_values():
|
||||||
|
"""Verify lambda interpolation at key photon numbers."""
|
||||||
|
N = 2000
|
||||||
|
|
||||||
|
cases = [
|
||||||
|
(p, N, "expected behavior")
|
||||||
|
for p in [2, 3, 4, 5, 6]
|
||||||
|
for N in [2000]
|
||||||
|
]
|
||||||
|
|
||||||
|
print("p | lambda | regime")
|
||||||
|
print("--|---------|----------")
|
||||||
|
for p, N, _ in cases:
|
||||||
|
lam = math.exp(-p * p / N)
|
||||||
|
regime = "bosonic" if lam > 0.9 else "crossover" if lam > 0.5 else "classical"
|
||||||
|
print(f"{p} | {lam:.4f} | {regime}")
|
||||||
|
|
||||||
|
def test_entropy_continuity():
|
||||||
|
"""Mock test for entropy continuity across p values."""
|
||||||
|
N = 2000
|
||||||
|
total_entropy = 0.0
|
||||||
|
for p in range(1, 7):
|
||||||
|
lam = math.exp(-p * p / N)
|
||||||
|
# Mock: entropy should vary smoothly
|
||||||
|
mock_entropy = 10.0 + (1 - lam) * 2
|
||||||
|
total_entropy += mock_entropy
|
||||||
|
print(f"p={p}: entropy~{mock_entropy:.2f}")
|
||||||
|
print(f"Total: {total_entropy:.2f}")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
test_lambda_values()
|
||||||
|
print()
|
||||||
|
test_entropy_continuity()
|
||||||
Loading…
Add table
Reference in a new issue