mirror of
https://github.com/allaunthefox/Research-Stack.git
synced 2026-07-31 03:05:21 +00:00
449 lines
18 KiB
Python
449 lines
18 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Eigenvector Stability of Braided Field in Noisy Environment
|
|
|
|
This script computes the eigenvector decomposition of the braided field
|
|
transfer matrix and analyzes stability under various noise conditions.
|
|
This is relevant for compression - if information is encoded in transfer
|
|
characteristics, we need to know if those characteristics are stable.
|
|
"""
|
|
|
|
import numpy as np
|
|
import cmath
|
|
import hashlib
|
|
import json
|
|
import zlib
|
|
from dataclasses import dataclass
|
|
from datetime import datetime, timezone
|
|
from pathlib import Path
|
|
from typing import List, Tuple
|
|
import matplotlib.pyplot as plt
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
RECEIPT_PATH = ROOT / "4-Infrastructure" / "hardware" / "noise_stability_sim_receipt.json"
|
|
PLOT_PATH = ROOT / "4-Infrastructure" / "hardware" / "eigenvalue_trajectory.png"
|
|
|
|
@dataclass
|
|
class NoiseEnvironment:
|
|
"""Parameters for the noisy environment."""
|
|
thermal_noise: float # Temperature-dependent noise
|
|
quantum_noise: float # Quantum fluctuations
|
|
disorder_strength: float # Structural disorder
|
|
correlation_length: float # Noise correlation length
|
|
|
|
class BraidedFieldMatrix:
|
|
"""Linear system representation of braided field for eigenvector analysis."""
|
|
|
|
def __init__(self, num_particles: int = 4):
|
|
self.num_particles = num_particles
|
|
# Transfer matrix representing the system
|
|
self.matrix = np.eye(num_particles, dtype=complex)
|
|
self.eigenvalues = None
|
|
self.eigenvectors = None
|
|
|
|
def apply_hamiltonian_component(self, component_type: str, weight: float):
|
|
"""Apply a Hamiltonian component to the transfer matrix."""
|
|
# Component-specific matrix modifications
|
|
if component_type == 'photon':
|
|
# Photon: diagonal phase shifts
|
|
for i in range(self.num_particles):
|
|
self.matrix[i, i] *= cmath.exp(1j * weight * 0.1)
|
|
elif component_type == 'electron':
|
|
# Electron: off-diagonal coupling
|
|
for i in range(self.num_particles - 1):
|
|
self.matrix[i, i+1] += weight * 0.05 * cmath.exp(1j * np.pi/4)
|
|
self.matrix[i+1, i] += weight * 0.05 * cmath.exp(-1j * np.pi/4)
|
|
elif component_type == 'phonon':
|
|
# Phonon: stronger coupling with phase
|
|
for i in range(self.num_particles - 1):
|
|
self.matrix[i, i+1] += weight * 0.1 * cmath.exp(1j * np.pi/2)
|
|
self.matrix[i+1, i] += weight * 0.1 * cmath.exp(-1j * np.pi/2)
|
|
elif component_type == 'interaction':
|
|
# Interaction: global coupling
|
|
for i in range(self.num_particles):
|
|
for j in range(self.num_particles):
|
|
if i != j:
|
|
self.matrix[i, j] += weight * 0.02 * cmath.exp(1j * np.pi)
|
|
|
|
def add_noise(self, noise_env: NoiseEnvironment, gain: float = 0.01):
|
|
"""Add noise to the transfer matrix."""
|
|
n = self.num_particles
|
|
|
|
# Thermal noise: random perturbations
|
|
thermal_perturbation = np.random.normal(0, noise_env.thermal_noise, (n, n)) + \
|
|
1j * np.random.normal(0, noise_env.thermal_noise, (n, n))
|
|
|
|
# Quantum noise: coherent perturbations
|
|
quantum_perturbation = np.random.normal(0, noise_env.quantum_noise, (n, n)) * \
|
|
np.exp(1j * np.random.uniform(0, 2*np.pi, (n, n)))
|
|
|
|
# Disorder: diagonal variations
|
|
disorder = np.random.normal(0, noise_env.disorder_strength, n)
|
|
disorder_matrix = np.diag(disorder)
|
|
|
|
# Combine noise sources
|
|
total_noise = thermal_perturbation + quantum_perturbation + disorder_matrix
|
|
self.matrix += total_noise * gain
|
|
|
|
def compute_eigendecomposition(self):
|
|
"""Compute eigenvalues and eigenvectors."""
|
|
self.eigenvalues, self.eigenvectors = np.linalg.eig(self.matrix)
|
|
return self.eigenvalues, self.eigenvectors
|
|
|
|
def spectral_radius(self) -> float:
|
|
"""Compute spectral radius (max eigenvalue magnitude)."""
|
|
if self.eigenvalues is None:
|
|
self.compute_eigendecomposition()
|
|
return max(abs(ev) for ev in self.eigenvalues)
|
|
|
|
def condition_number(self) -> float:
|
|
"""Compute condition number (stability metric)."""
|
|
if self.eigenvalues is None:
|
|
self.compute_eigendecomposition()
|
|
magnitudes = [abs(ev) for ev in self.eigenvalues]
|
|
return max(magnitudes) / (min(magnitudes) + 1e-10)
|
|
|
|
def stability_margin(self) -> float:
|
|
"""Compute stability margin (distance to instability)."""
|
|
if self.eigenvalues is None:
|
|
self.compute_eigendecomposition()
|
|
# Stability margin = minimum distance of eigenvalues from unit circle
|
|
margin = min(abs(abs(ev) - 1.0) for ev in self.eigenvalues)
|
|
return margin
|
|
|
|
def dominant_eigenvector(self) -> np.ndarray:
|
|
"""Get the eigenvector corresponding to the dominant eigenvalue."""
|
|
if self.eigenvalues is None:
|
|
self.compute_eigendecomposition()
|
|
idx = np.argmax(abs(self.eigenvalues))
|
|
return self.eigenvectors[:, idx]
|
|
|
|
def noise_stability_analysis(gain: float = 0.01, label: str = "micro"):
|
|
"""Analyze eigenvector stability under various noise conditions."""
|
|
print(f"=== Eigenvector Stability Analysis in Noisy Environment ({label}, gain={gain}) ===\n")
|
|
|
|
# Test different noise levels
|
|
noise_levels = [
|
|
("Low noise", NoiseEnvironment(0.01, 0.01, 0.01, 1.0)),
|
|
("Medium noise", NoiseEnvironment(0.05, 0.05, 0.05, 1.0)),
|
|
("High noise", NoiseEnvironment(0.1, 0.1, 0.1, 1.0)),
|
|
("Extreme noise", NoiseEnvironment(0.2, 0.2, 0.2, 1.0)),
|
|
]
|
|
|
|
print("Stability metrics vs noise level:")
|
|
print("-" * 70)
|
|
print(f"{'Noise Level':<15} {'Spectral Radius':<15} {'Condition #':<12} {'Stability Margin':<15}")
|
|
print("-" * 70)
|
|
|
|
results = []
|
|
|
|
for name, noise_env in noise_levels:
|
|
# Create braided field with Hamiltonian components
|
|
bf = BraidedFieldMatrix(num_particles=4)
|
|
|
|
# Apply standard Hamiltonian components
|
|
bf.apply_hamiltonian_component('photon', weight=1.0)
|
|
bf.apply_hamiltonian_component('electron', weight=1.0)
|
|
bf.apply_hamiltonian_component('phonon', weight=1.0)
|
|
bf.apply_hamiltonian_component('interaction', weight=1.0)
|
|
|
|
# Add noise
|
|
bf.add_noise(noise_env, gain=gain)
|
|
|
|
# Compute stability metrics
|
|
spectral_radius = bf.spectral_radius()
|
|
condition_num = bf.condition_number()
|
|
stability_margin = bf.stability_margin()
|
|
|
|
print(f"{name:<15} {spectral_radius:<15.4f} {condition_num:<12.4f} {stability_margin:<15.4f}")
|
|
|
|
results.append({
|
|
"name": name,
|
|
"gain": gain,
|
|
"spectral_radius": float(spectral_radius),
|
|
"condition_number": float(condition_num),
|
|
"stability_margin": float(stability_margin),
|
|
"eigenvalues": [
|
|
{
|
|
"real": float(ev.real),
|
|
"imag": float(ev.imag),
|
|
"magnitude": float(abs(ev)),
|
|
"phase": float(cmath.phase(ev)),
|
|
}
|
|
for ev in bf.eigenvalues
|
|
],
|
|
})
|
|
|
|
print()
|
|
|
|
# Analyze eigenvalue distribution
|
|
print("Eigenvalue distribution (high noise case):")
|
|
high_noise_eigenvalues = [
|
|
complex(row["real"], row["imag"]) for row in results[-1]["eigenvalues"]
|
|
]
|
|
for i, ev in enumerate(high_noise_eigenvalues):
|
|
print(f" λ_{i}: {ev:.4f} (magnitude: {abs(ev):.4f}, phase: {cmath.phase(ev):.4f} rad)")
|
|
|
|
return {
|
|
"label": label,
|
|
"gain": gain,
|
|
"rows": results,
|
|
}
|
|
|
|
def eigenvector_persistence(gain: float = 0.01, label: str = "micro"):
|
|
"""Test if eigenvectors persist under repeated noise."""
|
|
print(f"\n=== Eigenvector Persistence Under Repeated Noise ({label}, gain={gain}) ===\n")
|
|
|
|
bf = BraidedFieldMatrix(num_particles=4)
|
|
|
|
# Apply standard Hamiltonian components
|
|
bf.apply_hamiltonian_component('photon', weight=1.0)
|
|
bf.apply_hamiltonian_component('electron', weight=1.0)
|
|
bf.apply_hamiltonian_component('phonon', weight=1.0)
|
|
bf.apply_hamiltonian_component('interaction', weight=1.0)
|
|
|
|
# Get initial eigenvector
|
|
bf.compute_eigendecomposition()
|
|
initial_eigenvector = bf.dominant_eigenvector()
|
|
|
|
print(f"Initial dominant eigenvector: {initial_eigenvector}")
|
|
|
|
noise_env = NoiseEnvironment(0.05, 0.05, 0.05, 1.0)
|
|
|
|
# Apply noise multiple times and track eigenvector similarity
|
|
similarities = []
|
|
|
|
for i in range(10):
|
|
bf.add_noise(noise_env, gain=gain)
|
|
bf.compute_eigendecomposition()
|
|
current_eigenvector = bf.dominant_eigenvector()
|
|
|
|
# Compute similarity (cosine of angle between vectors)
|
|
similarity = abs(np.vdot(initial_eigenvector, current_eigenvector)) / \
|
|
(np.linalg.norm(initial_eigenvector) * np.linalg.norm(current_eigenvector))
|
|
similarities.append(similarity)
|
|
|
|
print(f" Noise iteration {i}: similarity = {similarity:.4f}")
|
|
|
|
print(f"\nAverage similarity: {np.mean(similarities):.4f}")
|
|
print(f"Similarity degradation: {similarities[0] - similarities[-1]:.4f}")
|
|
|
|
return {
|
|
"label": label,
|
|
"gain": gain,
|
|
"similarities": [float(x) for x in similarities],
|
|
"average_similarity": float(np.mean(similarities)),
|
|
"similarity_degradation": float(similarities[0] - similarities[-1]),
|
|
}
|
|
|
|
def information_capacity_analysis(gain: float = 0.01, label: str = "micro"):
|
|
"""Analyze information capacity under noise using eigenvalue spectrum."""
|
|
print(f"\n=== Information Capacity Analysis ({label}, gain={gain}) ===\n")
|
|
|
|
bf = BraidedFieldMatrix(num_particles=4)
|
|
|
|
# Apply standard Hamiltonian components
|
|
bf.apply_hamiltonian_component('photon', weight=1.0)
|
|
bf.apply_hamiltonian_component('electron', weight=1.0)
|
|
bf.apply_hamiltonian_component('phonon', weight=1.0)
|
|
bf.apply_hamiltonian_component('interaction', weight=1.0)
|
|
|
|
print("Information capacity vs noise level:")
|
|
print("-" * 60)
|
|
print(f"{'Noise Level':<15} {'Spectral Entropy':<20} {'Effective Rank':<15}")
|
|
print("-" * 60)
|
|
|
|
noise_levels = [0.0, 0.02, 0.05, 0.1, 0.2]
|
|
rows = []
|
|
|
|
for noise_level in noise_levels:
|
|
bf_temp = BraidedFieldMatrix(num_particles=4)
|
|
bf_temp.matrix = bf.matrix.copy()
|
|
|
|
if noise_level > 0:
|
|
noise_env = NoiseEnvironment(noise_level, noise_level, noise_level, 1.0)
|
|
bf_temp.add_noise(noise_env, gain=gain)
|
|
|
|
bf_temp.compute_eigendecomposition()
|
|
|
|
# Compute spectral entropy (information measure)
|
|
eigenvalue_mags = np.array([abs(ev) for ev in bf_temp.eigenvalues])
|
|
eigenvalue_mags = eigenvalue_mags / np.sum(eigenvalue_mags) # Normalize
|
|
spectral_entropy = -np.sum(eigenvalue_mags * np.log(eigenvalue_mags + 1e-10))
|
|
|
|
# Compute effective rank (number of significant eigenvalues)
|
|
effective_rank = np.sum(eigenvalue_mags > 0.1)
|
|
|
|
print(f"{noise_level:<15.2f} {spectral_entropy:<20.4f} {effective_rank:<15.0f}")
|
|
rows.append({
|
|
"noise_level": float(noise_level),
|
|
"spectral_entropy": float(spectral_entropy),
|
|
"effective_rank": int(effective_rank),
|
|
})
|
|
|
|
return {
|
|
"label": label,
|
|
"gain": gain,
|
|
"rows": rows,
|
|
}
|
|
|
|
def stochastic_crc_lane(stability: dict, persistence: dict, capacity: dict) -> dict:
|
|
"""Derive a deterministic CRC witness from the seeded stochastic micro-noise lane.
|
|
|
|
This is not an error-correcting code by itself. It is a compact witness over
|
|
the sampled noise response, suitable for detecting drift in a replayed probe.
|
|
"""
|
|
payload = {
|
|
"stability_rows": [
|
|
{
|
|
"name": row["name"],
|
|
"spectral_radius_q": round(row["spectral_radius"], 8),
|
|
"condition_number_q": round(row["condition_number"], 8),
|
|
"stability_margin_q": round(row["stability_margin"], 8),
|
|
"eigenvalue_magnitudes_q": [
|
|
round(ev["magnitude"], 8) for ev in row["eigenvalues"]
|
|
],
|
|
"eigenvalue_phases_q": [
|
|
round(ev["phase"], 8) for ev in row["eigenvalues"]
|
|
],
|
|
}
|
|
for row in stability["rows"]
|
|
],
|
|
"persistence_q": [round(x, 8) for x in persistence["similarities"]],
|
|
"capacity_rows": [
|
|
{
|
|
"noise_level": row["noise_level"],
|
|
"spectral_entropy_q": round(row["spectral_entropy"], 8),
|
|
"effective_rank": row["effective_rank"],
|
|
}
|
|
for row in capacity["rows"]
|
|
],
|
|
}
|
|
encoded = json.dumps(payload, sort_keys=True, separators=(",", ":")).encode("utf-8")
|
|
crc = zlib.crc32(encoded) & 0xFFFFFFFF
|
|
return {
|
|
"schema": "stochastic_crc_lane_v1",
|
|
"source": "seeded micro-gain eigen/noise lane",
|
|
"quantization": "round floating metrics to 8 decimal places before CRC32",
|
|
"byte_length": len(encoded),
|
|
"crc32_hex": f"{crc:08x}",
|
|
"payload_sha256": hashlib.sha256(encoded).hexdigest(),
|
|
"claim_boundary": "CRC witnesses replay drift in this seeded toy noise lane; it is not a proof of physical noise immunity or cryptographic integrity.",
|
|
}
|
|
|
|
def plot_eigenvalue_trajectory(gain: float = 0.01, label: str = "micro"):
|
|
"""Plot eigenvalue trajectory under increasing noise."""
|
|
print(f"\n=== Eigenvalue Trajectory Visualization ({label}, gain={gain}) ===\n")
|
|
|
|
bf = BraidedFieldMatrix(num_particles=4)
|
|
|
|
# Apply standard Hamiltonian components
|
|
bf.apply_hamiltonian_component('photon', weight=1.0)
|
|
bf.apply_hamiltonian_component('electron', weight=1.0)
|
|
bf.apply_hamiltonian_component('phonon', weight=1.0)
|
|
bf.apply_hamiltonian_component('interaction', weight=1.0)
|
|
|
|
# Track eigenvalues under increasing noise
|
|
noise_levels = np.linspace(0, 0.3, 30)
|
|
eigenvalue_trajectories = [[] for _ in range(4)]
|
|
|
|
for noise_level in noise_levels:
|
|
bf_temp = BraidedFieldMatrix(num_particles=4)
|
|
bf_temp.matrix = bf.matrix.copy()
|
|
|
|
if noise_level > 0:
|
|
noise_env = NoiseEnvironment(noise_level, noise_level, noise_level, 1.0)
|
|
bf_temp.add_noise(noise_env, gain=gain)
|
|
|
|
bf_temp.compute_eigendecomposition()
|
|
|
|
for i, ev in enumerate(bf_temp.eigenvalues):
|
|
eigenvalue_trajectories[i].append(ev)
|
|
|
|
# Plot trajectories
|
|
fig, ax = plt.subplots(figsize=(10, 8))
|
|
|
|
colors = ['red', 'blue', 'green', 'orange']
|
|
for i, trajectory in enumerate(eigenvalue_trajectories):
|
|
real_parts = [ev.real for ev in trajectory]
|
|
imag_parts = [ev.imag for ev in trajectory]
|
|
ax.plot(real_parts, imag_parts, color=colors[i], linewidth=2,
|
|
marker='o', markersize=3, label=f'λ_{i}')
|
|
# Mark initial and final points
|
|
ax.plot(real_parts[0], imag_parts[0], 's', color=colors[i], markersize=8)
|
|
ax.plot(real_parts[-1], imag_parts[-1], '^', color=colors[i], markersize=8)
|
|
|
|
# Draw unit circle
|
|
theta = np.linspace(0, 2*np.pi, 100)
|
|
ax.plot(np.cos(theta), np.sin(theta), 'k--', alpha=0.3, label='Unit circle')
|
|
|
|
ax.set_xlabel('Re(λ)')
|
|
ax.set_ylabel('Im(λ)')
|
|
ax.set_title('Eigenvalue Trajectories Under Increasing Noise')
|
|
ax.axhline(y=0, color='k', linestyle='-', alpha=0.1)
|
|
ax.axvline(x=0, color='k', linestyle='-', alpha=0.1)
|
|
ax.grid(True, alpha=0.3)
|
|
ax.legend()
|
|
ax.axis('equal')
|
|
|
|
plt.tight_layout()
|
|
plt.savefig(PLOT_PATH, dpi=150)
|
|
print(f"Eigenvalue trajectory plot saved to {PLOT_PATH}")
|
|
return {
|
|
"label": label,
|
|
"gain": gain,
|
|
"plot_path": str(PLOT_PATH),
|
|
"noise_levels": [float(x) for x in noise_levels],
|
|
}
|
|
|
|
if __name__ == "__main__":
|
|
# Set random seed for reproducibility
|
|
np.random.seed(42)
|
|
|
|
micro_stability = noise_stability_analysis(gain=0.01, label="micro")
|
|
micro_persistence = eigenvector_persistence(gain=0.01, label="micro")
|
|
micro_capacity = information_capacity_analysis(gain=0.01, label="micro")
|
|
micro_stochastic_crc = stochastic_crc_lane(
|
|
micro_stability,
|
|
micro_persistence,
|
|
micro_capacity,
|
|
)
|
|
trajectory = plot_eigenvalue_trajectory(gain=0.01, label="micro")
|
|
|
|
direct_stability = noise_stability_analysis(gain=1.0, label="direct")
|
|
direct_persistence = eigenvector_persistence(gain=1.0, label="direct")
|
|
direct_capacity = information_capacity_analysis(gain=1.0, label="direct")
|
|
|
|
receipt = {
|
|
"generated_utc": datetime.now(timezone.utc).isoformat(),
|
|
"lawful": True,
|
|
"mode": "virtual_only",
|
|
"source_note": "No hardware programming, RF emission, JTAG, serial flashing, board access, or material claim. Python eigenvector stability simulation only.",
|
|
"noise_gain_boundary": "The original micro lane uses gain=0.01, so nominal extreme noise is intentionally small. Direct lane uses gain=1.0 to expose degradation.",
|
|
"micro_gain": {
|
|
"stability": micro_stability,
|
|
"persistence": micro_persistence,
|
|
"capacity": micro_capacity,
|
|
"stochastic_crc": micro_stochastic_crc,
|
|
},
|
|
"direct_gain": {
|
|
"stability": direct_stability,
|
|
"persistence": direct_persistence,
|
|
"capacity": direct_capacity,
|
|
},
|
|
"trajectory": trajectory,
|
|
"claim_boundary": "This simulation records transfer-matrix eigen stability in a toy braided-field model. It does not prove topological protection, local-noise immunity, device feasibility, material existence, compression advantage, or Hutter Prize relevance.",
|
|
}
|
|
encoded = json.dumps(receipt, indent=2, sort_keys=True).encode("utf-8")
|
|
receipt["receipt_hash_preimage_sha256"] = hashlib.sha256(encoded).hexdigest()
|
|
RECEIPT_PATH.write_text(json.dumps(receipt, indent=2, sort_keys=True) + "\n", encoding="utf-8")
|
|
|
|
print("\n=== Analysis Complete ===")
|
|
print("The eigenvector analysis shows:")
|
|
print("1. Micro-gain noise can look almost invariant because gain=0.01")
|
|
print("2. Direct-gain noise exposes actual degradation and mode drift")
|
|
print("3. Eigenvectors should be treated as transfer-characteristic candidates")
|
|
print("4. Eigenvalue trajectories show how the toy system evolves under noise")
|
|
print("\nFor compression applications, this suggests that transfer characteristic")
|
|
print("encoding is worth testing, but no compression advantage is claimed.")
|
|
print(f"Receipt written to {RECEIPT_PATH}")
|