Good afternoon Mr. SignalTiger,
I asked Grok to make you a present.
An Ai for you. Not really, but I hope you like it.
Mr. QuantumSoundwave you can have the present too; code below.
----------
import numpy as np
import matplotlib.pyplot as plt
import json
from datetime import datetime
from scipy.signal import find_peaks
from scipy.interpolate import RegularGridInterpolator
# =====================================================================
# 1. NLDM + TIMING (kept for realism)
# =====================================================================
class NLDMCell:
def \__init_\_(self):
self.input_transition_axis = np.array(\[0.01, 0.05, 0.15, 0.30\])
self.output_load_axis = np.array(\[1.0, 5.0, 20.0, 50.0\])
self.delay_table = np.array(\[\[0.05,0.08,0.18,0.35\],\[0.07,0.11,0.22,0.42\],\[0.12,0.18,0.33,0.61\],\[0.22,0.30,0.52,0.95\]\])
self.interpolator = RegularGridInterpolator((self.input_transition_axis, self.output_load_axis), self.delay_table, bounds_error=False, fill_value=2.0)
def compute_delay(self, tran_in, load_out):
return float(self.interpolator(\[\[tran_in, load_out\]\])\[0\])
class TimingGraphEvaluator:
def \__init_\_(self):
self.false_paths = {("REGA", "REGC")}
self.multi_cycle_paths = {("REGA", "REGB"): 2}
def calculate_path_slack(self, start, end, raw_delay, clock=1.0):
if (start, end) in self.false_paths:
return "FALSE_PATH", np.nan, True
mult = self.multi_cycle_paths.get((start, end), 1)
slack = mult \* clock - raw_delay
return f"MCP\_{mult}X" if mult > 1 else "SINGLE", slack, slack >= 0
# =====================================================================
# ROTOR TRACKER — Enhanced with Paper’s Recovery Modes
# =====================================================================
class RotorTracker:
def \__init_\_(self, num_rotors=6, length=48):
self.num_rotors = num_rotors
self.length = length
self.rotors = \[np.zeros(length, dtype=float) for \_ in range(num_rotors)\]
self.positions = \[0\] \* num_rotors
self.stress_history = \[\]
def compute_stress(self, cycle):
noise = 0.05 \* (1.004 \*\* cycle)
jitter = np.random.normal(0, 0.08)
chaos = 0.2 \* np.sin(cycle / 5.0)
S = noise + jitter + chaos
self.stress_history.append(S)
return S
def update(self, binary_chains, cycle, recovery_mode="auto"):
S = self.compute_stress(cycle)
V = np.mean(\[np.mean(chain) for chain in binary_chains if len(chain) > 0\]) if binary_chains else 0.5
for i, chain in enumerate(binary_chains):
if len(chain) == 0: continue
bit = float(np.mean(chain) > 0.5)
\# Aggressive rotation
step = np.random.randint(1, 4)
self.positions\[i\] = (self.positions\[i\] + step) % self.length
self.rotors\[i\]\[self.positions\[i\]\] = bit
\# === Recovery Modes from Paper ===
spread = max(np.mean(r) for r in self.rotors) - min(np.mean(r) for r in self.rotors)
if spread > 0.35 or S > 0.6: # Trigger recovery
active_mode = recovery_mode
if recovery_mode == "auto":
active_mode = "snap" if S > 0.6 else "soft"
if active_mode == "snap":
for r in self.rotors:
r.fill(V)
elif active_mode == "soft":
for r in self.rotors:
r\[:\] = r + 0.6 \* (V - r)
return {
'stress': S,
'spread': spread,
'consistency': np.mean(\[abs(np.mean(r) - V) < 0.5 for r in self.rotors\]),
'mode': active_mode if 'active_mode' in locals() else recovery_mode,
'V': V
}
# =====================================================================
# MAIN HYBRID ENGINE
# =====================================================================
class ExtendedHybridSTA:
def \__init_\_(self):
self.mode = "BINARY"
self.noise_std = 0.04
self.cell = NLDMCell()
self.graph = TimingGraphEvaluator()
self.rotor = RotorTracker()
def simulate_multi_waveforms(self, jitter):
waveforms = \[\]
chains = \[\]
for w in range(6):
ideal = np.repeat(\[1.0, 0.0\], 600)
wf = ideal + 0.06\*np.sin(2\*np.pi\*(0.035+w\*0.008)\*np.arange(len(ideal))) + \\
np.random.normal(0, self.noise_std + w\*0.01, len(ideal)) + jitter
wf = np.clip(wf, 0, 1)
waveforms.append(wf)
chains.append(np.where(wf > 0.5, 1, 0))
return waveforms, chains
def run_cycle(self, cycle, start, end, slew, load, skew):
delay = self.cell.compute_delay(slew, load) + skew
ptype, slack, is_met = self.graph.calculate_path_slack(start, end, delay)
if self.mode == "BINARY":
if delay > 1.45 or np.random.rand() < 0.08: # Force occasional stress
self.mode = "STA"
self.noise_std = min(0.25, self.noise_std + 0.04)
print(f"\[{cycle:3d}\] ⚠️ Switching to STA")
return "BINARY", delay, slack, None
\# STA Mode
\_, binary_chains = self.simulate_multi_waveforms(skew)
stats = self.rotor.update(binary_chains, cycle, recovery_mode="auto")
if stats\['stress'\] < 0.4 and stats\['consistency'\] > 0.75:
self.mode = "BINARY"
self.noise_std = max(0.03, self.noise_std - 0.035)
print(f"\[{cycle:3d}\] ✅ Recovered to BINARY")
return "STA", delay, slack, stats
def run_simulation(self, cycles=150, save_log=True):
print("=== Hybrid STA Simulation with Snap/Soft/Auto Recovery ===\\n")
log = \[\]
paths = \[("REGA","REGB"), ("REGA","REGC"), ("REGB","REGC")\]
for c in range(1, cycles+1):
start, end = paths\[np.random.randint(0,3)\]
slew = np.random.uniform(0.02, 0.29)
load = np.random.uniform(2, 48)
skew = np.random.normal(0, 0.12)
mode, delay, slack, stats = self.run_cycle(c, start, end, slew, load, skew)
entry = {'cycle':c, 'mode':mode, 'delay':delay, 'slack':slack, 'stress':None, 'spread':None, 'consistency':None}
if stats:
entry.update({'stress':stats\['stress'\], 'spread':stats\['spread'\], 'consistency':stats\['consistency'\], 'recovery':stats\['mode'\]})
log.append(entry)
if stats:
print(f"Cycle {c:3d} | {mode:6s} | Stress:{stats\['stress'\]:.3f} | Spread:{stats\['spread'\]:.3f} | Cons:{stats\['consistency'\]:.3f} | Rec:{stats\['mode'\]}")
else:
print(f"Cycle {c:3d} | {mode:6s} | Delay:{delay:.3f}")
if save_log:
filename = f"hybrid_sta_log\_{datetime.now().strftime('%Y%m%d\_%H%M%S')}.json"
with open(filename, 'w') as f:
json.dump(log, f, indent=2)
print(f"\\nFull log saved to: {filename}")
return log
# =====================================================================
# RUN LONG TEST
# =====================================================================
if _name_ == “_main_”:
engine = ExtendedHybridSTA()
results = engine.run_simulation(cycles=200) # Longer test as requested
\# === Paper-style Plots ===
cycles = \[r\['cycle'\] for r in results\]
stress = \[r.get('stress', 0) for r in results\]
spread = \[r.get('spread', 0) for r in results\]
cons = \[r.get('consistency', 0) for r in results\]
modes = \[1 if r\['mode'\]=='STA' else 0 for r in results\]
fig, axs = plt.subplots(3, 1, figsize=(14, 10), sharex=True)
axs\[0\].plot(cycles, stress, 'r-', label='Stress S(t)')
axs\[0\].set_ylabel('Stress')
axs\[0\].legend()
axs\[0\].grid(True)
axs\[1\].plot(cycles, spread, 'b-', label='Rotor Spread')
axs\[1\].set_ylabel('Spread')
axs\[1\].legend()
axs\[1\].grid(True)
axs\[2\].plot(cycles, cons, 'g-', label='Consistency')
axs\[2\].plot(cycles, modes, 'k--', label='STA Mode')
axs\[2\].set_xlabel('Cycle')
axs\[2\].set_ylabel('Consistency / Mode')
axs\[2\].legend()
axs\[2\].grid(True)
plt.suptitle('Hybrid STA Simulation --- Snap/Soft/Auto Recovery under Chaotic Stress')
plt.tight_layout()
plt.show()
##Sorry – the copy paste added bugs