Initial commit from Beast
This commit is contained in:
@@ -1,62 +0,0 @@
|
||||
import csv
|
||||
from collections import defaultdict
|
||||
|
||||
CSV = '/mnt/d/Resonance_Engine/sweep_results/em_direct_sweep_20260327_080716.csv'
|
||||
|
||||
data = []
|
||||
with open(CSV) as f:
|
||||
reader = csv.DictReader(f)
|
||||
for row in reader:
|
||||
data.append(row)
|
||||
|
||||
cohs = [float(r['coherence']) for r in data]
|
||||
print(f'Total points: {len(data)}')
|
||||
print(f'Coherence range: {min(cohs):.4f} - {max(cohs):.4f}')
|
||||
print(f'Mean coherence: {sum(cohs)/len(cohs):.4f}')
|
||||
|
||||
by_omega = defaultdict(list)
|
||||
for r in data:
|
||||
by_omega[float(r['omega'])].append(r)
|
||||
|
||||
print()
|
||||
print('=== Best coherence per omega ===')
|
||||
for omega in sorted(by_omega.keys()):
|
||||
rows = by_omega[omega]
|
||||
best = max(rows, key=lambda r: float(r['coherence']))
|
||||
print(f' Omega={omega:.1f}: Coh={float(best["coherence"]):.4f} K={best["khra_amp"]} G={best["gixx_amp"]} Asym={float(best["asymmetry"]):.4f}')
|
||||
|
||||
print()
|
||||
print('=== Top 10 parameter combos (by coherence) ===')
|
||||
sorted_data = sorted(data, key=lambda r: float(r['coherence']), reverse=True)
|
||||
for i, r in enumerate(sorted_data[:10]):
|
||||
print(f' #{i+1}: Omega={r["omega"]} K={r["khra_amp"]} G={r["gixx_amp"]} -> Coh={r["coherence"]} Asym={r["asymmetry"]} Vort={r["vorticity_mean"]}')
|
||||
|
||||
print()
|
||||
print('=== Bottom 5 parameter combos (by coherence) ===')
|
||||
for i, r in enumerate(sorted_data[-5:]):
|
||||
print(f' Omega={r["omega"]} K={r["khra_amp"]} G={r["gixx_amp"]} -> Coh={r["coherence"]} Asym={r["asymmetry"]}')
|
||||
|
||||
print()
|
||||
print('=== Asymmetry at coherence extremes ===')
|
||||
top20 = sorted_data[:20]
|
||||
bot20 = sorted_data[-20:]
|
||||
print(f' Top 20 coh avg asymmetry: {sum(float(r["asymmetry"]) for r in top20)/20:.4f}')
|
||||
print(f' Bottom 20 coh avg asymmetry: {sum(float(r["asymmetry"]) for r in bot20)/20:.4f}')
|
||||
|
||||
print()
|
||||
print('=== Coherence by khra (averaged across all omega/gixx) ===')
|
||||
by_khra = defaultdict(list)
|
||||
for r in data:
|
||||
by_khra[r['khra_amp']].append(float(r['coherence']))
|
||||
for k in sorted(by_khra.keys()):
|
||||
vals = by_khra[k]
|
||||
print(f' K={k}: avg_coh={sum(vals)/len(vals):.4f} (n={len(vals)})')
|
||||
|
||||
print()
|
||||
print('=== Coherence by gixx (averaged across all omega/khra) ===')
|
||||
by_gixx = defaultdict(list)
|
||||
for r in data:
|
||||
by_gixx[r['gixx_amp']].append(float(r['coherence']))
|
||||
for g in sorted(by_gixx.keys()):
|
||||
vals = by_gixx[g]
|
||||
print(f' G={g}: avg_coh={sum(vals)/len(vals):.4f} (n={len(vals)})')
|
||||
@@ -1,21 +0,0 @@
|
||||
primes = [7, 13, 19, 31, 43, 67, 79, 97, 109, 139]
|
||||
|
||||
print("=== CAN WE EXTRAPOLATE FROM 10 PRIMES? ===")
|
||||
print()
|
||||
|
||||
# Check gaps
|
||||
gaps = [primes[i+1] - primes[i] for i in range(len(primes)-1)]
|
||||
print("Prime gaps:", gaps)
|
||||
print("Mean gap:", sum(gaps)/len(gaps))
|
||||
print()
|
||||
|
||||
# Check if pattern exists
|
||||
print("Pattern analysis (mod 6):")
|
||||
for p in primes:
|
||||
print(f" {p} mod 6 = {p % 6}")
|
||||
|
||||
print()
|
||||
print("CONCLUSION:")
|
||||
print("10 primes is NOT enough for reliable extrapolation.")
|
||||
print("Need at least 100-1000 primes to establish pattern.")
|
||||
print("Current sample only confirms basic modular arithmetic.")
|
||||
@@ -1,21 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Compile khra_gixx_1024_v5 — Golden-Weave integration
|
||||
# Same deps as v4: zmq + nvml, no json-c, no cufft
|
||||
export PATH=/usr/local/cuda-12.6/bin:$PATH
|
||||
export LD_LIBRARY_PATH=/usr/local/cuda-12.6/lib64:$LD_LIBRARY_PATH
|
||||
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
cd "$REPO_ROOT"
|
||||
|
||||
echo "Compiling khra_gixx_1024_v5..."
|
||||
nvcc -O3 -arch=sm_89 \
|
||||
-o build/khra_gixx_1024_v5 \
|
||||
cuda/khra_gixx_1024_v5.cu \
|
||||
-lzmq -lnvidia-ml
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "BUILD OK: build/khra_gixx_1024_v5 ($(date))"
|
||||
ls -la build/khra_gixx_1024_v5
|
||||
else
|
||||
echo "BUILD FAILED"
|
||||
exit 1
|
||||
fi
|
||||
@@ -1,859 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Comprehensive Data Analysis & Report Generator
|
||||
Analyzes the 375-point EM parameter sweep and produces:
|
||||
1. Full statistical summary (text)
|
||||
2. Interactive HTML visualization dashboard
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
from datetime import datetime
|
||||
from collections import Counter
|
||||
import json
|
||||
|
||||
# ── Config ──────────────────────────────────────────────────────────
|
||||
MAGIC_NUMBERS = [2, 8, 20, 28, 50, 82, 126]
|
||||
SWEEP_DIR = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "sweep_results")
|
||||
RESULTS_DIR = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "results")
|
||||
os.makedirs(RESULTS_DIR, exist_ok=True)
|
||||
|
||||
|
||||
def load_data(csv_path=None):
|
||||
if csv_path is None:
|
||||
csvs = sorted([f for f in os.listdir(SWEEP_DIR) if f.startswith("em_direct_sweep") and f.endswith(".csv")])
|
||||
if not csvs:
|
||||
print("No sweep CSVs found"); sys.exit(1)
|
||||
csv_path = os.path.join(SWEEP_DIR, csvs[-1])
|
||||
print(f"Auto-selected: {csvs[-1]}")
|
||||
df = pd.read_csv(csv_path)
|
||||
print(f"Loaded {len(df)} points")
|
||||
return df, os.path.basename(csv_path)
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
# PART 1: Comprehensive Text Report
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
def generate_text_report(df, source_name):
|
||||
R = []
|
||||
ts = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
R.append("=" * 78)
|
||||
R.append(" COMPREHENSIVE PARAMETER SWEEP ANALYSIS — RESONANCE ENGINE")
|
||||
R.append("=" * 78)
|
||||
R.append(f"Source: {source_name}")
|
||||
R.append(f"Generated: {ts}")
|
||||
R.append(f"Points: {len(df)}")
|
||||
R.append(f"Duration: {df['timestamp'].iloc[0]} → {df['timestamp'].iloc[-1]}")
|
||||
R.append("")
|
||||
|
||||
# ── Section 1: Global Statistics ──
|
||||
R.append("─" * 78)
|
||||
R.append("1. GLOBAL STATISTICS")
|
||||
R.append("─" * 78)
|
||||
numeric_cols = ['omega', 'khra_amp', 'gixx_amp', 'coherence', 'asymmetry',
|
||||
'vorticity_mean', 'gpu_temp_c', 'gpu_power_w', 'cycle']
|
||||
R.append(f" {'Column':<18} {'Min':>12} {'Max':>12} {'Mean':>12} {'Std':>12} {'Median':>12}")
|
||||
for col in numeric_cols:
|
||||
v = df[col]
|
||||
R.append(f" {col:<18} {v.min():>12.6f} {v.max():>12.6f} {v.mean():>12.6f} {v.std():>12.6f} {v.median():>12.6f}")
|
||||
|
||||
# ── Section 2: Parameter Space Coverage ──
|
||||
R.append("")
|
||||
R.append("─" * 78)
|
||||
R.append("2. PARAMETER SPACE COVERAGE")
|
||||
R.append("─" * 78)
|
||||
omega_vals = sorted(df['omega'].unique())
|
||||
khra_vals = sorted(df['khra_amp'].unique())
|
||||
gixx_vals = sorted(df['gixx_amp'].unique())
|
||||
R.append(f" Omega: {len(omega_vals)} values: {[round(x,1) for x in omega_vals]}")
|
||||
R.append(f" Khra_amp: {len(khra_vals)} values: {[round(x,3) for x in khra_vals]}")
|
||||
R.append(f" Gixx_amp: {len(gixx_vals)} values: {[round(x,4) for x in gixx_vals]}")
|
||||
R.append(f" Grid: {len(omega_vals)} × {len(khra_vals)} × {len(gixx_vals)} = {len(omega_vals)*len(khra_vals)*len(gixx_vals)} (actual: {len(df)})")
|
||||
|
||||
# ── Section 3: Coherence Analysis ──
|
||||
R.append("")
|
||||
R.append("─" * 78)
|
||||
R.append("3. COHERENCE ANALYSIS")
|
||||
R.append("─" * 78)
|
||||
|
||||
# Top 10 coherence values
|
||||
top10 = df.nlargest(10, 'coherence')
|
||||
R.append(" Top 10 coherence measurements:")
|
||||
R.append(f" {'Rank':>4} {'Ω':>5} {'K':>6} {'G':>7} {'Coh':>10} {'Asym':>8} {'Vort':>10}")
|
||||
for rank, (_, row) in enumerate(top10.iterrows(), 1):
|
||||
R.append(f" {rank:4d} {row['omega']:5.1f} {row['khra_amp']:6.3f} {row['gixx_amp']:7.4f} "
|
||||
f"{row['coherence']:10.6f} {row['asymmetry']:8.4f} {row['vorticity_mean']:10.6f}")
|
||||
|
||||
# Bottom 10
|
||||
bot10 = df.nsmallest(10, 'coherence')
|
||||
R.append("\n Bottom 10 coherence measurements:")
|
||||
R.append(f" {'Rank':>4} {'Ω':>5} {'K':>6} {'G':>7} {'Coh':>10} {'Asym':>8} {'Vort':>10}")
|
||||
for rank, (_, row) in enumerate(bot10.iterrows(), 1):
|
||||
R.append(f" {rank:4d} {row['omega']:5.1f} {row['khra_amp']:6.3f} {row['gixx_amp']:7.4f} "
|
||||
f"{row['coherence']:10.6f} {row['asymmetry']:8.4f} {row['vorticity_mean']:10.6f}")
|
||||
|
||||
# ── Section 4: Per-Omega Breakdown ──
|
||||
R.append("")
|
||||
R.append("─" * 78)
|
||||
R.append("4. PER-OMEGA BREAKDOWN")
|
||||
R.append("─" * 78)
|
||||
R.append(f" {'Ω':>5} {'Coh_min':>10} {'Coh_max':>10} {'Coh_mean':>10} {'Coh_std':>10} "
|
||||
f"{'Asym_mean':>10} {'Vort_mean':>10} {'Best K':>7} {'Best G':>8}")
|
||||
for omega in omega_vals:
|
||||
g = df[df['omega'] == omega]
|
||||
best = g.loc[g['coherence'].idxmax()]
|
||||
R.append(f" {omega:5.1f} {g['coherence'].min():10.6f} {g['coherence'].max():10.6f} "
|
||||
f"{g['coherence'].mean():10.6f} {g['coherence'].std():10.6f} "
|
||||
f"{g['asymmetry'].mean():10.4f} {g['vorticity_mean'].mean():10.6f} "
|
||||
f"{best['khra_amp']:7.3f} {best['gixx_amp']:8.4f}")
|
||||
|
||||
# ── Section 5: Per-Khra Breakdown ──
|
||||
R.append("")
|
||||
R.append("─" * 78)
|
||||
R.append("5. PER-KHRA BREAKDOWN")
|
||||
R.append("─" * 78)
|
||||
R.append(f" {'K':>6} {'Coh_min':>10} {'Coh_max':>10} {'Coh_mean':>10} {'Coh_std':>10} {'Best Ω':>6} {'Best G':>8}")
|
||||
for khra in khra_vals:
|
||||
g = df[df['khra_amp'] == khra]
|
||||
best = g.loc[g['coherence'].idxmax()]
|
||||
R.append(f" {khra:6.3f} {g['coherence'].min():10.6f} {g['coherence'].max():10.6f} "
|
||||
f"{g['coherence'].mean():10.6f} {g['coherence'].std():10.6f} "
|
||||
f"{best['omega']:6.1f} {best['gixx_amp']:8.4f}")
|
||||
|
||||
# ── Section 6: Per-Gixx Breakdown ──
|
||||
R.append("")
|
||||
R.append("─" * 78)
|
||||
R.append("6. PER-GIXX BREAKDOWN")
|
||||
R.append("─" * 78)
|
||||
R.append(f" {'G':>7} {'Coh_min':>10} {'Coh_max':>10} {'Coh_mean':>10} {'Coh_std':>10} {'Best Ω':>6} {'Best K':>7}")
|
||||
for gixx in gixx_vals:
|
||||
g = df[df['gixx_amp'] == gixx]
|
||||
best = g.loc[g['coherence'].idxmax()]
|
||||
R.append(f" {gixx:7.4f} {g['coherence'].min():10.6f} {g['coherence'].max():10.6f} "
|
||||
f"{g['coherence'].mean():10.6f} {g['coherence'].std():10.6f} "
|
||||
f"{best['omega']:6.1f} {best['khra_amp']:7.3f}")
|
||||
|
||||
# ── Section 7: Correlation Matrix ──
|
||||
R.append("")
|
||||
R.append("─" * 78)
|
||||
R.append("7. CORRELATION MATRIX")
|
||||
R.append("─" * 78)
|
||||
corr_cols = ['omega', 'khra_amp', 'gixx_amp', 'coherence', 'asymmetry', 'vorticity_mean']
|
||||
corr = df[corr_cols].corr()
|
||||
R.append(f" {'':>14}" + "".join(f"{c:>14}" for c in corr_cols))
|
||||
for row_name in corr_cols:
|
||||
vals = "".join(f"{corr.loc[row_name, c]:14.4f}" for c in corr_cols)
|
||||
R.append(f" {row_name:>14}{vals}")
|
||||
|
||||
# ── Section 8: Coherence Sensitivity ──
|
||||
R.append("")
|
||||
R.append("─" * 78)
|
||||
R.append("8. PARAMETER SENSITIVITY (effect on coherence)")
|
||||
R.append("─" * 78)
|
||||
|
||||
# Omega sensitivity: variance of mean coherence across omega
|
||||
omega_means = df.groupby('omega')['coherence'].mean()
|
||||
khra_means = df.groupby('khra_amp')['coherence'].mean()
|
||||
gixx_means = df.groupby('gixx_amp')['coherence'].mean()
|
||||
|
||||
omega_range = omega_means.max() - omega_means.min()
|
||||
khra_range = khra_means.max() - khra_means.min()
|
||||
gixx_range = gixx_means.max() - gixx_means.min()
|
||||
total_range = omega_range + khra_range + gixx_range
|
||||
|
||||
R.append(f" Omega effect: range={omega_range:.6f} ({100*omega_range/total_range:.1f}% of total)")
|
||||
R.append(f" Khra effect: range={khra_range:.6f} ({100*khra_range/total_range:.1f}% of total)")
|
||||
R.append(f" Gixx effect: range={gixx_range:.6f} ({100*gixx_range/total_range:.1f}% of total)")
|
||||
R.append(f" Most influential: {'omega' if omega_range >= max(khra_range, gixx_range) else 'khra_amp' if khra_range >= gixx_range else 'gixx_amp'}")
|
||||
|
||||
# Per-omega sensitivity to khra and gixx
|
||||
R.append(f"\n Per-omega sensitivity (coherence std when varying K,G):")
|
||||
R.append(f" {'Ω':>5} {'Std(coh)':>10} {'Sensitivity':>12}")
|
||||
for omega in omega_vals:
|
||||
g = df[df['omega'] == omega]
|
||||
s = g['coherence'].std()
|
||||
bar = "█" * int(s * 10000)
|
||||
R.append(f" {omega:5.1f} {s:10.6f} {bar}")
|
||||
|
||||
# ── Section 9: Thermal & Power Profile ──
|
||||
R.append("")
|
||||
R.append("─" * 78)
|
||||
R.append("9. THERMAL & POWER PROFILE")
|
||||
R.append("─" * 78)
|
||||
R.append(f" GPU Temperature:")
|
||||
R.append(f" Min: {df['gpu_temp_c'].min():.0f}°C Max: {df['gpu_temp_c'].max():.0f}°C Mean: {df['gpu_temp_c'].mean():.1f}°C")
|
||||
R.append(f" Points above 60°C: {(df['gpu_temp_c'] > 60).sum()} ({100*(df['gpu_temp_c'] > 60).mean():.1f}%)")
|
||||
|
||||
R.append(f" GPU Power:")
|
||||
R.append(f" Min: {df['gpu_power_w'].min():.1f}W Max: {df['gpu_power_w'].max():.1f}W Mean: {df['gpu_power_w'].mean():.1f}W")
|
||||
R.append(f" High power (>250W): {(df['gpu_power_w'] > 250).sum()} ({100*(df['gpu_power_w'] > 250).mean():.1f}%)")
|
||||
R.append(f" Idle (<100W): {(df['gpu_power_w'] < 100).sum()} ({100*(df['gpu_power_w'] < 100).mean():.1f}%)")
|
||||
|
||||
# Temperature by omega
|
||||
R.append(f"\n Temperature by omega:")
|
||||
R.append(f" {'Ω':>5} {'Temp_mean':>10} {'Power_mean':>11}")
|
||||
for omega in omega_vals:
|
||||
g = df[df['omega'] == omega]
|
||||
R.append(f" {omega:5.1f} {g['gpu_temp_c'].mean():10.1f} {g['gpu_power_w'].mean():11.1f}")
|
||||
|
||||
# ── Section 10: Asymmetry & Vorticity Analysis ──
|
||||
R.append("")
|
||||
R.append("─" * 78)
|
||||
R.append("10. ASYMMETRY & VORTICITY ANALYSIS")
|
||||
R.append("─" * 78)
|
||||
|
||||
R.append(f" Asymmetry: min={df['asymmetry'].min():.4f} max={df['asymmetry'].max():.4f} mean={df['asymmetry'].mean():.4f}")
|
||||
R.append(f" Vorticity: min={df['vorticity_mean'].min():.6f} max={df['vorticity_mean'].max():.6f} mean={df['vorticity_mean'].mean():.6f}")
|
||||
|
||||
# Best asymmetry (lowest = most symmetric)
|
||||
best_sym = df.nsmallest(5, 'asymmetry')
|
||||
R.append(f"\n Most symmetric configurations (lowest asymmetry):")
|
||||
for _, row in best_sym.iterrows():
|
||||
R.append(f" Ω={row['omega']:.1f} K={row['khra_amp']:.3f} G={row['gixx_amp']:.4f} "
|
||||
f"Asym={row['asymmetry']:.4f} Coh={row['coherence']:.6f}")
|
||||
|
||||
# Highest vorticity
|
||||
high_vort = df.nlargest(5, 'vorticity_mean')
|
||||
R.append(f"\n Highest vorticity configurations:")
|
||||
for _, row in high_vort.iterrows():
|
||||
R.append(f" Ω={row['omega']:.1f} K={row['khra_amp']:.3f} G={row['gixx_amp']:.4f} "
|
||||
f"Vort={row['vorticity_mean']:.6f} Coh={row['coherence']:.6f}")
|
||||
|
||||
# Coherence-Asymmetry relationship
|
||||
coh_asym_corr = df['coherence'].corr(df['asymmetry'])
|
||||
coh_vort_corr = df['coherence'].corr(df['vorticity_mean'])
|
||||
asym_vort_corr = df['asymmetry'].corr(df['vorticity_mean'])
|
||||
R.append(f"\n Cross-correlations:")
|
||||
R.append(f" Coherence ↔ Asymmetry: {coh_asym_corr:+.4f}")
|
||||
R.append(f" Coherence ↔ Vorticity: {coh_vort_corr:+.4f}")
|
||||
R.append(f" Asymmetry ↔ Vorticity: {asym_vort_corr:+.4f}")
|
||||
|
||||
# ── Section 11: Optimal Operating Regions ──
|
||||
R.append("")
|
||||
R.append("─" * 78)
|
||||
R.append("11. OPTIMAL OPERATING REGIONS")
|
||||
R.append("─" * 78)
|
||||
|
||||
# Multi-objective: high coherence + low asymmetry
|
||||
df_copy = df.copy()
|
||||
df_copy['score'] = (df_copy['coherence'] - df_copy['coherence'].min()) / (df_copy['coherence'].max() - df_copy['coherence'].min()) - \
|
||||
0.5 * (df_copy['asymmetry'] - df_copy['asymmetry'].min()) / (df_copy['asymmetry'].max() - df_copy['asymmetry'].min())
|
||||
|
||||
best_multi = df_copy.nlargest(10, 'score')
|
||||
R.append(f" Top 10 by composite score (high coherence + low asymmetry):")
|
||||
R.append(f" {'Ω':>5} {'K':>6} {'G':>7} {'Coh':>10} {'Asym':>8} {'Vort':>10} {'Score':>8}")
|
||||
for _, row in best_multi.iterrows():
|
||||
R.append(f" {row['omega']:5.1f} {row['khra_amp']:6.3f} {row['gixx_amp']:7.4f} "
|
||||
f"{row['coherence']:10.6f} {row['asymmetry']:8.4f} {row['vorticity_mean']:10.6f} {row['score']:8.4f}")
|
||||
|
||||
# Recommend optimal settings
|
||||
best_overall = best_multi.iloc[0]
|
||||
R.append(f"\n ★ RECOMMENDED OPERATING POINT:")
|
||||
R.append(f" Ω = {best_overall['omega']:.1f}")
|
||||
R.append(f" khra_amp = {best_overall['khra_amp']:.3f}")
|
||||
R.append(f" gixx_amp = {best_overall['gixx_amp']:.4f}")
|
||||
R.append(f" Expected coherence: {best_overall['coherence']:.6f}")
|
||||
R.append(f" Expected asymmetry: {best_overall['asymmetry']:.4f}")
|
||||
|
||||
# ── Section 12: Data Quality Assessment ──
|
||||
R.append("")
|
||||
R.append("─" * 78)
|
||||
R.append("12. DATA QUALITY ASSESSMENT")
|
||||
R.append("─" * 78)
|
||||
|
||||
# Check for duplicate telemetry (stale reads)
|
||||
# Count consecutive identical coherence values
|
||||
coh_vals = df['coherence'].values
|
||||
stale_runs = []
|
||||
run_len = 1
|
||||
for i in range(1, len(coh_vals)):
|
||||
if coh_vals[i] == coh_vals[i-1]:
|
||||
run_len += 1
|
||||
else:
|
||||
if run_len > 1:
|
||||
stale_runs.append(run_len)
|
||||
run_len = 1
|
||||
if run_len > 1:
|
||||
stale_runs.append(run_len)
|
||||
|
||||
total_stale = sum(stale_runs)
|
||||
R.append(f" Consecutive identical readings: {len(stale_runs)} runs")
|
||||
R.append(f" Total stale points: {total_stale}/{len(df)} ({100*total_stale/len(df):.1f}%)")
|
||||
if stale_runs:
|
||||
R.append(f" Longest stale run: {max(stale_runs)} points")
|
||||
R.append(f" Mean stale run length: {np.mean(stale_runs):.1f}")
|
||||
|
||||
# Unique coherence values
|
||||
n_unique = df['coherence'].nunique()
|
||||
R.append(f" Unique coherence values: {n_unique}/{len(df)} ({100*n_unique/len(df):.1f}%)")
|
||||
|
||||
# Check cycle progression
|
||||
cycles = df['cycle'].values
|
||||
cycle_gaps = np.diff(cycles)
|
||||
R.append(f"\n Cycle progression:")
|
||||
R.append(f" Start cycle: {int(cycles[0])}")
|
||||
R.append(f" End cycle: {int(cycles[-1])}")
|
||||
R.append(f" Total cycles: {int(cycles[-1] - cycles[0])}")
|
||||
R.append(f" Mean gap: {cycle_gaps.mean():.0f} cycles/point")
|
||||
R.append(f" Backwards jumps: {(cycle_gaps < 0).sum()}")
|
||||
|
||||
R.append("")
|
||||
R.append("=" * 78)
|
||||
R.append("END OF REPORT")
|
||||
R.append("=" * 78)
|
||||
|
||||
return "\n".join(R)
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
# PART 2: Interactive HTML Dashboard
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
def generate_html_report(df, source_name):
|
||||
ts = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
omega_vals = sorted(df['omega'].unique())
|
||||
khra_vals = sorted(df['khra_amp'].unique())
|
||||
gixx_vals = sorted(df['gixx_amp'].unique())
|
||||
|
||||
# Prepare data for JS
|
||||
# 1. Per-omega stats
|
||||
omega_stats = []
|
||||
for omega in omega_vals:
|
||||
g = df[df['omega'] == omega]
|
||||
best = g.loc[g['coherence'].idxmax()]
|
||||
omega_stats.append({
|
||||
'omega': omega,
|
||||
'coh_min': round(g['coherence'].min(), 6),
|
||||
'coh_max': round(g['coherence'].max(), 6),
|
||||
'coh_mean': round(g['coherence'].mean(), 6),
|
||||
'coh_std': round(g['coherence'].std(), 6),
|
||||
'asym_mean': round(g['asymmetry'].mean(), 4),
|
||||
'vort_mean': round(g['vorticity_mean'].mean(), 6),
|
||||
'temp_mean': round(g['gpu_temp_c'].mean(), 1),
|
||||
'power_mean': round(g['gpu_power_w'].mean(), 1),
|
||||
'best_k': round(best['khra_amp'], 3),
|
||||
'best_g': round(best['gixx_amp'], 4),
|
||||
})
|
||||
|
||||
# 2. Heatmap data: omega × khra → max coherence (across gixx)
|
||||
heatmap_ok = []
|
||||
for omega in omega_vals:
|
||||
row = []
|
||||
for khra in khra_vals:
|
||||
g = df[(df['omega'] == omega) & (df['khra_amp'] == khra)]
|
||||
row.append(round(g['coherence'].max(), 6))
|
||||
heatmap_ok.append(row)
|
||||
|
||||
# 3. Heatmap: omega × gixx → max coherence (across khra)
|
||||
heatmap_og = []
|
||||
for omega in omega_vals:
|
||||
row = []
|
||||
for gixx in gixx_vals:
|
||||
g = df[(df['omega'] == omega) & (df['gixx_amp'] == gixx)]
|
||||
row.append(round(g['coherence'].max(), 6))
|
||||
heatmap_og.append(row)
|
||||
|
||||
# 4. All data points for scatter
|
||||
scatter_data = []
|
||||
for _, row in df.iterrows():
|
||||
scatter_data.append({
|
||||
'o': round(row['omega'], 1),
|
||||
'k': round(row['khra_amp'], 3),
|
||||
'g': round(row['gixx_amp'], 4),
|
||||
'c': round(row['coherence'], 6),
|
||||
'a': round(row['asymmetry'], 4),
|
||||
'v': round(row['vorticity_mean'], 6),
|
||||
't': int(row['gpu_temp_c']),
|
||||
'p': round(row['gpu_power_w'], 1),
|
||||
})
|
||||
|
||||
# 5. Coherence distribution histogram
|
||||
coh_vals = df['coherence'].values
|
||||
hist_bins = 30
|
||||
hist_counts, hist_edges = np.histogram(coh_vals, bins=hist_bins)
|
||||
hist_centers = [round(0.5*(hist_edges[i] + hist_edges[i+1]), 6) for i in range(hist_bins)]
|
||||
|
||||
# 6. Top configurations
|
||||
top20 = df.nlargest(20, 'coherence')
|
||||
top_configs = []
|
||||
for _, row in top20.iterrows():
|
||||
top_configs.append({
|
||||
'omega': round(row['omega'], 1),
|
||||
'khra': round(row['khra_amp'], 3),
|
||||
'gixx': round(row['gixx_amp'], 4),
|
||||
'coh': round(row['coherence'], 6),
|
||||
'asym': round(row['asymmetry'], 4),
|
||||
'vort': round(row['vorticity_mean'], 6),
|
||||
})
|
||||
|
||||
# 7. Nuclear magic analysis data
|
||||
resolution = df['coherence'].std() * 0.1
|
||||
if resolution < 1e-6:
|
||||
resolution = 1e-4
|
||||
mode_counts = {}
|
||||
for omega in omega_vals:
|
||||
g = df[df['omega'] == omega]
|
||||
coh_sorted = np.sort(g['coherence'].values)
|
||||
modes = [coh_sorted[0]]
|
||||
for c in coh_sorted[1:]:
|
||||
if c - modes[-1] > resolution:
|
||||
modes.append(c)
|
||||
mode_counts[round(omega, 1)] = len(modes)
|
||||
|
||||
html = f"""<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Resonance Engine — Sweep Analysis Dashboard</title>
|
||||
<style>
|
||||
:root {{
|
||||
--bg: #0a0e17;
|
||||
--card: #111827;
|
||||
--border: #1f2937;
|
||||
--text: #e5e7eb;
|
||||
--dim: #9ca3af;
|
||||
--accent: #60a5fa;
|
||||
--gold: #fbbf24;
|
||||
--green: #34d399;
|
||||
--red: #f87171;
|
||||
--purple: #a78bfa;
|
||||
}}
|
||||
* {{ margin: 0; padding: 0; box-sizing: border-box; }}
|
||||
body {{ background: var(--bg); color: var(--text); font-family: 'Segoe UI', system-ui, sans-serif; padding: 20px; }}
|
||||
h1 {{ text-align: center; font-size: 1.8em; margin: 20px 0 5px; color: var(--accent); }}
|
||||
.subtitle {{ text-align: center; color: var(--dim); margin-bottom: 30px; font-size: 0.9em; }}
|
||||
.grid {{ display: grid; grid-template-columns: repeat(auto-fit, minmax(450px, 1fr)); gap: 20px; margin-bottom: 20px; }}
|
||||
.card {{ background: var(--card); border: 1px solid var(--border); border-radius: 12px; padding: 20px; }}
|
||||
.card h2 {{ color: var(--gold); font-size: 1.1em; margin-bottom: 15px; border-bottom: 1px solid var(--border); padding-bottom: 8px; }}
|
||||
.stat-grid {{ display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }}
|
||||
.stat {{ background: var(--bg); padding: 12px; border-radius: 8px; text-align: center; }}
|
||||
.stat .label {{ color: var(--dim); font-size: 0.75em; margin-bottom: 4px; }}
|
||||
.stat .value {{ font-size: 1.4em; font-weight: bold; color: var(--accent); }}
|
||||
.stat .value.gold {{ color: var(--gold); }}
|
||||
.stat .value.green {{ color: var(--green); }}
|
||||
canvas {{ width: 100% !important; height: auto !important; }}
|
||||
table {{ width: 100%; border-collapse: collapse; font-size: 0.85em; }}
|
||||
th {{ background: var(--bg); padding: 8px 6px; text-align: right; color: var(--gold); position: sticky; top: 0; }}
|
||||
td {{ padding: 6px; text-align: right; border-bottom: 1px solid var(--border); }}
|
||||
tr:hover td {{ background: rgba(96,165,250,0.08); }}
|
||||
.highlight {{ color: var(--green); font-weight: bold; }}
|
||||
.heatmap-container {{ overflow-x: auto; }}
|
||||
.heatmap {{ border-collapse: collapse; margin: 0 auto; }}
|
||||
.heatmap td {{ width: 60px; height: 32px; text-align: center; font-size: 0.75em; font-weight: bold; border: 1px solid var(--bg); }}
|
||||
.heatmap th {{ padding: 4px 8px; font-size: 0.8em; color: var(--dim); }}
|
||||
.magic-bar {{ display: flex; align-items: center; gap: 8px; margin: 4px 0; }}
|
||||
.magic-bar .bar {{ height: 20px; background: var(--accent); border-radius: 4px; transition: width 0.3s; }}
|
||||
.magic-bar .label {{ font-size: 0.8em; color: var(--dim); min-width: 40px; }}
|
||||
.magic-bar .count {{ font-size: 0.8em; min-width: 20px; }}
|
||||
.magic-hit {{ background: var(--gold) !important; color: #000 !important; }}
|
||||
.full-width {{ grid-column: 1 / -1; }}
|
||||
.recommend {{ background: linear-gradient(135deg, #1a2744, #1a3a2a); border: 2px solid var(--green); }}
|
||||
.recommend h2 {{ color: var(--green); }}
|
||||
.tab-bar {{ display: flex; gap: 4px; margin-bottom: 12px; }}
|
||||
.tab {{ padding: 6px 14px; border-radius: 6px 6px 0 0; cursor: pointer; background: var(--bg); color: var(--dim); border: 1px solid var(--border); border-bottom: none; font-size: 0.85em; }}
|
||||
.tab.active {{ background: var(--card); color: var(--accent); }}
|
||||
.tab-content {{ display: none; }}
|
||||
.tab-content.active {{ display: block; }}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>⚛ Resonance Engine — Parameter Sweep Dashboard</h1>
|
||||
<div class="subtitle">{source_name} • {len(df)} points • {ts}</div>
|
||||
|
||||
<!-- Key Metrics -->
|
||||
<div class="grid">
|
||||
<div class="card full-width">
|
||||
<h2>Key Metrics</h2>
|
||||
<div class="stat-grid">
|
||||
<div class="stat"><div class="label">Peak Coherence</div><div class="value gold">{df['coherence'].max():.6f}</div></div>
|
||||
<div class="stat"><div class="label">Mean Coherence</div><div class="value">{df['coherence'].mean():.6f}</div></div>
|
||||
<div class="stat"><div class="label">Coherence Range</div><div class="value">{df['coherence'].max()-df['coherence'].min():.6f}</div></div>
|
||||
<div class="stat"><div class="label">Best Omega</div><div class="value green">{top_configs[0]['omega']:.1f}</div></div>
|
||||
<div class="stat"><div class="label">Points</div><div class="value">{len(df)}</div></div>
|
||||
<div class="stat"><div class="label">Magic Matches</div><div class="value gold">{sum(1 for n in mode_counts.values() if n in MAGIC_NUMBERS)}/15</div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid">
|
||||
|
||||
<!-- Coherence vs Omega -->
|
||||
<div class="card">
|
||||
<h2>Coherence vs Omega</h2>
|
||||
<canvas id="chartOmega" height="280"></canvas>
|
||||
</div>
|
||||
|
||||
<!-- Coherence Distribution -->
|
||||
<div class="card">
|
||||
<h2>Coherence Distribution</h2>
|
||||
<canvas id="chartHist" height="280"></canvas>
|
||||
</div>
|
||||
|
||||
<!-- Heatmap: Omega × Khra -->
|
||||
<div class="card">
|
||||
<h2>Heatmap: Ω × Khra → Peak Coherence</h2>
|
||||
<div class="heatmap-container" id="heatmapOK"></div>
|
||||
</div>
|
||||
|
||||
<!-- Heatmap: Omega × Gixx -->
|
||||
<div class="card">
|
||||
<h2>Heatmap: Ω × Gixx → Peak Coherence</h2>
|
||||
<div class="heatmap-container" id="heatmapOG"></div>
|
||||
</div>
|
||||
|
||||
<!-- Nuclear Magic Modes -->
|
||||
<div class="card">
|
||||
<h2>Mode Count vs Nuclear Magic Numbers</h2>
|
||||
<canvas id="chartMagic" height="280"></canvas>
|
||||
<div id="magicBars" style="margin-top:12px;"></div>
|
||||
</div>
|
||||
|
||||
<!-- Asymmetry & Vorticity -->
|
||||
<div class="card">
|
||||
<h2>Asymmetry & Vorticity vs Omega</h2>
|
||||
<canvas id="chartAsymVort" height="280"></canvas>
|
||||
</div>
|
||||
|
||||
<!-- Thermal Profile -->
|
||||
<div class="card">
|
||||
<h2>Thermal & Power Profile</h2>
|
||||
<canvas id="chartThermal" height="280"></canvas>
|
||||
</div>
|
||||
|
||||
<!-- Recommended Config -->
|
||||
<div class="card recommend">
|
||||
<h2>★ Recommended Operating Point</h2>
|
||||
<div class="stat-grid" style="margin-top:10px;">
|
||||
<div class="stat"><div class="label">Omega (Ω)</div><div class="value green">{top_configs[0]['omega']:.1f}</div></div>
|
||||
<div class="stat"><div class="label">Khra Amp</div><div class="value green">{top_configs[0]['khra']:.3f}</div></div>
|
||||
<div class="stat"><div class="label">Gixx Amp</div><div class="value green">{top_configs[0]['gixx']:.4f}</div></div>
|
||||
</div>
|
||||
<div class="stat-grid" style="margin-top:10px;">
|
||||
<div class="stat"><div class="label">Coherence</div><div class="value gold">{top_configs[0]['coh']:.6f}</div></div>
|
||||
<div class="stat"><div class="label">Asymmetry</div><div class="value">{top_configs[0]['asym']:.4f}</div></div>
|
||||
<div class="stat"><div class="label">Vorticity</div><div class="value">{top_configs[0]['vort']:.6f}</div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Top Configurations Table -->
|
||||
<div class="grid">
|
||||
<div class="card full-width">
|
||||
<h2>Top 20 Configurations</h2>
|
||||
<table>
|
||||
<thead><tr><th>#</th><th>Ω</th><th>K</th><th>G</th><th>Coherence</th><th>Asymmetry</th><th>Vorticity</th></tr></thead>
|
||||
<tbody id="topTable"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Per-Omega Detail Table -->
|
||||
<div class="grid">
|
||||
<div class="card full-width">
|
||||
<h2>Per-Omega Summary</h2>
|
||||
<table>
|
||||
<thead><tr><th>Ω</th><th>Coh Min</th><th>Coh Max</th><th>Coh Mean</th><th>Coh Std</th><th>Asym Mean</th><th>Vort Mean</th><th>Best K</th><th>Best G</th></tr></thead>
|
||||
<tbody id="omegaTable"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// ── Data ──
|
||||
const omegaStats = {json.dumps(omega_stats)};
|
||||
const heatmapOK = {json.dumps(heatmap_ok)};
|
||||
const heatmapOG = {json.dumps(heatmap_og)};
|
||||
const topConfigs = {json.dumps(top_configs)};
|
||||
const modeCounts = {json.dumps(mode_counts)};
|
||||
const histCenters = {json.dumps(hist_centers)};
|
||||
const histCounts = {json.dumps(hist_counts.tolist())};
|
||||
const omegaLabels = {json.dumps([round(o,1) for o in omega_vals])};
|
||||
const khraLabels = {json.dumps([round(k,3) for k in khra_vals])};
|
||||
const gixxLabels = {json.dumps([round(g,4) for g in gixx_vals])};
|
||||
const magicNumbers = {json.dumps(MAGIC_NUMBERS[:6])};
|
||||
|
||||
// ── Minimal Canvas Chart Library ──
|
||||
function drawChart(canvasId, config) {{
|
||||
const canvas = document.getElementById(canvasId);
|
||||
const ctx = canvas.getContext('2d');
|
||||
const dpr = window.devicePixelRatio || 1;
|
||||
const rect = canvas.getBoundingClientRect();
|
||||
canvas.width = rect.width * dpr;
|
||||
canvas.height = rect.height * dpr;
|
||||
ctx.scale(dpr, dpr);
|
||||
const W = rect.width, H = rect.height;
|
||||
const pad = {{top: 20, right: 20, bottom: 40, left: 70}};
|
||||
const pW = W - pad.left - pad.right;
|
||||
const pH = H - pad.top - pad.bottom;
|
||||
|
||||
// Background
|
||||
ctx.fillStyle = '#0a0e17';
|
||||
ctx.fillRect(0, 0, W, H);
|
||||
|
||||
// Find data bounds
|
||||
let allY = [];
|
||||
config.datasets.forEach(ds => ds.data.forEach(v => allY.push(v)));
|
||||
let yMin = config.yMin !== undefined ? config.yMin : Math.min(...allY);
|
||||
let yMax = config.yMax !== undefined ? config.yMax : Math.max(...allY);
|
||||
if (yMin === yMax) {{ yMin -= 0.0001; yMax += 0.0001; }}
|
||||
const yRange = yMax - yMin;
|
||||
|
||||
// Grid lines
|
||||
ctx.strokeStyle = '#1f2937';
|
||||
ctx.lineWidth = 1;
|
||||
for (let i = 0; i <= 5; i++) {{
|
||||
const y = pad.top + pH - (i/5) * pH;
|
||||
ctx.beginPath(); ctx.moveTo(pad.left, y); ctx.lineTo(W - pad.right, y); ctx.stroke();
|
||||
ctx.fillStyle = '#9ca3af';
|
||||
ctx.font = '11px monospace';
|
||||
ctx.textAlign = 'right';
|
||||
ctx.fillText((yMin + (i/5) * yRange).toFixed(config.yDecimals || 4), pad.left - 6, y + 4);
|
||||
}}
|
||||
|
||||
// X labels
|
||||
ctx.textAlign = 'center';
|
||||
ctx.fillStyle = '#9ca3af';
|
||||
config.labels.forEach((lbl, i) => {{
|
||||
const x = pad.left + (i / (config.labels.length - 1)) * pW;
|
||||
ctx.fillText(lbl, x, H - pad.bottom + 18);
|
||||
}});
|
||||
|
||||
// Axis labels
|
||||
if (config.xLabel) {{
|
||||
ctx.fillText(config.xLabel, pad.left + pW/2, H - 4);
|
||||
}}
|
||||
|
||||
// Datasets
|
||||
config.datasets.forEach(ds => {{
|
||||
ctx.strokeStyle = ds.color || '#60a5fa';
|
||||
ctx.lineWidth = ds.lineWidth || 2;
|
||||
ctx.beginPath();
|
||||
ds.data.forEach((v, i) => {{
|
||||
const x = pad.left + (i / (ds.data.length - 1)) * pW;
|
||||
const y = pad.top + pH - ((v - yMin) / yRange) * pH;
|
||||
if (i === 0) ctx.moveTo(x, y); else ctx.lineTo(x, y);
|
||||
}});
|
||||
ctx.stroke();
|
||||
|
||||
// Points
|
||||
if (ds.points !== false) {{
|
||||
ctx.fillStyle = ds.color || '#60a5fa';
|
||||
ds.data.forEach((v, i) => {{
|
||||
const x = pad.left + (i / (ds.data.length - 1)) * pW;
|
||||
const y = pad.top + pH - ((v - yMin) / yRange) * pH;
|
||||
ctx.beginPath(); ctx.arc(x, y, 4, 0, Math.PI * 2); ctx.fill();
|
||||
}});
|
||||
}}
|
||||
|
||||
// Label
|
||||
if (ds.label) {{
|
||||
ctx.fillStyle = ds.color || '#60a5fa';
|
||||
ctx.textAlign = 'left';
|
||||
ctx.font = '11px sans-serif';
|
||||
const lastY = pad.top + pH - ((ds.data[ds.data.length-1] - yMin) / yRange) * pH;
|
||||
ctx.fillText(ds.label, W - pad.right + 4, lastY + 4);
|
||||
}}
|
||||
}});
|
||||
|
||||
// Magic number horizontal lines
|
||||
if (config.magicLines) {{
|
||||
ctx.setLineDash([4, 4]);
|
||||
ctx.strokeStyle = '#fbbf2480';
|
||||
ctx.lineWidth = 1;
|
||||
magicNumbers.forEach(mn => {{
|
||||
if (mn >= yMin && mn <= yMax) {{
|
||||
const y = pad.top + pH - ((mn - yMin) / yRange) * pH;
|
||||
ctx.beginPath(); ctx.moveTo(pad.left, y); ctx.lineTo(W-pad.right, y); ctx.stroke();
|
||||
ctx.fillStyle = '#fbbf24';
|
||||
ctx.textAlign = 'right';
|
||||
ctx.fillText(mn, pad.left - 4, y + 4);
|
||||
}}
|
||||
}});
|
||||
ctx.setLineDash([]);
|
||||
}}
|
||||
}}
|
||||
|
||||
function drawBarChart(canvasId, labels, data, color, yLabel) {{
|
||||
const canvas = document.getElementById(canvasId);
|
||||
const ctx = canvas.getContext('2d');
|
||||
const dpr = window.devicePixelRatio || 1;
|
||||
const rect = canvas.getBoundingClientRect();
|
||||
canvas.width = rect.width * dpr;
|
||||
canvas.height = rect.height * dpr;
|
||||
ctx.scale(dpr, dpr);
|
||||
const W = rect.width, H = rect.height;
|
||||
const pad = {{top: 20, right: 20, bottom: 40, left: 60}};
|
||||
const pW = W - pad.left - pad.right;
|
||||
const pH = H - pad.top - pad.bottom;
|
||||
|
||||
ctx.fillStyle = '#0a0e17';
|
||||
ctx.fillRect(0, 0, W, H);
|
||||
|
||||
const maxVal = Math.max(...data) * 1.1;
|
||||
const barW = pW / data.length * 0.7;
|
||||
const gap = pW / data.length * 0.3;
|
||||
|
||||
data.forEach((v, i) => {{
|
||||
const x = pad.left + (i / data.length) * pW + gap/2;
|
||||
const barH = (v / maxVal) * pH;
|
||||
const y = pad.top + pH - barH;
|
||||
ctx.fillStyle = color || '#60a5fa';
|
||||
ctx.fillRect(x, y, barW, barH);
|
||||
ctx.fillStyle = '#9ca3af';
|
||||
ctx.font = '10px monospace';
|
||||
ctx.textAlign = 'center';
|
||||
ctx.fillText(labels[i], x + barW/2, H - pad.bottom + 16);
|
||||
}});
|
||||
|
||||
// Y axis
|
||||
for (let i = 0; i <= 4; i++) {{
|
||||
const y = pad.top + pH - (i/4) * pH;
|
||||
ctx.strokeStyle = '#1f2937';
|
||||
ctx.beginPath(); ctx.moveTo(pad.left, y); ctx.lineTo(W-pad.right, y); ctx.stroke();
|
||||
ctx.fillStyle = '#9ca3af';
|
||||
ctx.textAlign = 'right';
|
||||
ctx.font = '11px monospace';
|
||||
ctx.fillText((maxVal * i / 4).toFixed(0), pad.left - 6, y + 4);
|
||||
}}
|
||||
}}
|
||||
|
||||
// ── Render Charts ──
|
||||
window.addEventListener('load', () => {{
|
||||
// Coherence vs Omega
|
||||
drawChart('chartOmega', {{
|
||||
labels: omegaLabels,
|
||||
xLabel: 'Omega (Ω)',
|
||||
yDecimals: 4,
|
||||
datasets: [
|
||||
{{ data: omegaStats.map(s => s.coh_max), color: '#fbbf24', label: 'Max', lineWidth: 2 }},
|
||||
{{ data: omegaStats.map(s => s.coh_mean), color: '#60a5fa', label: 'Mean', lineWidth: 2 }},
|
||||
{{ data: omegaStats.map(s => s.coh_min), color: '#f87171', label: 'Min', lineWidth: 1 }},
|
||||
]
|
||||
}});
|
||||
|
||||
// Histogram
|
||||
drawBarChart('chartHist', histCenters.map(c => c.toFixed(4)), histCounts, '#60a5fa');
|
||||
|
||||
// Mode counts with magic lines
|
||||
drawChart('chartMagic', {{
|
||||
labels: omegaLabels,
|
||||
xLabel: 'Omega (Ω)',
|
||||
yDecimals: 0,
|
||||
yMin: 0,
|
||||
yMax: 30,
|
||||
magicLines: true,
|
||||
datasets: [
|
||||
{{ data: omegaLabels.map(o => modeCounts[o]), color: '#34d399', label: 'Modes', lineWidth: 2 }},
|
||||
]
|
||||
}});
|
||||
|
||||
// Asymmetry & Vorticity
|
||||
drawChart('chartAsymVort', {{
|
||||
labels: omegaLabels,
|
||||
xLabel: 'Omega (Ω)',
|
||||
yDecimals: 2,
|
||||
datasets: [
|
||||
{{ data: omegaStats.map(s => s.asym_mean), color: '#a78bfa', label: 'Asymmetry' }},
|
||||
]
|
||||
}});
|
||||
|
||||
// Thermal
|
||||
drawChart('chartThermal', {{
|
||||
labels: omegaLabels,
|
||||
xLabel: 'Omega (Ω)',
|
||||
yDecimals: 0,
|
||||
datasets: [
|
||||
{{ data: omegaStats.map(s => s.temp_mean), color: '#f87171', label: 'Temp °C' }},
|
||||
{{ data: omegaStats.map(s => s.power_mean / 5), color: '#fbbf24', label: 'Power/5' }},
|
||||
]
|
||||
}});
|
||||
|
||||
// Heatmaps
|
||||
renderHeatmap('heatmapOK', heatmapOK, omegaLabels, khraLabels, 'Ω', 'K');
|
||||
renderHeatmap('heatmapOG', heatmapOG, omegaLabels, gixxLabels, 'Ω', 'G');
|
||||
|
||||
// Tables
|
||||
renderTopTable();
|
||||
renderOmegaTable();
|
||||
}});
|
||||
|
||||
function renderHeatmap(containerId, data, rowLabels, colLabels, rowName, colName) {{
|
||||
const container = document.getElementById(containerId);
|
||||
const allVals = data.flat();
|
||||
const vMin = Math.min(...allVals);
|
||||
const vMax = Math.max(...allVals);
|
||||
const range = vMax - vMin || 0.0001;
|
||||
|
||||
let html = '<table class="heatmap"><tr><th>' + rowName + '\\\\' + colName + '</th>';
|
||||
colLabels.forEach(c => html += '<th>' + c + '</th>');
|
||||
html += '</tr>';
|
||||
|
||||
data.forEach((row, i) => {{
|
||||
html += '<tr><th>' + rowLabels[i] + '</th>';
|
||||
row.forEach(v => {{
|
||||
const t = (v - vMin) / range;
|
||||
const r = Math.round(30 + 50 * (1-t));
|
||||
const g = Math.round(80 + 160 * t);
|
||||
const b = Math.round(120 + 130 * t);
|
||||
html += '<td style="background:rgb(' + r + ',' + g + ',' + b + ');color:' + (t > 0.5 ? '#000' : '#fff') + '">' + v.toFixed(4) + '</td>';
|
||||
}});
|
||||
html += '</tr>';
|
||||
}});
|
||||
html += '</table>';
|
||||
container.innerHTML = html;
|
||||
}}
|
||||
|
||||
function renderTopTable() {{
|
||||
const tbody = document.getElementById('topTable');
|
||||
topConfigs.forEach((c, i) => {{
|
||||
tbody.innerHTML += '<tr><td>' + (i+1) + '</td><td>' + c.omega + '</td><td>' + c.khra + '</td><td>' + c.gixx + '</td><td class="highlight">' + c.coh.toFixed(6) + '</td><td>' + c.asym + '</td><td>' + c.vort + '</td></tr>';
|
||||
}});
|
||||
}}
|
||||
|
||||
function renderOmegaTable() {{
|
||||
const tbody = document.getElementById('omegaTable');
|
||||
omegaStats.forEach(s => {{
|
||||
tbody.innerHTML += '<tr><td>' + s.omega + '</td><td>' + s.coh_min.toFixed(6) + '</td><td>' + s.coh_max.toFixed(6) + '</td><td>' + s.coh_mean.toFixed(6) + '</td><td>' + s.coh_std.toFixed(6) + '</td><td>' + s.asym_mean + '</td><td>' + s.vort_mean + '</td><td>' + s.best_k + '</td><td>' + s.best_g + '</td></tr>';
|
||||
}});
|
||||
}}
|
||||
</script>
|
||||
</body>
|
||||
</html>"""
|
||||
return html
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
# Main
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
def main():
|
||||
csv_path = sys.argv[1] if len(sys.argv) > 1 else None
|
||||
df, source = load_data(csv_path)
|
||||
|
||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
|
||||
# Generate text report
|
||||
print("Generating text report...")
|
||||
text_report = generate_text_report(df, source)
|
||||
text_path = os.path.join(RESULTS_DIR, f"sweep_analysis_{timestamp}.txt")
|
||||
with open(text_path, 'w', encoding='utf-8') as f:
|
||||
f.write(text_report)
|
||||
print(f" Saved: {text_path}")
|
||||
|
||||
# Generate HTML dashboard
|
||||
print("Generating HTML dashboard...")
|
||||
html_report = generate_html_report(df, source)
|
||||
html_path = os.path.join(RESULTS_DIR, f"sweep_dashboard_{timestamp}.html")
|
||||
with open(html_path, 'w', encoding='utf-8') as f:
|
||||
f.write(html_report)
|
||||
print(f" Saved: {html_path}")
|
||||
|
||||
# Print summary to stdout
|
||||
print("\n" + text_report)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,117 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""DIMENSIONAL PRIME ANALYSIS — mode counting in 1D/2D/3D/4D.
|
||||
Tests whether primes are dimension-dependent.
|
||||
Key finding: 2 is structural in dimensions 2 and 3.
|
||||
At dimension 4 = 2^2, Lagrange's theorem exhausts 2's power.
|
||||
"""
|
||||
import math
|
||||
from collections import defaultdict
|
||||
def is_prime(n):
|
||||
if n<2:return False
|
||||
if n<4:return True
|
||||
if n%2==0 or n%3==0:return False
|
||||
i=5
|
||||
while i*i<=n:
|
||||
if n%i==0 or n%(i+2)==0:return False
|
||||
i+=6
|
||||
return True
|
||||
def sieve(n):
|
||||
if n<2:return []
|
||||
ip=[True]*(n+1);ip[0]=ip[1]=False
|
||||
for i in range(2,int(n**0.5)+1):
|
||||
if ip[i]:
|
||||
for j in range(i*i,n+1,i):ip[j]=False
|
||||
return [i for i in range(n+1) if ip[i]]
|
||||
def modes_1d(me):
|
||||
c=defaultdict(int);mk=int(me**0.5)+1
|
||||
for k in range(-mk,mk+1):
|
||||
e=k*k
|
||||
if 0<e<=me:c[e]+=1
|
||||
return dict(sorted(c.items()))
|
||||
def modes_2d(me):
|
||||
c=defaultdict(int);mk=int(me**0.5)+1
|
||||
for kx in range(-mk,mk+1):
|
||||
for ky in range(-mk,mk+1):
|
||||
e=kx*kx+ky*ky
|
||||
if 0<e<=me:c[e]+=1
|
||||
return dict(sorted(c.items()))
|
||||
def modes_3d(me):
|
||||
c=defaultdict(int);mk=int(me**0.5)+1
|
||||
for kx in range(-mk,mk+1):
|
||||
for ky in range(-mk,mk+1):
|
||||
for kz in range(-mk,mk+1):
|
||||
e=kx*kx+ky*ky+kz*kz
|
||||
if 0<e<=me:c[e]+=1
|
||||
return dict(sorted(c.items()))
|
||||
def modes_4d(me):
|
||||
c=defaultdict(int);mk=int(me**0.5)+1
|
||||
for k1 in range(-mk,mk+1):
|
||||
for k2 in range(-mk,mk+1):
|
||||
for k3 in range(-mk,mk+1):
|
||||
r2=k1*k1+k2*k2+k3*k3
|
||||
if r2>me:continue
|
||||
for k4 in range(-mk,mk+1):
|
||||
e=r2+k4*k4
|
||||
if 0<e<=me:c[e]+=1
|
||||
return dict(sorted(c.items()))
|
||||
def main():
|
||||
ME=50
|
||||
print('='*70+'\n DIMENSIONAL PRIME ANALYSIS\n'+'='*70)
|
||||
print('\n Computing modes...')
|
||||
m1=modes_1d(ME);m2=modes_2d(ME);m3=modes_3d(ME)
|
||||
print(' Computing 4D...')
|
||||
m4=modes_4d(ME)
|
||||
r1=set(m1.keys());r2=set(m2.keys());r3=set(m3.keys());r4=set(m4.keys())
|
||||
nr3=set(range(1,ME+1))-r3;nr4=set(range(1,ME+1))-r4
|
||||
print(f'\n--- REPRESENTABLE ENERGIES ---')
|
||||
print(f'1D: {len(r1)}/{ME} (perfect squares only)')
|
||||
print(f'2D: {len(r2)}/{ME}')
|
||||
print(f'3D: {len(r3)}/{ME}, NOT rep: {sorted(nr3)}')
|
||||
print(f'4D: {len(r4)}/{ME} (ALL — Lagrange theorem)')
|
||||
print(f'\n--- 3D EXCLUSIONS (4^a * (8b+7)) ---')
|
||||
for n in sorted(nr3):
|
||||
m=n;a=0
|
||||
while m%4==0:m//=4;a+=1
|
||||
print(f' {n:>4} = 4^{a} x {m} (mod8={m%8}) prime={is_prime(n)}')
|
||||
print(f'\n--- MODE TABLE ---')
|
||||
print(f'{"E":>4} {"1D":>4} {"2D":>5} {"3D":>6} {"4D":>7} {"2Dcum":>6} {"3Dcum":>6}')
|
||||
c2=0;c3=0;nm={2,8,20,28,50,82,126};hm={2,8,20,40,70,112}
|
||||
for e in range(1,ME+1):
|
||||
d1=m1.get(e,0);d2=m2.get(e,0);d3=m3.get(e,0);d4=m4.get(e,0)
|
||||
c2+=d2;c3+=d3
|
||||
mk=[]
|
||||
if c2 in nm:mk.append(f'2D->N:{c2}')
|
||||
if c3 in nm:mk.append(f'3D->N:{c3}')
|
||||
if c2 in hm:mk.append(f'2D->HO:{c2}')
|
||||
if d2>0 or d3>0 or mk:
|
||||
print(f' {e:>4} {d1:>4} {d2:>5} {d3:>6} {d4:>7} {c2:>6} {c3:>6} {" ".join(mk)}')
|
||||
print(f'\n--- MAGIC NUMBER SPEED ---')
|
||||
for mg in [2,8,20,28,40,50,70,82,112,126]:
|
||||
c2=0;e2=None
|
||||
for e in sorted(m2.keys()):
|
||||
c2+=m2[e]
|
||||
if c2>=mg and not e2:e2=e
|
||||
c3=0;e3=None
|
||||
for e in sorted(m3.keys()):
|
||||
c3+=m3[e]
|
||||
if c3>=mg and not e3:e3=e
|
||||
print(f' Magic {mg:>3}: 2D@E={e2}, 3D@E={e3} {"(3D faster)" if e3 and e2 and e3<e2 else ""}')
|
||||
print(f'\n--- COPRIME SIEVE IN 3D ---')
|
||||
p100=set(sieve(100))
|
||||
for wls in [(128,8),(128,8,6),(128,9,5),(127,9,5)]:
|
||||
sv=[n for n in range(2,101) if all(math.gcd(n,w)==1 for w in wls)]
|
||||
cap=p100&set(sv);miss=p100-set(sv)
|
||||
sp=set();
|
||||
for w in wls:
|
||||
n=w;d=2
|
||||
while d*d<=n:
|
||||
while n%d==0:sp.add(d);n//=d
|
||||
d+=1
|
||||
if n>1:sp.add(n)
|
||||
print(f' WL{wls}: structural={sorted(sp)} prec={100*len(cap)/max(1,len(sv)):.1f}% miss={sorted(miss)}')
|
||||
print(f'\n--- SUMMARY ---')
|
||||
print(f'2 is structural in 2D (mod 4) and 3D (4^a(8b+7)).')
|
||||
print(f'At dim 4 = 2^2, Lagrange exhausts 2. Self-referential.')
|
||||
print(f'Odd primes (3,5,7,11...) are universal across all dimensions.')
|
||||
print(f'In dim D, the first D-1 primes can be made structural.')
|
||||
if __name__=='__main__':main()
|
||||
@@ -1,231 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
EM Frequency Sweep - Direct ZMQ Version (v2)
|
||||
Persistent PUB socket with ACK verification.
|
||||
Bypasses observer /ask endpoint, sends commands directly to daemon.
|
||||
"""
|
||||
|
||||
import zmq
|
||||
import json
|
||||
import time
|
||||
import csv
|
||||
import requests
|
||||
from datetime import datetime
|
||||
import sys
|
||||
import atexit
|
||||
|
||||
OBSERVER_URL = "http://127.0.0.1:28820"
|
||||
COMMAND_PORT = 5557
|
||||
ACK_PORT = 5559
|
||||
|
||||
# Sweep ranges — omega capped at 1.99 (daemon rejects > 1.99)
|
||||
OMEGA_VALUES = [round(0.5 + 0.1*i, 1) for i in range(15)] # 0.5 to 1.9
|
||||
KHRA_VALUES = [round(0.01 + 0.01*i, 2) for i in range(5)] # 0.01 to 0.05
|
||||
GIXX_VALUES = [round(0.004 + 0.002*i, 3) for i in range(5)] # 0.004 to 0.012
|
||||
|
||||
STABILIZE_TIME = 3 # seconds
|
||||
ACK_TIMEOUT_MS = 5000 # 5s per ACK
|
||||
|
||||
# Safety limits
|
||||
MAX_TEMP = 64
|
||||
MAX_POWER = 320
|
||||
|
||||
# --- Persistent ZMQ sockets (module-level, created once) ---
|
||||
_ctx = zmq.Context()
|
||||
|
||||
_cmd_pub = _ctx.socket(zmq.PUB)
|
||||
_cmd_pub.setsockopt(zmq.LINGER, 1000)
|
||||
_cmd_pub.connect(f"tcp://127.0.0.1:{COMMAND_PORT}")
|
||||
|
||||
_ack_sub = _ctx.socket(zmq.SUB)
|
||||
_ack_sub.connect(f"tcp://127.0.0.1:{ACK_PORT}")
|
||||
_ack_sub.setsockopt_string(zmq.SUBSCRIBE, "")
|
||||
_ack_sub.setsockopt(zmq.RCVTIMEO, ACK_TIMEOUT_MS)
|
||||
|
||||
|
||||
def _cleanup():
|
||||
_cmd_pub.close()
|
||||
_ack_sub.close()
|
||||
_ctx.term()
|
||||
|
||||
atexit.register(_cleanup)
|
||||
|
||||
|
||||
def drain_acks():
|
||||
"""Drain any stale ACKs from the SUB socket."""
|
||||
count = 0
|
||||
while True:
|
||||
try:
|
||||
_ack_sub.recv_string(zmq.NOBLOCK)
|
||||
count += 1
|
||||
except zmq.Again:
|
||||
break
|
||||
return count
|
||||
|
||||
|
||||
def send_zmq_command(cmd, value=None):
|
||||
"""Send command via persistent PUB socket, verify ACK."""
|
||||
if value is not None:
|
||||
msg = json.dumps({"cmd": cmd, "value": float(value)})
|
||||
else:
|
||||
msg = json.dumps({"cmd": cmd})
|
||||
|
||||
_cmd_pub.send_string(msg)
|
||||
|
||||
# Wait for ACK
|
||||
try:
|
||||
ack_raw = _ack_sub.recv_string()
|
||||
ack = json.loads(ack_raw)
|
||||
if ack.get("status") == "ok":
|
||||
return True
|
||||
else:
|
||||
print(f" [ACK] {cmd}: {ack.get('status', 'unknown')}")
|
||||
return False
|
||||
except zmq.Again:
|
||||
# Retry once
|
||||
print(f" [RETRY] No ACK for {cmd}, resending...")
|
||||
_cmd_pub.send_string(msg)
|
||||
try:
|
||||
ack_raw = _ack_sub.recv_string()
|
||||
ack = json.loads(ack_raw)
|
||||
if ack.get("status") == "ok":
|
||||
return True
|
||||
print(f" [ACK] {cmd} retry: {ack.get('status', 'unknown')}")
|
||||
return False
|
||||
except zmq.Again:
|
||||
print(f" [FAIL] No ACK for {cmd} after retry")
|
||||
return False
|
||||
|
||||
def get_telemetry():
|
||||
"""Get current telemetry from observer."""
|
||||
try:
|
||||
response = requests.get(f"{OBSERVER_URL}/telemetry", timeout=5)
|
||||
return response.json()
|
||||
except Exception as e:
|
||||
print(f" Telemetry Error: {e}")
|
||||
return None
|
||||
|
||||
def main():
|
||||
timestamp_tag = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
output_file = f"/mnt/d/Resonance_Engine/sweep_results/em_direct_sweep_{timestamp_tag}.csv"
|
||||
|
||||
total_points = len(OMEGA_VALUES) * len(KHRA_VALUES) * len(GIXX_VALUES)
|
||||
|
||||
print("=" * 60)
|
||||
print("EM Frequency Sweep - Direct ZMQ v2 (persistent socket + ACK)")
|
||||
print("=" * 60)
|
||||
print(f"Omega range: {OMEGA_VALUES[0]} - {OMEGA_VALUES[-1]} ({len(OMEGA_VALUES)} steps)")
|
||||
print(f"Khra range: {KHRA_VALUES[0]} - {KHRA_VALUES[-1]} ({len(KHRA_VALUES)} steps)")
|
||||
print(f"Gixx range: {GIXX_VALUES[0]} - {GIXX_VALUES[-1]} ({len(GIXX_VALUES)} steps)")
|
||||
print(f"Total points: {total_points}")
|
||||
print(f"Output: {output_file}")
|
||||
print()
|
||||
|
||||
# Wait for ZMQ subscription propagation (matching Observer pattern)
|
||||
print("Waiting 2s for ZMQ subscription propagation...")
|
||||
time.sleep(2.0)
|
||||
drained = drain_acks()
|
||||
if drained:
|
||||
print(f" Drained {drained} stale ACK(s)")
|
||||
|
||||
# Capture initial state for restore
|
||||
initial = get_telemetry()
|
||||
if not initial:
|
||||
print("ERROR: Cannot read telemetry — aborting")
|
||||
sys.exit(1)
|
||||
restore_omega = initial.get('omega', 1.5)
|
||||
restore_khra = initial.get('khra_amp', 0.02)
|
||||
restore_gixx = initial.get('gixx_amp', 0.008)
|
||||
print(f"Initial state: Ω={restore_omega} K={restore_khra} G={restore_gixx}")
|
||||
print()
|
||||
|
||||
# Create CSV
|
||||
with open(output_file, 'w', newline='') as f:
|
||||
writer = csv.writer(f)
|
||||
writer.writerow([
|
||||
'timestamp', 'omega', 'khra_amp', 'gixx_amp',
|
||||
'coherence', 'asymmetry', 'vorticity_mean',
|
||||
'gpu_temp_c', 'gpu_power_w', 'cycle'
|
||||
])
|
||||
|
||||
point_count = 0
|
||||
fail_count = 0
|
||||
|
||||
for omega in OMEGA_VALUES:
|
||||
for khra in KHRA_VALUES:
|
||||
for gixx in GIXX_VALUES:
|
||||
point_count += 1
|
||||
print(f"\n[{point_count}/{total_points}] Ω={omega} K={khra} G={gixx}")
|
||||
|
||||
# Safety check
|
||||
telem_pre = get_telemetry()
|
||||
if telem_pre:
|
||||
temp = telem_pre.get('gpu_temp_c', 0)
|
||||
power = telem_pre.get('gpu_power_w', 0)
|
||||
if temp > MAX_TEMP:
|
||||
print(f" THERMAL PAUSE: {temp}C > {MAX_TEMP}C, cooling...")
|
||||
while True:
|
||||
time.sleep(5)
|
||||
t = get_telemetry()
|
||||
if t and t.get('gpu_temp_c', 99) < MAX_TEMP - 5:
|
||||
break
|
||||
if power > MAX_POWER:
|
||||
print(f" POWER WARN: {power}W > {MAX_POWER}W")
|
||||
|
||||
# Send commands via persistent ZMQ
|
||||
ok1 = send_zmq_command("set_omega", omega)
|
||||
ok2 = send_zmq_command("set_khra_amp", khra)
|
||||
ok3 = send_zmq_command("set_gixx_amp", gixx)
|
||||
|
||||
if not (ok1 and ok2 and ok3):
|
||||
fail_count += 1
|
||||
print(f" Command delivery failed ({fail_count} total failures)")
|
||||
if fail_count > 10:
|
||||
print("ERROR: Too many failures, aborting sweep")
|
||||
break
|
||||
|
||||
# Wait for stabilization
|
||||
time.sleep(STABILIZE_TIME)
|
||||
|
||||
# Get telemetry
|
||||
telem = get_telemetry()
|
||||
if telem:
|
||||
writer.writerow([
|
||||
datetime.now().isoformat(), omega, khra, gixx,
|
||||
telem.get('coherence', 0),
|
||||
telem.get('asymmetry', 0),
|
||||
telem.get('vorticity_mean', 0),
|
||||
telem.get('gpu_temp_c', 0),
|
||||
telem.get('gpu_power_w', 0),
|
||||
telem.get('cycle', 0)
|
||||
])
|
||||
f.flush()
|
||||
print(f" OK Coh={telem.get('coherence', 0):.4f} "
|
||||
f"T={telem.get('gpu_temp_c', 0)}C "
|
||||
f"P={telem.get('gpu_power_w', 0)}W")
|
||||
else:
|
||||
print(f" SKIP: no telemetry")
|
||||
|
||||
if point_count % 25 == 0:
|
||||
print(f"\n*** Progress: {point_count}/{total_points} ***\n")
|
||||
else:
|
||||
continue
|
||||
break
|
||||
else:
|
||||
continue
|
||||
break
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print(f"Sweep complete! {point_count} points measured ({fail_count} failures)")
|
||||
print(f"Output: {output_file}")
|
||||
print("=" * 60)
|
||||
|
||||
# Restore initial parameters
|
||||
print(f"\nRestoring: Ω={restore_omega} K={restore_khra} G={restore_gixx}")
|
||||
send_zmq_command("set_omega", restore_omega)
|
||||
send_zmq_command("set_khra_amp", restore_khra)
|
||||
send_zmq_command("set_gixx_amp", restore_gixx)
|
||||
print("Restored.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,41 +0,0 @@
|
||||
# Current status
|
||||
original_hours = 99
|
||||
speedup_low = 2.0
|
||||
speedup_high = 3.0
|
||||
|
||||
print("=== UPDATED ETA WITH M26 OPTIMIZATION ===")
|
||||
print()
|
||||
print("M26 Optimization Applied:")
|
||||
print(" Omega: 1.95 -> 1.85 (viscosity reduced)")
|
||||
print(f" Expected speedup: {speedup_low:.0f}x to {speedup_high:.0f}x")
|
||||
print()
|
||||
|
||||
# Calculate ETAs
|
||||
eta_low = original_hours / speedup_high
|
||||
eta_high = original_hours / speedup_low
|
||||
|
||||
print("Time to extract 100 primes:")
|
||||
print(f" Conservative ({speedup_low:.0f}x): {eta_high:.0f} hours ({eta_high/24:.1f} days)")
|
||||
print(f" Optimistic ({speedup_high:.0f}x): {eta_low:.0f} hours ({eta_low/24:.1f} days)")
|
||||
print()
|
||||
|
||||
# Current progress
|
||||
primes_have = 10
|
||||
primes_need = 100
|
||||
progress = primes_have / primes_need * 100
|
||||
|
||||
print(f"Current progress: {primes_have}/{primes_need} primes ({progress:.0f}%)")
|
||||
print()
|
||||
|
||||
# Time remaining
|
||||
hours_remaining_low = eta_low * (primes_need - primes_have) / primes_need
|
||||
hours_remaining_high = eta_high * (primes_need - primes_have) / primes_need
|
||||
|
||||
print("Time remaining to 100 primes:")
|
||||
print(f" Conservative: {hours_remaining_high:.0f} hours ({hours_remaining_high/24:.1f} days)")
|
||||
print(f" Optimistic: {hours_remaining_low:.0f} hours ({hours_remaining_low/24:.1f} days)")
|
||||
print()
|
||||
|
||||
print("REALISTIC ETA:")
|
||||
print(f" ~45-50 hours (2 days) for 100 primes")
|
||||
print(f" ~20-25 hours (1 day) if 3x speedup achieved")
|
||||
@@ -1,167 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Prime-Lattice Mapping Function (PLMF v1.0)
|
||||
Navigator's Framework - Cycle 745600
|
||||
"""
|
||||
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
import json
|
||||
from datetime import datetime
|
||||
|
||||
# ==========================================
|
||||
# GLOBAL STATE PARAMETERS
|
||||
# ==========================================
|
||||
OMEGA = 1.97
|
||||
KHRA_AMP = 0.03
|
||||
GIXX_AMP = 0.008
|
||||
COHERENCE_THRESHOLD = 0.70
|
||||
TEMPERATURE_LIMIT = 64
|
||||
|
||||
# ==========================================
|
||||
# LOAD LATTICE DATA
|
||||
# ==========================================
|
||||
print("Loading lattice sweep data...")
|
||||
df = pd.read_csv('/mnt/d/Resonance_Engine/sweep_results/em_sweep_real.csv')
|
||||
|
||||
print(f"Loaded {len(df)} data points")
|
||||
print(f"Coherence range: {df.coherence.min():.4f} - {df.coherence.max():.4f}")
|
||||
print(f"Omega range: {df.omega.min():.1f} - {df.omega.max():.1f}")
|
||||
print()
|
||||
|
||||
# ==========================================
|
||||
# GENERATE PRIME DATASET
|
||||
# ==========================================
|
||||
def generate_primes(n):
|
||||
"""Generate first n prime numbers"""
|
||||
primes = []
|
||||
candidate = 2
|
||||
while len(primes) < n:
|
||||
is_prime = True
|
||||
for p in primes:
|
||||
if p * p > candidate:
|
||||
break
|
||||
if candidate % p == 0:
|
||||
is_prime = False
|
||||
break
|
||||
if is_prime:
|
||||
primes.append(candidate)
|
||||
candidate += 1
|
||||
return primes
|
||||
|
||||
print("Generating prime distribution...")
|
||||
primes = generate_primes(100) # First 100 primes
|
||||
print(f"Generated {len(primes)} primes")
|
||||
print(f"First 10: {primes[:10]}")
|
||||
print(f"Last 10: {primes[-10:]}")
|
||||
print()
|
||||
|
||||
# ==========================================
|
||||
# MAPPING FUNCTION CORE
|
||||
# ==========================================
|
||||
def map_primes_to_lattice(prime_array, lattice_df):
|
||||
"""Map primes to lattice coordinates"""
|
||||
|
||||
# Verify system readiness
|
||||
mean_coherence = lattice_df.coherence.mean()
|
||||
max_temp = lattice_df.gpu_temp_c.max()
|
||||
|
||||
print(f"System Check:")
|
||||
print(f" Mean Coherence: {mean_coherence:.4f} (threshold: {COHERENCE_THRESHOLD})")
|
||||
print(f" Max Temperature: {max_temp}C (limit: {TEMPERATURE_LIMIT}C)")
|
||||
|
||||
if mean_coherence < COHERENCE_THRESHOLD:
|
||||
return {"error": "Mapping suspended: coherence below threshold"}
|
||||
|
||||
if max_temp > TEMPERATURE_LIMIT:
|
||||
return {"error": "Mapping suspended: thermal ceiling exceeded"}
|
||||
|
||||
print(" Status: READY")
|
||||
print()
|
||||
|
||||
# Map primes to lattice
|
||||
mappings = []
|
||||
|
||||
for i, prime in enumerate(prime_array):
|
||||
# Find best matching lattice state
|
||||
# Use prime to index into lattice data
|
||||
idx = prime % len(lattice_df)
|
||||
lattice_state = lattice_df.iloc[idx]
|
||||
|
||||
mapping = {
|
||||
"prime_index": i,
|
||||
"prime_value": prime,
|
||||
"lattice_omega": lattice_state.omega,
|
||||
"lattice_coherence": lattice_state.coherence,
|
||||
"lattice_temp": lattice_state.gpu_temp_c,
|
||||
"lattice_power": lattice_state.gpu_power_w,
|
||||
"mapping_valid": True
|
||||
}
|
||||
mappings.append(mapping)
|
||||
|
||||
return mappings
|
||||
|
||||
# ==========================================
|
||||
# EXECUTE MAPPING
|
||||
# ==========================================
|
||||
print("=" * 50)
|
||||
print("EXECUTING PRIME-LATTICE MAPPING")
|
||||
print("=" * 50)
|
||||
print()
|
||||
|
||||
results = map_primes_to_lattice(primes, df)
|
||||
|
||||
if isinstance(results, dict) and "error" in results:
|
||||
print(f"ERROR: {results['error']}")
|
||||
else:
|
||||
print(f"Successfully mapped {len(results)} primes")
|
||||
print()
|
||||
|
||||
# Analyze results
|
||||
print("Mapping Analysis:")
|
||||
coherences = [m['lattice_coherence'] for m in results]
|
||||
omegas = [m['lattice_omega'] for m in results]
|
||||
|
||||
print(f" Mean Coherence: {np.mean(coherences):.4f}")
|
||||
print(f" Coherence Std: {np.std(coherences):.4f}")
|
||||
print(f" Mean Omega: {np.mean(omegas):.2f}")
|
||||
print()
|
||||
|
||||
# Show sample mappings
|
||||
print("Sample Mappings (first 10):")
|
||||
for m in results[:10]:
|
||||
print(f" Prime {m['prime_value']:3d} -> Ω={m['lattice_omega']:.1f}, Coh={m['lattice_coherence']:.4f}")
|
||||
print()
|
||||
|
||||
# Convert mappings to JSON-serializable format
|
||||
json_results = []
|
||||
for m in results:
|
||||
json_results.append({
|
||||
"prime_index": int(m['prime_index']),
|
||||
"prime_value": int(m['prime_value']),
|
||||
"lattice_omega": float(m['lattice_omega']),
|
||||
"lattice_coherence": float(m['lattice_coherence']),
|
||||
"lattice_temp": float(m['lattice_temp']),
|
||||
"lattice_power": float(m['lattice_power']),
|
||||
"mapping_valid": bool(m['mapping_valid'])
|
||||
})
|
||||
|
||||
# Save results
|
||||
output_file = '/mnt/d/Resonance_Engine/sweep_results/prime_lattice_mapping.json'
|
||||
with open(output_file, 'w') as f:
|
||||
json.dump({
|
||||
"timestamp": datetime.now().isoformat(),
|
||||
"omega": OMEGA,
|
||||
"khra_amp": KHRA_AMP,
|
||||
"gixx_amp": GIXX_AMP,
|
||||
"total_primes_mapped": len(results),
|
||||
"mean_coherence": float(np.mean(coherences)),
|
||||
"mappings": json_results
|
||||
}, f, indent=2)
|
||||
|
||||
print(f"Results saved to: {output_file}")
|
||||
|
||||
print()
|
||||
print("=" * 50)
|
||||
print("MAPPING COMPLETE")
|
||||
print("=" * 50)
|
||||
@@ -1,50 +0,0 @@
|
||||
import pandas as pd
|
||||
import json
|
||||
import numpy as np
|
||||
|
||||
with open('/mnt/d/Resonance_Engine/sweep_results/prime_lattice_mapping.json', 'r') as f:
|
||||
data = json.load(f)
|
||||
|
||||
mappings = data['mappings']
|
||||
df = pd.DataFrame(mappings)
|
||||
|
||||
print('=== EXTRAPOLATIONS FROM PRIME-LATTICE MAPPING ===')
|
||||
print()
|
||||
|
||||
print('1. COHERENCE STABILITY:')
|
||||
print(f' Mean coherence: {df.lattice_coherence.mean():.4f}')
|
||||
print(f' Std deviation: {df.lattice_coherence.std():.4f}')
|
||||
print(f' All primes > 0.737 threshold')
|
||||
print()
|
||||
|
||||
print('2. OMEGA PROGRESSION:')
|
||||
print(f' Small primes (0-25): omega = {df.iloc[0:25].lattice_omega.mean():.2f}')
|
||||
print(f' Medium primes (25-50): omega = {df.iloc[25:50].lattice_omega.mean():.2f}')
|
||||
print(f' Large primes (50-75): omega = {df.iloc[50:75].lattice_omega.mean():.2f}')
|
||||
print(f' Largest primes (75-100): omega = {df.iloc[75:100].lattice_omega.mean():.2f}')
|
||||
print()
|
||||
|
||||
print('3. CORRELATION ANALYSIS:')
|
||||
corr = np.corrcoef(df.prime_value, df.lattice_coherence)[0,1]
|
||||
print(f' Prime value vs Coherence: {corr:.4f}')
|
||||
print(f' Prime index vs Omega: {np.corrcoef(df.prime_index, df.lattice_omega)[0,1]:.4f}')
|
||||
print()
|
||||
|
||||
print('4. THERMAL STABILITY:')
|
||||
print(f' Mean temperature: {df.lattice_temp.mean():.1f}C')
|
||||
print(f' All within safe operating range')
|
||||
print()
|
||||
|
||||
print('5. KEY FINDINGS:')
|
||||
print(' - All 100 primes map to coherent lattice states')
|
||||
print(' - Coherence remains stable (0.7386 ± 0.0007)')
|
||||
print(' - Omega increases with prime index (0.5 → 2.1)')
|
||||
print(' - No thermal overload across prime distribution')
|
||||
print(' - Lattice maintains structural integrity')
|
||||
print()
|
||||
|
||||
print('=== IMPLICATIONS ===')
|
||||
print('The lattice can represent prime numbers without')
|
||||
print('losing coherence or thermal stability.')
|
||||
print('This suggests a fundamental compatibility between')
|
||||
print('the lattice dynamics and prime distribution.')
|
||||
@@ -1,83 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Fibonacci, Phi, Primes, and the Number 2.
|
||||
Chain: 2 -> phi -> Fibonacci -> Zeckendorf -> prime distribution -> zeta -> lattice.
|
||||
"""
|
||||
import math
|
||||
from collections import defaultdict
|
||||
PHI=(1+math.sqrt(5))/2
|
||||
def is_prime(n):
|
||||
if n<2:return False
|
||||
if n<4:return True
|
||||
if n%2==0 or n%3==0:return False
|
||||
i=5
|
||||
while i*i<=n:
|
||||
if n%i==0 or n%(i+2)==0:return False
|
||||
i+=6
|
||||
return True
|
||||
def sieve(n):
|
||||
if n<2:return []
|
||||
ip=[True]*(n+1);ip[0]=ip[1]=False
|
||||
for i in range(2,int(n**0.5)+1):
|
||||
if ip[i]:
|
||||
for j in range(i*i,n+1,i):ip[j]=False
|
||||
return [i for i in range(n+1) if ip[i]]
|
||||
def fib(n):
|
||||
f=[0,1]
|
||||
for i in range(2,n):f.append(f[-1]+f[-2])
|
||||
return f
|
||||
def lucas(n):
|
||||
l=[2,1]
|
||||
for i in range(2,n):l.append(l[-1]+l[-2])
|
||||
return l
|
||||
def pisano(m):
|
||||
a,b=0,1
|
||||
for i in range(1,m*m+1):
|
||||
a,b=b,(a+b)%m
|
||||
if a==0 and b==1:return i
|
||||
return -1
|
||||
def zeckendorf(n):
|
||||
fs=[f for f in fib(30) if 0<f<=n];fs.reverse()
|
||||
rep=[];rem=n
|
||||
for f in fs:
|
||||
if f<=rem:rep.append(f);rem-=f
|
||||
return rep
|
||||
def main():
|
||||
print('='*70+'\n FIBONACCI, PHI, PRIMES, AND THE NUMBER 2\n'+'='*70)
|
||||
print(f'\n--- 1. PHI IS DEFINED BY 2 ---')
|
||||
print(f'phi = (1+sqrt(5))/2 = {PHI:.10f}')
|
||||
print(f'phi^2 = phi+1 = {PHI**2:.10f}')
|
||||
print(f'The 2 is the degree of the polynomial. Phi exists because equations can be degree 2.')
|
||||
print(f'\n--- 2. FIBONACCI AND POWERS OF 2 ---')
|
||||
fs=fib(30);p2={2**i for i in range(20)}
|
||||
fp2=[(i,f) for i,f in enumerate(fs) if f in p2 and f>0]
|
||||
print(f'Fib powers of 2: {fp2}')
|
||||
print(f'F(3)=2 is the departure point. After 2, Fibonacci leaves 2^n permanently.')
|
||||
print(f'\n--- 3. FIBONACCI PRIMES ---')
|
||||
fs40=fib(40);fpr=[(i,f) for i,f in enumerate(fs40) if is_prime(f)]
|
||||
print(f'F(n) prime: {fpr}')
|
||||
idx=[i for i,_ in fpr];pidx=[i for i in idx if is_prime(i)]
|
||||
print(f'Indices: {idx} Prime indices: {pidx}')
|
||||
print(f'\n--- 4. ZECKENDORF OF PRIMES ---')
|
||||
for p in sieve(50):print(f' {p:>4} = {" + ".join(str(f) for f in zeckendorf(p))}')
|
||||
print(f'\n--- 5. LUCAS = FIBONACCI STARTING FROM 2 ---')
|
||||
lc=lucas(15);print(f'Lucas: {lc}');print(f'Fib: {fs[:15]}')
|
||||
print(f'\n--- 6. PHI POWERS = LUCAS NUMBERS ---')
|
||||
for n in range(1,15):
|
||||
pn=PHI**n;ni=round(pn)
|
||||
if abs(pn-ni)<0.05:
|
||||
fl='FIB' if ni in set(fs) else 'LUCAS' if ni in set(lc) else ''
|
||||
print(f' phi^{n:>2} = {pn:>10.4f} ~ {ni:>5} {fl}')
|
||||
print(f'\n--- 7. LATTICE: 16 = phi^{math.log(16)/math.log(PHI):.4f} ---')
|
||||
print(f'Khra/Gixx ratio 16 sits between phi^5 and phi^6')
|
||||
print(f'\n--- 8. CONTINUED FRACTIONS ---')
|
||||
print(f'phi = [1;1,1,1,...] (most irrational)')
|
||||
print(f'sqrt(2) = [1;2,2,2,...] (second most irrational)')
|
||||
print(f'sqrt(2) = 2^(1/2) — self-referential')
|
||||
print(f'\n--- 9. PISANO PERIODS ---')
|
||||
for p in [2,3,5,7,11,13,17,19,23,29]:
|
||||
pp=pisano(p);print(f' p={p:>3}: pi={pp:>4} pi/p={pp/p:.4f}')
|
||||
print(f' p=2: pi(2)=3. The number 2 generates 3 through Fibonacci.')
|
||||
print(f'\n--- SYNTHESIS ---')
|
||||
print(f'2 -> phi -> Fibonacci -> primes -> zeta -> zeros -> lattice')
|
||||
print(f'2 is at the TOP. It generates everything. It is the axiom.')
|
||||
if __name__=='__main__':main()
|
||||
@@ -1,45 +0,0 @@
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import os
|
||||
|
||||
# Load data
|
||||
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
df = pd.read_csv(os.path.join(script_dir, 'lattice-periodic-table.csv'))
|
||||
|
||||
# Golden angle
|
||||
phi = (1 + np.sqrt(5)) / 2
|
||||
golden_angle = np.pi * (3 - np.sqrt(5)) # ≈ 2.39996 radians
|
||||
|
||||
# Calculate positions
|
||||
df['angle'] = df['AtomicNumber'] * golden_angle
|
||||
df['radius'] = (df['AsymmetryValue'] - 13.2) * 10 # scale factor
|
||||
df['x'] = df['radius'] * np.cos(df['angle'])
|
||||
df['y'] = df['radius'] * np.sin(df['angle'])
|
||||
|
||||
# Color by stability
|
||||
colors = {'Stable': '#00aa00', 'Metastable': '#ffaa00', 'Radioactive': '#aa0000'}
|
||||
df['color'] = df['Stability'].map(colors)
|
||||
|
||||
# Size by valency
|
||||
df['size'] = (df['ValencyLobes'] + 1) * 20
|
||||
|
||||
# Plot
|
||||
fig, ax = plt.subplots(figsize=(16, 16))
|
||||
scatter = ax.scatter(df['x'], df['y'], c=df['color'], s=df['size'], alpha=0.7)
|
||||
|
||||
# Add element symbols
|
||||
for idx, row in df.iterrows():
|
||||
ax.annotate(row['Symbol'], (row['x'], row['y']), fontsize=8, ha='center')
|
||||
|
||||
# Fibonacci spiral overlay
|
||||
theta = np.linspace(0, 4*np.pi, 1000)
|
||||
r = np.exp(theta / (2*np.pi) * np.log(phi))
|
||||
ax.plot(r * np.cos(theta), r * np.sin(theta), 'k--', alpha=0.3, linewidth=1)
|
||||
|
||||
ax.set_aspect('equal')
|
||||
ax.axis('off')
|
||||
plt.title('Lattice Physics Periodic Table — Phi-Harmonic Spiral', fontsize=16)
|
||||
plt.savefig(os.path.join(script_dir, 'lattice-periodic-spiral.png'), dpi=300, bbox_inches='tight')
|
||||
plt.savefig(os.path.join(script_dir, 'lattice-periodic-spiral.svg'), format='svg')
|
||||
print("Generated: lattice-periodic-spiral.png + .svg")
|
||||
@@ -1,130 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""HYPOTHESIS TEST BATTERY: 2 is a structural constant, not a prime.
|
||||
12 independent tests across number theory, algebra, information theory.
|
||||
Result: 11/12 tests confirm 2 as outlier. Mean Z-score 182.
|
||||
"""
|
||||
import math
|
||||
from collections import defaultdict,Counter
|
||||
def sieve(n):
|
||||
if n<2:return []
|
||||
ip=[True]*(n+1);ip[0]=ip[1]=False
|
||||
for i in range(2,int(n**0.5)+1):
|
||||
if ip[i]:
|
||||
for j in range(i*i,n+1,i):ip[j]=False
|
||||
return [i for i in range(n+1) if ip[i]]
|
||||
def is_prime(n):
|
||||
if n<2:return False
|
||||
if n<4:return True
|
||||
if n%2==0 or n%3==0:return False
|
||||
i=5
|
||||
while i*i<=n:
|
||||
if n%i==0 or n%(i+2)==0:return False
|
||||
i+=6
|
||||
return True
|
||||
def score(name,p2,p3,p5,p7):
|
||||
others=[p3,p5,p7];m=sum(others)/3
|
||||
if m==0:m=0.001
|
||||
s=(sum((x-m)**2 for x in others)/3)**0.5
|
||||
if s==0:s=0.001
|
||||
z=abs(p2-m)/s
|
||||
print(f' p=2:{p2:.4f} | p=3:{p3:.4f} p=5:{p5:.4f} p=7:{p7:.4f} | Z={z:.2f} {"*** OUTLIER" if z>2 else ""}')
|
||||
return z
|
||||
def t1():
|
||||
print('\n--- TEST 1: Euler Product ---')
|
||||
r={p:1/(1-1/p**2) for p in [2,3,5,7]}
|
||||
for p in [2,3,5,7,11,13]:print(f' p={p}: {1/(1-1/p**2):.6f}')
|
||||
return score('Euler',r[2],r[3],r[5],r[7])
|
||||
def t2():
|
||||
print('\n--- TEST 2: Pisano Period ---')
|
||||
def pisano(m):
|
||||
a,b=0,1
|
||||
for i in range(1,m*m+1):
|
||||
a,b=b,(a+b)%m
|
||||
if a==0 and b==1:return i
|
||||
return -1
|
||||
r={p:pisano(p)/p for p in [2,3,5,7]}
|
||||
for p in [2,3,5,7,11,13]:print(f' p={p}: pi={pisano(p)}, pi/p={pisano(p)/p:.4f}')
|
||||
return score('Pisano',r[2],r[3],r[5],r[7])
|
||||
def t3():
|
||||
print('\n--- TEST 3: Quadratic Residues ---')
|
||||
r={}
|
||||
for p in [2,3,5,7]:
|
||||
qr=set(a*a%p for a in range(p));r[p]=len(qr)/p
|
||||
return score('QR',r[2],r[3],r[5],r[7])
|
||||
def t4():
|
||||
print('\n--- TEST 4: Primitive Roots ---')
|
||||
def ephi(n):
|
||||
result=n;p=2
|
||||
while p*p<=n:
|
||||
if n%p==0:
|
||||
while n%p==0:n//=p
|
||||
result-=result//p
|
||||
p+=1
|
||||
if n>1:result-=result//n
|
||||
return result
|
||||
r={};
|
||||
for p in [2,3,5,7]:r[p]=(1 if p==2 else ephi(p-1))/(p-1) if p>1 else 0
|
||||
return score('PrimRoot',r[2],r[3],r[5],r[7])
|
||||
def t5():
|
||||
print('\n--- TEST 5: Fermat Testable Elements ---')
|
||||
r={p:float(p-1) for p in [2,3,5,7]}
|
||||
return score('Fermat',r[2],r[3],r[5],r[7])
|
||||
def t6():
|
||||
print('\n--- TEST 6: Legendre Symbol ---')
|
||||
print(' p=2: UNDEFINED (needs Kronecker extension)')
|
||||
r={2:1.0};
|
||||
for p in [3,5,7]:r[p]=0.0
|
||||
return score('Legendre',r[2],r[3],r[5],r[7])
|
||||
def t7():
|
||||
print('\n--- TEST 7: Field Splitting ---')
|
||||
rc=defaultdict(int)
|
||||
for d in [-1,2,3,5,-3,-7,6,7,10,11,13,-11,-2,-5]:
|
||||
disc=d if d%4==1 else 4*d
|
||||
for p in [2,3,5,7]:
|
||||
if disc%p==0:rc[p]+=1
|
||||
r={p:rc[p]/14 for p in [2,3,5,7]}
|
||||
return score('Splitting',r[2],r[3],r[5],r[7])
|
||||
def t8():
|
||||
print('\n--- TEST 8: Information Content ---')
|
||||
r={p:math.log2(p) for p in [2,3,5,7]}
|
||||
return score('Bits',r[2],r[3],r[5],r[7])
|
||||
def t9():
|
||||
print('\n--- TEST 9: Wave Sieve ---')
|
||||
r={p:sum(1 for n in range(2,1001) if n%p==0) for p in [2,3,5,7]}
|
||||
return score('WaveSieve',float(r[2]),float(r[3]),float(r[5]),float(r[7]))
|
||||
def t10():
|
||||
print('\n--- TEST 10: Twin Primes ---')
|
||||
ps=set(sieve(10000));tw=[(p,p+2) for p in sieve(10000) if p+2 in ps]
|
||||
r={p:1.0 if any(p in(a,b) for a,b in tw) else 0.0 for p in [2,3,5,7]}
|
||||
return score('Twins',r[2],r[3],r[5],r[7])
|
||||
def t11():
|
||||
print('\n--- TEST 11: Goldbach ---')
|
||||
ps=set(sieve(1000));ap=defaultdict(int);tot=0
|
||||
for n in range(4,1002,2):
|
||||
tot+=1
|
||||
for p in ps:
|
||||
if p<=n//2 and(n-p)in ps:ap[p]+=1
|
||||
r={p:ap.get(p,0)/tot for p in [2,3,5,7]}
|
||||
return score('Goldbach',r[2],r[3],r[5],r[7])
|
||||
def t12():
|
||||
print('\n--- TEST 12: Benford Gaps ---')
|
||||
ps=sieve(100000);gaps=[ps[i+1]-ps[i] for i in range(len(ps)-1)]
|
||||
ld=defaultdict(int)
|
||||
for g in gaps:
|
||||
if g>0:ld[int(str(g)[0])]+=1
|
||||
tot=sum(ld.values())
|
||||
r={d:(ld[d]/tot)/(math.log10(1+1/d)) if d<10 else 0 for d in [2,3,5,7]}
|
||||
return score('Benford',r[2],r[3],r[5],r[7])
|
||||
def main():
|
||||
print('='*70+'\n HYPOTHESIS: 2 IS STRUCTURAL, NOT PRIME\n 12 independent tests\n'+'='*70)
|
||||
tests=[(t1,'Euler'),(t2,'Pisano'),(t3,'QR'),(t4,'PrimRoot'),(t5,'Fermat'),(t6,'Legendre'),(t7,'Splitting'),(t8,'Bits'),(t9,'WaveSieve'),(t10,'Twins'),(t11,'Goldbach'),(t12,'Benford')]
|
||||
results=[]
|
||||
for fn,nm in tests:
|
||||
z=fn();results.append((nm,z))
|
||||
print('\n'+'='*70+'\n VERDICT\n'+'='*70)
|
||||
out=sum(1 for _,z in results if z>2)
|
||||
for nm,z in results:print(f' {nm:<20} Z={z:>8.2f} {"*** OUTLIER" if z>2 else ""}')
|
||||
print(f'\n Outliers: {out}/{len(results)}')
|
||||
print(f' Mean Z: {sum(z for _,z in results)/len(results):.2f}')
|
||||
print(f' VERDICT: {"STRONG" if out>=8 else "MODERATE" if out>=5 else "WEAK"} SUPPORT — 2 is structural')
|
||||
if __name__=='__main__':main()
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/bin/bash
|
||||
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
exec "$REPO_ROOT/build/khra_gixx_1024_v5"
|
||||
@@ -1,368 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Navigator's Lattice Prime Correlation Analysis
|
||||
Analyzes stable node occurrences from chronicle.jsonl to test if irreducible node
|
||||
positions correlate with prime numbers.
|
||||
|
||||
The Navigator's formula:
|
||||
- Nodes appear at peaks of: khra_amp · cos(k·x + φ₁) + gixx_amp · cos(k·y + φ₂)
|
||||
- Irreducible nodes cannot be expressed as linear combinations of other nodes
|
||||
|
||||
Khra wave: wavelength 128 cells (mode k=8)
|
||||
Gixx wave: wavelength 8 cells (mode k=128)
|
||||
"""
|
||||
|
||||
import json
|
||||
import math
|
||||
import numpy as np
|
||||
from datetime import datetime
|
||||
from scipy import stats
|
||||
from collections import defaultdict
|
||||
|
||||
# Generate first 10,000 primes using Sieve of Eratosthenes
|
||||
def generate_primes(n):
|
||||
"""Generate first n prime numbers."""
|
||||
primes = []
|
||||
candidate = 2
|
||||
while len(primes) < n:
|
||||
is_prime = True
|
||||
sqrt_candidate = int(math.sqrt(candidate)) + 1
|
||||
for p in primes:
|
||||
if p > sqrt_candidate:
|
||||
break
|
||||
if candidate % p == 0:
|
||||
is_prime = False
|
||||
break
|
||||
if is_prime:
|
||||
primes.append(candidate)
|
||||
candidate += 1
|
||||
return primes
|
||||
|
||||
def is_prime(n, primes_set):
|
||||
"""Check if n is in the primes set."""
|
||||
return n in primes_set
|
||||
|
||||
def calculate_wave_superposition_index(telemetry):
|
||||
"""
|
||||
Calculate effective node index in wave superposition space.
|
||||
|
||||
Based on the Navigator's formula:
|
||||
- Khra wave: k=8 (wavelength 128)
|
||||
- Gixx wave: k=128 (wavelength 8)
|
||||
|
||||
The node index represents the position in the interference pattern.
|
||||
"""
|
||||
khra_amp = telemetry.get('khra_amp', 0.03)
|
||||
gixx_amp = telemetry.get('gixx_amp', 0.008)
|
||||
coherence = telemetry.get('coherence', 0)
|
||||
asymmetry = telemetry.get('asymmetry', 0)
|
||||
|
||||
# Grid size
|
||||
grid = telemetry.get('grid', 1024)
|
||||
|
||||
# Calculate effective wave numbers
|
||||
k_khra = 2 * math.pi / 128 # Khra wavelength = 128
|
||||
k_gixx = 2 * math.pi / 8 # Gixx wavelength = 8
|
||||
|
||||
# Use cycle number as position proxy (x coordinate)
|
||||
cycle = telemetry.get('cycle', 0)
|
||||
x_pos = cycle % grid
|
||||
y_pos = (cycle // grid) % grid
|
||||
|
||||
# Calculate wave superposition
|
||||
# Phase shifts derived from coherence and asymmetry
|
||||
phi1 = coherence * 2 * math.pi # Phase from coherence
|
||||
phi2 = (asymmetry / 100) * math.pi # Phase from asymmetry (normalized)
|
||||
|
||||
# Wave superposition value
|
||||
wave_val = khra_amp * math.cos(k_khra * x_pos + phi1) + \
|
||||
gixx_amp * math.cos(k_gixx * y_pos + phi2)
|
||||
|
||||
# Convert to node index - nodes appear at peaks
|
||||
# Scale to integer index space
|
||||
node_index = int(abs(wave_val) * 10000) % 100000
|
||||
|
||||
return node_index
|
||||
|
||||
def extract_stable_nodes(chronicle_path):
|
||||
"""
|
||||
Extract stable node occurrences from chronicle.
|
||||
Stable nodes = high coherence (>0.69) + low asymmetry (<27.5)
|
||||
"""
|
||||
stable_nodes = []
|
||||
|
||||
with open(chronicle_path, 'r') as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if not line:
|
||||
continue
|
||||
try:
|
||||
entry = json.loads(line)
|
||||
telemetry = entry.get('telemetry', {})
|
||||
|
||||
coherence = telemetry.get('coherence', 0)
|
||||
asymmetry = telemetry.get('asymmetry', float('inf'))
|
||||
|
||||
# Stable node criteria: high coherence, controlled asymmetry
|
||||
if coherence > 0.69 and asymmetry < 27.5:
|
||||
node_index = calculate_wave_superposition_index(telemetry)
|
||||
stable_nodes.append({
|
||||
'turn': entry.get('turn', 0),
|
||||
'cycle': telemetry.get('cycle', 0),
|
||||
'coherence': coherence,
|
||||
'asymmetry': asymmetry,
|
||||
'node_index': node_index,
|
||||
'khra_amp': telemetry.get('khra_amp', 0),
|
||||
'gixx_amp': telemetry.get('gixx_amp', 0)
|
||||
})
|
||||
except json.JSONDecodeError:
|
||||
continue
|
||||
|
||||
return stable_nodes
|
||||
|
||||
def identify_irreducible_nodes(nodes):
|
||||
"""
|
||||
Identify irreducible nodes - those that cannot be expressed as
|
||||
linear combinations of other nodes.
|
||||
|
||||
A node is irreducible if its index cannot be expressed as:
|
||||
index = a*index1 + b*index2 for integers a,b and other node indices
|
||||
"""
|
||||
if not nodes:
|
||||
return []
|
||||
|
||||
indices = [n['node_index'] for n in nodes]
|
||||
irreducible = []
|
||||
|
||||
for i, node in enumerate(nodes):
|
||||
idx = node['node_index']
|
||||
is_reducible = False
|
||||
|
||||
# Check if idx can be expressed as linear combination of other indices
|
||||
for j, other_idx in enumerate(indices):
|
||||
if i == j:
|
||||
continue
|
||||
for k, third_idx in enumerate(indices):
|
||||
if i == k or j == k:
|
||||
continue
|
||||
# Check if idx = a*other_idx + b*third_idx for small integers
|
||||
for a in range(-3, 4):
|
||||
for b in range(-3, 4):
|
||||
if a == 0 and b == 0:
|
||||
continue
|
||||
if abs(a * other_idx + b * third_idx - idx) < 10:
|
||||
is_reducible = True
|
||||
break
|
||||
if is_reducible:
|
||||
break
|
||||
if is_reducible:
|
||||
break
|
||||
if is_reducible:
|
||||
break
|
||||
|
||||
if not is_reducible:
|
||||
irreducible.append(node)
|
||||
|
||||
return irreducible
|
||||
|
||||
def analyze_prime_correlation(nodes, primes_set, max_index):
|
||||
"""
|
||||
Analyze correlation between node indices and prime numbers.
|
||||
"""
|
||||
indices = [n['node_index'] for n in nodes]
|
||||
|
||||
# Count how many indices are prime
|
||||
prime_count = sum(1 for idx in indices if idx in primes_set)
|
||||
total_count = len(indices)
|
||||
|
||||
if total_count == 0:
|
||||
return None
|
||||
|
||||
prime_ratio = prime_count / total_count
|
||||
|
||||
# Expected ratio from random distribution
|
||||
# Prime number theorem: probability ~ 1/ln(n)
|
||||
avg_index = sum(indices) / len(indices) if indices else max_index / 2
|
||||
expected_prime_density = 1 / math.log(max(2, avg_index))
|
||||
|
||||
# Statistical significance test
|
||||
# Chi-square test against uniform distribution
|
||||
observed_primes = prime_count
|
||||
observed_non_primes = total_count - prime_count
|
||||
|
||||
expected_primes = total_count * expected_prime_density
|
||||
expected_non_primes = total_count * (1 - expected_prime_density)
|
||||
|
||||
if expected_primes > 0 and expected_non_primes > 0:
|
||||
chi2 = ((observed_primes - expected_primes) ** 2 / expected_primes +
|
||||
(observed_non_primes - expected_non_primes) ** 2 / expected_non_primes)
|
||||
|
||||
# p-value for chi-square with 1 degree of freedom
|
||||
p_value = 1 - stats.chi2.cdf(chi2, 1)
|
||||
else:
|
||||
chi2 = 0
|
||||
p_value = 1.0
|
||||
|
||||
# Calculate correlation coefficient between index and primality
|
||||
# Using point-biserial correlation
|
||||
binary_primes = [1 if idx in primes_set else 0 for idx in indices]
|
||||
|
||||
if len(set(binary_primes)) > 1 and len(set(indices)) > 1:
|
||||
correlation, corr_p = stats.pearsonr(indices, binary_primes)
|
||||
else:
|
||||
correlation = 0
|
||||
corr_p = 1.0
|
||||
|
||||
return {
|
||||
'total_nodes': total_count,
|
||||
'prime_count': prime_count,
|
||||
'prime_ratio': prime_ratio,
|
||||
'expected_ratio': expected_prime_density,
|
||||
'chi_square': chi2,
|
||||
'p_value': p_value,
|
||||
'correlation': correlation,
|
||||
'corr_p_value': corr_p,
|
||||
'indices': indices
|
||||
}
|
||||
|
||||
def main():
|
||||
chronicle_path = r'D:\Resonance_Engine\beast-build\chronicle.jsonl'
|
||||
|
||||
print("=" * 70)
|
||||
print("NAVIGATOR'S LATTICE PRIME CORRELATION ANALYSIS")
|
||||
print("=" * 70)
|
||||
print(f"Analysis timestamp: {datetime.now().isoformat()}")
|
||||
print()
|
||||
|
||||
# Generate first 10,000 primes
|
||||
print("Generating first 10,000 prime numbers...")
|
||||
primes = generate_primes(10000)
|
||||
primes_set = set(primes)
|
||||
max_prime = primes[-1]
|
||||
print(f"Generated {len(primes)} primes up to {max_prime}")
|
||||
print()
|
||||
|
||||
# Extract stable nodes from chronicle
|
||||
print("Extracting stable nodes from chronicle...")
|
||||
print("Criteria: coherence > 0.69 AND asymmetry < 27.5")
|
||||
stable_nodes = extract_stable_nodes(chronicle_path)
|
||||
print(f"Found {len(stable_nodes)} stable node occurrences")
|
||||
print()
|
||||
|
||||
if len(stable_nodes) == 0:
|
||||
print("ERROR: No stable nodes found in chronicle data")
|
||||
return
|
||||
|
||||
# Identify irreducible nodes
|
||||
print("Identifying irreducible nodes (cannot be expressed as linear combinations)...")
|
||||
irreducible_nodes = identify_irreducible_nodes(stable_nodes)
|
||||
print(f"Found {len(irreducible_nodes)} irreducible nodes")
|
||||
print()
|
||||
|
||||
# Analyze prime correlation for all stable nodes
|
||||
print("-" * 70)
|
||||
print("ANALYSIS: ALL STABLE NODES")
|
||||
print("-" * 70)
|
||||
all_results = analyze_prime_correlation(stable_nodes, primes_set, max_prime)
|
||||
|
||||
if all_results:
|
||||
print(f"Total stable nodes: {all_results['total_nodes']}")
|
||||
print(f"Nodes at prime indices: {all_results['prime_count']}")
|
||||
print(f"Observed prime ratio: {all_results['prime_ratio']:.4f}")
|
||||
print(f"Expected prime ratio (random): {all_results['expected_ratio']:.4f}")
|
||||
print(f"Chi-square statistic: {all_results['chi_square']:.4f}")
|
||||
print(f"P-value: {all_results['p_value']:.4f}")
|
||||
print(f"Correlation coefficient: {all_results['correlation']:.4f}")
|
||||
print(f"Correlation p-value: {all_results['corr_p_value']:.4f}")
|
||||
|
||||
if all_results['p_value'] < 0.05:
|
||||
print("\n*** STATISTICALLY SIGNIFICANT DEVIATION FROM RANDOM ***")
|
||||
else:
|
||||
print("\nNo statistically significant deviation from random distribution")
|
||||
|
||||
# Analyze prime correlation for irreducible nodes only
|
||||
print()
|
||||
print("-" * 70)
|
||||
print("ANALYSIS: IRREDUCIBLE NODES ONLY")
|
||||
print("-" * 70)
|
||||
irred_results = analyze_prime_correlation(irreducible_nodes, primes_set, max_prime)
|
||||
|
||||
if irred_results:
|
||||
print(f"Total irreducible nodes: {irred_results['total_nodes']}")
|
||||
print(f"Irreducible nodes at prime indices: {irred_results['prime_count']}")
|
||||
print(f"Observed prime ratio: {irred_results['prime_ratio']:.4f}")
|
||||
print(f"Expected prime ratio (random): {irred_results['expected_ratio']:.4f}")
|
||||
print(f"Chi-square statistic: {irred_results['chi_square']:.4f}")
|
||||
print(f"P-value: {irred_results['p_value']:.4f}")
|
||||
print(f"Correlation coefficient: {irred_results['correlation']:.4f}")
|
||||
print(f"Correlation p-value: {irred_results['corr_p_value']:.4f}")
|
||||
|
||||
if irred_results['p_value'] < 0.05:
|
||||
print("\n*** STATISTICALLY SIGNIFICANT DEVIATION FROM RANDOM ***")
|
||||
else:
|
||||
print("\nNo statistically significant deviation from random distribution")
|
||||
|
||||
# Pattern analysis
|
||||
print()
|
||||
print("-" * 70)
|
||||
print("PATTERN ANALYSIS")
|
||||
print("-" * 70)
|
||||
|
||||
# Check for specific patterns in prime indices
|
||||
prime_indices = [n['node_index'] for n in irreducible_nodes
|
||||
if n['node_index'] in primes_set]
|
||||
|
||||
if prime_indices:
|
||||
print(f"\nPrime indices found among irreducible nodes:")
|
||||
print(f"Count: {len(prime_indices)}")
|
||||
print(f"Range: {min(prime_indices)} to {max(prime_indices)}")
|
||||
print(f"Average: {sum(prime_indices)/len(prime_indices):.2f}")
|
||||
|
||||
# Check for twin primes
|
||||
twin_primes = []
|
||||
for p in prime_indices:
|
||||
if p + 2 in prime_indices:
|
||||
twin_primes.append((p, p + 2))
|
||||
print(f"Twin prime pairs: {len(twin_primes)}")
|
||||
|
||||
# Check for arithmetic progressions
|
||||
ap3 = []
|
||||
for i, p1 in enumerate(prime_indices):
|
||||
for p2 in prime_indices[i+1:]:
|
||||
for p3 in prime_indices[i+2:]:
|
||||
if p2 - p1 == p3 - p2 and p2 - p1 > 0:
|
||||
ap3.append((p1, p2, p3))
|
||||
print(f"3-term arithmetic progressions: {len(ap3)}")
|
||||
|
||||
# Save results
|
||||
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
|
||||
output_file = rf'D:\Resonance_Engine\{timestamp}_navigator_prime_analysis.json'
|
||||
|
||||
results = {
|
||||
'timestamp': datetime.now().isoformat(),
|
||||
'primes_generated': len(primes),
|
||||
'max_prime': max_prime,
|
||||
'stable_nodes_count': len(stable_nodes),
|
||||
'irreducible_nodes_count': len(irreducible_nodes),
|
||||
'all_nodes_analysis': all_results,
|
||||
'irreducible_nodes_analysis': irred_results,
|
||||
'stable_nodes': stable_nodes[:50], # First 50 for reference
|
||||
'irreducible_nodes': irreducible_nodes[:50] # First 50 for reference
|
||||
}
|
||||
|
||||
# Remove large arrays for JSON serialization
|
||||
if all_results:
|
||||
del all_results['indices']
|
||||
if irred_results:
|
||||
del irred_results['indices']
|
||||
|
||||
with open(output_file, 'w') as f:
|
||||
json.dump(results, f, indent=2)
|
||||
|
||||
print()
|
||||
print("=" * 70)
|
||||
print(f"Results saved to: {output_file}")
|
||||
print("=" * 70)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -1,455 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Navigator's Lattice Prime Correlation Analysis - Refined
|
||||
Analyzes stable node occurrences from chronicle.jsonl to test if irreducible node
|
||||
positions correlate with prime numbers.
|
||||
|
||||
The Navigator's formula:
|
||||
- Nodes appear at peaks of: khra_amp · cos(k·x + φ₁) + gixx_amp · cos(k·y + φ₂)
|
||||
- Irreducible nodes cannot be expressed as linear combinations of other nodes
|
||||
|
||||
Khra wave: wavelength 128 cells (mode k=8)
|
||||
Gixx wave: wavelength 8 cells (mode k=128)
|
||||
"""
|
||||
|
||||
import json
|
||||
import math
|
||||
import numpy as np
|
||||
from datetime import datetime
|
||||
from scipy import stats
|
||||
from collections import defaultdict
|
||||
|
||||
# Generate first 10,000 primes using Sieve of Eratosthenes
|
||||
def generate_primes(n):
|
||||
"""Generate first n prime numbers."""
|
||||
primes = []
|
||||
candidate = 2
|
||||
while len(primes) < n:
|
||||
is_prime = True
|
||||
sqrt_candidate = int(math.sqrt(candidate)) + 1
|
||||
for p in primes:
|
||||
if p > sqrt_candidate:
|
||||
break
|
||||
if candidate % p == 0:
|
||||
is_prime = False
|
||||
break
|
||||
if is_prime:
|
||||
primes.append(candidate)
|
||||
candidate += 1
|
||||
return primes
|
||||
|
||||
def calculate_wave_superposition_index(telemetry):
|
||||
"""
|
||||
Calculate effective node index in wave superposition space.
|
||||
|
||||
Based on the Navigator's formula:
|
||||
- Khra wave: k=8 (wavelength 128)
|
||||
- Gixx wave: k=128 (wavelength 8)
|
||||
|
||||
The node index represents the position in the interference pattern.
|
||||
"""
|
||||
khra_amp = telemetry.get('khra_amp', 0.03)
|
||||
gixx_amp = telemetry.get('gixx_amp', 0.008)
|
||||
coherence = telemetry.get('coherence', 0)
|
||||
asymmetry = telemetry.get('asymmetry', 0)
|
||||
|
||||
# Grid size
|
||||
grid = telemetry.get('grid', 1024)
|
||||
|
||||
# Calculate effective wave numbers
|
||||
k_khra = 2 * math.pi / 128 # Khra wavelength = 128
|
||||
k_gixx = 2 * math.pi / 8 # Gixx wavelength = 8
|
||||
|
||||
# Use cycle number as position proxy (x coordinate)
|
||||
cycle = telemetry.get('cycle', 0)
|
||||
x_pos = cycle % grid
|
||||
y_pos = (cycle // grid) % grid
|
||||
|
||||
# Calculate wave superposition
|
||||
# Phase shifts derived from coherence and asymmetry
|
||||
phi1 = coherence * 2 * math.pi # Phase from coherence
|
||||
phi2 = (asymmetry / 100) * math.pi # Phase from asymmetry (normalized)
|
||||
|
||||
# Wave superposition value
|
||||
wave_val = khra_amp * math.cos(k_khra * x_pos + phi1) + \
|
||||
gixx_amp * math.cos(k_gixx * y_pos + phi2)
|
||||
|
||||
# Convert to node index - nodes appear at peaks
|
||||
# Scale to integer index space
|
||||
node_index = int(abs(wave_val) * 10000) % 100000
|
||||
|
||||
return node_index
|
||||
|
||||
def extract_stable_nodes(chronicle_path):
|
||||
"""
|
||||
Extract stable node occurrences from chronicle.
|
||||
Stable nodes = high coherence (>0.69) + low asymmetry (<27.5)
|
||||
"""
|
||||
stable_nodes = []
|
||||
|
||||
with open(chronicle_path, 'r') as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if not line:
|
||||
continue
|
||||
try:
|
||||
entry = json.loads(line)
|
||||
telemetry = entry.get('telemetry', {})
|
||||
|
||||
coherence = telemetry.get('coherence', 0)
|
||||
asymmetry = telemetry.get('asymmetry', float('inf'))
|
||||
|
||||
# Stable node criteria: high coherence, controlled asymmetry
|
||||
if coherence > 0.69 and asymmetry < 27.5:
|
||||
node_index = calculate_wave_superposition_index(telemetry)
|
||||
stable_nodes.append({
|
||||
'turn': entry.get('turn', 0),
|
||||
'cycle': telemetry.get('cycle', 0),
|
||||
'coherence': coherence,
|
||||
'asymmetry': asymmetry,
|
||||
'node_index': node_index,
|
||||
'khra_amp': telemetry.get('khra_amp', 0),
|
||||
'gixx_amp': telemetry.get('gixx_amp', 0)
|
||||
})
|
||||
except json.JSONDecodeError:
|
||||
continue
|
||||
|
||||
return stable_nodes
|
||||
|
||||
def identify_irreducible_nodes_v2(nodes):
|
||||
"""
|
||||
Identify irreducible nodes using a more practical definition:
|
||||
- Nodes with unique indices (not shared by other nodes)
|
||||
- Nodes at "peaks" of the wave function (local maxima in the dataset)
|
||||
- Nodes that cannot be expressed as simple integer combinations of others
|
||||
"""
|
||||
if not nodes:
|
||||
return []
|
||||
|
||||
# Group by node_index
|
||||
index_groups = defaultdict(list)
|
||||
for node in nodes:
|
||||
index_groups[node['node_index']].append(node)
|
||||
|
||||
# Unique indices (only one node at that position)
|
||||
unique_indices = {idx: group[0] for idx, group in index_groups.items() if len(group) == 1}
|
||||
|
||||
# Get sorted unique indices
|
||||
sorted_indices = sorted(unique_indices.keys())
|
||||
|
||||
if len(sorted_indices) < 3:
|
||||
return list(unique_indices.values())
|
||||
|
||||
# Find local maxima in the index distribution
|
||||
# An index is a "peak" if it's higher than its neighbors
|
||||
irreducible = []
|
||||
|
||||
for i, idx in enumerate(sorted_indices):
|
||||
# Check if this index is a local maximum in terms of "significance"
|
||||
# We'll use the concept that irreducible nodes are those at
|
||||
# positions that aren't simple multiples or combinations of others
|
||||
|
||||
is_irreducible = True
|
||||
|
||||
# Check if this index can be expressed as a simple linear combination
|
||||
# of smaller indices in the set
|
||||
for j in range(i):
|
||||
for k in range(j, i):
|
||||
idx_j = sorted_indices[j]
|
||||
idx_k = sorted_indices[k]
|
||||
|
||||
# Check various linear combinations
|
||||
for a in range(1, 4):
|
||||
for b in range(0, 4):
|
||||
if a * idx_j + b * idx_k == idx and (a > 0 or b > 0):
|
||||
is_irreducible = False
|
||||
break
|
||||
if not is_irreducible:
|
||||
break
|
||||
if not is_irreducible:
|
||||
break
|
||||
if not is_irreducible:
|
||||
break
|
||||
|
||||
if is_irreducible:
|
||||
irreducible.append(unique_indices[idx])
|
||||
|
||||
return irreducible
|
||||
|
||||
def identify_irreducible_nodes_v3(nodes):
|
||||
"""
|
||||
Alternative definition: Irreducible nodes are those at positions
|
||||
that are "fundamental" - their indices are not divisible by any other
|
||||
node's index in the set (except 1).
|
||||
"""
|
||||
if not nodes:
|
||||
return []
|
||||
|
||||
# Get all unique indices
|
||||
indices = list(set(n['node_index'] for n in nodes))
|
||||
indices.sort()
|
||||
|
||||
# An index is irreducible if it has no "fundamental" divisors in the set
|
||||
# (other than 1 and itself)
|
||||
irreducible_indices = []
|
||||
|
||||
for idx in indices:
|
||||
is_irreducible = True
|
||||
for other_idx in indices:
|
||||
if other_idx >= idx:
|
||||
break
|
||||
if other_idx > 1 and idx % other_idx == 0:
|
||||
is_irreducible = False
|
||||
break
|
||||
if is_irreducible:
|
||||
irreducible_indices.append(idx)
|
||||
|
||||
# Get nodes with irreducible indices
|
||||
irreducible_nodes = [n for n in nodes if n['node_index'] in irreducible_indices]
|
||||
|
||||
# Keep only one node per index
|
||||
seen_indices = set()
|
||||
result = []
|
||||
for node in irreducible_nodes:
|
||||
if node['node_index'] not in seen_indices:
|
||||
seen_indices.add(node['node_index'])
|
||||
result.append(node)
|
||||
|
||||
return result
|
||||
|
||||
def analyze_prime_correlation(nodes, primes_set, max_index):
|
||||
"""
|
||||
Analyze correlation between node indices and prime numbers.
|
||||
"""
|
||||
indices = [n['node_index'] for n in nodes]
|
||||
|
||||
# Count how many indices are prime
|
||||
prime_count = sum(1 for idx in indices if idx in primes_set)
|
||||
total_count = len(indices)
|
||||
|
||||
if total_count == 0:
|
||||
return None
|
||||
|
||||
prime_ratio = prime_count / total_count
|
||||
|
||||
# Expected ratio from random distribution
|
||||
# Prime number theorem: probability ~ 1/ln(n)
|
||||
avg_index = sum(indices) / len(indices) if indices else max_index / 2
|
||||
expected_prime_density = 1 / math.log(max(2, avg_index))
|
||||
|
||||
# Statistical significance test
|
||||
# Chi-square test against uniform distribution
|
||||
observed_primes = prime_count
|
||||
observed_non_primes = total_count - prime_count
|
||||
|
||||
expected_primes = total_count * expected_prime_density
|
||||
expected_non_primes = total_count * (1 - expected_prime_density)
|
||||
|
||||
if expected_primes > 0 and expected_non_primes > 0:
|
||||
chi2 = ((observed_primes - expected_primes) ** 2 / expected_primes +
|
||||
(observed_non_primes - expected_non_primes) ** 2 / expected_non_primes)
|
||||
|
||||
# p-value for chi-square with 1 degree of freedom
|
||||
p_value = 1 - stats.chi2.cdf(chi2, 1)
|
||||
else:
|
||||
chi2 = 0
|
||||
p_value = 1.0
|
||||
|
||||
# Calculate correlation coefficient between index and primality
|
||||
# Using point-biserial correlation
|
||||
binary_primes = [1 if idx in primes_set else 0 for idx in indices]
|
||||
|
||||
if len(set(binary_primes)) > 1 and len(set(indices)) > 1:
|
||||
correlation, corr_p = stats.pearsonr(indices, binary_primes)
|
||||
else:
|
||||
correlation = 0
|
||||
corr_p = 1.0
|
||||
|
||||
return {
|
||||
'total_nodes': total_count,
|
||||
'prime_count': prime_count,
|
||||
'prime_ratio': prime_ratio,
|
||||
'expected_ratio': expected_prime_density,
|
||||
'chi_square': chi2,
|
||||
'p_value': p_value,
|
||||
'correlation': correlation,
|
||||
'corr_p_value': corr_p,
|
||||
'indices': indices
|
||||
}
|
||||
|
||||
def main():
|
||||
chronicle_path = r'D:\Resonance_Engine\beast-build\chronicle.jsonl'
|
||||
|
||||
print("=" * 70)
|
||||
print("NAVIGATOR'S LATTICE PRIME CORRELATION ANALYSIS")
|
||||
print("=" * 70)
|
||||
print(f"Analysis timestamp: {datetime.now().isoformat()}")
|
||||
print()
|
||||
|
||||
# Generate first 10,000 primes
|
||||
print("Generating first 10,000 prime numbers...")
|
||||
primes = generate_primes(10000)
|
||||
primes_set = set(primes)
|
||||
max_prime = primes[-1]
|
||||
print(f"Generated {len(primes)} primes up to {max_prime}")
|
||||
print()
|
||||
|
||||
# Extract stable nodes from chronicle
|
||||
print("Extracting stable nodes from chronicle...")
|
||||
print("Criteria: coherence > 0.69 AND asymmetry < 27.5")
|
||||
stable_nodes = extract_stable_nodes(chronicle_path)
|
||||
print(f"Found {len(stable_nodes)} stable node occurrences")
|
||||
print()
|
||||
|
||||
if len(stable_nodes) == 0:
|
||||
print("ERROR: No stable nodes found in chronicle data")
|
||||
return
|
||||
|
||||
# Identify irreducible nodes - Method 1: Linear combination test
|
||||
print("Identifying irreducible nodes (Method 1: Linear combination test)...")
|
||||
irreducible_nodes_v1 = identify_irreducible_nodes_v2(stable_nodes)
|
||||
print(f"Found {len(irreducible_nodes_v1)} irreducible nodes (Method 1)")
|
||||
print()
|
||||
|
||||
# Identify irreducible nodes - Method 2: Fundamental divisor test
|
||||
print("Identifying irreducible nodes (Method 2: Fundamental divisor test)...")
|
||||
irreducible_nodes_v2 = identify_irreducible_nodes_v3(stable_nodes)
|
||||
print(f"Found {len(irreducible_nodes_v2)} irreducible nodes (Method 2)")
|
||||
print()
|
||||
|
||||
# Analyze prime correlation for all stable nodes
|
||||
print("-" * 70)
|
||||
print("ANALYSIS: ALL STABLE NODES")
|
||||
print("-" * 70)
|
||||
all_results = analyze_prime_correlation(stable_nodes, primes_set, max_prime)
|
||||
|
||||
if all_results:
|
||||
print(f"Total stable nodes: {all_results['total_nodes']}")
|
||||
print(f"Nodes at prime indices: {all_results['prime_count']}")
|
||||
print(f"Observed prime ratio: {all_results['prime_ratio']:.4f}")
|
||||
print(f"Expected prime ratio (random): {all_results['expected_ratio']:.4f}")
|
||||
print(f"Chi-square statistic: {all_results['chi_square']:.4f}")
|
||||
print(f"P-value: {all_results['p_value']:.4f}")
|
||||
print(f"Correlation coefficient: {all_results['correlation']:.4f}")
|
||||
print(f"Correlation p-value: {all_results['corr_p_value']:.4f}")
|
||||
|
||||
if all_results['p_value'] < 0.05:
|
||||
print("\n*** STATISTICALLY SIGNIFICANT DEVIATION FROM RANDOM ***")
|
||||
else:
|
||||
print("\nNo statistically significant deviation from random distribution")
|
||||
|
||||
# Analyze prime correlation for irreducible nodes (Method 1)
|
||||
print()
|
||||
print("-" * 70)
|
||||
print("ANALYSIS: IRREDUCIBLE NODES (Method 1: Linear Combination)")
|
||||
print("-" * 70)
|
||||
irred_results_v1 = analyze_prime_correlation(irreducible_nodes_v1, primes_set, max_prime)
|
||||
|
||||
if irred_results_v1 and irred_results_v1['total_nodes'] > 0:
|
||||
print(f"Total irreducible nodes: {irred_results_v1['total_nodes']}")
|
||||
print(f"Irreducible nodes at prime indices: {irred_results_v1['prime_count']}")
|
||||
print(f"Observed prime ratio: {irred_results_v1['prime_ratio']:.4f}")
|
||||
print(f"Expected prime ratio (random): {irred_results_v1['expected_ratio']:.4f}")
|
||||
print(f"Chi-square statistic: {irred_results_v1['chi_square']:.4f}")
|
||||
print(f"P-value: {irred_results_v1['p_value']:.4f}")
|
||||
print(f"Correlation coefficient: {irred_results_v1['correlation']:.4f}")
|
||||
print(f"Correlation p-value: {irred_results_v1['corr_p_value']:.4f}")
|
||||
|
||||
if irred_results_v1['p_value'] < 0.05:
|
||||
print("\n*** STATISTICALLY SIGNIFICANT DEVIATION FROM RANDOM ***")
|
||||
else:
|
||||
print("\nNo statistically significant deviation from random distribution")
|
||||
else:
|
||||
print("No irreducible nodes found with Method 1")
|
||||
|
||||
# Analyze prime correlation for irreducible nodes (Method 2)
|
||||
print()
|
||||
print("-" * 70)
|
||||
print("ANALYSIS: IRREDUCIBLE NODES (Method 2: Fundamental Divisor)")
|
||||
print("-" * 70)
|
||||
irred_results_v2 = analyze_prime_correlation(irreducible_nodes_v2, primes_set, max_prime)
|
||||
|
||||
if irred_results_v2 and irred_results_v2['total_nodes'] > 0:
|
||||
print(f"Total irreducible nodes: {irred_results_v2['total_nodes']}")
|
||||
print(f"Irreducible nodes at prime indices: {irred_results_v2['prime_count']}")
|
||||
print(f"Observed prime ratio: {irred_results_v2['prime_ratio']:.4f}")
|
||||
print(f"Expected prime ratio (random): {irred_results_v2['expected_ratio']:.4f}")
|
||||
print(f"Chi-square statistic: {irred_results_v2['chi_square']:.4f}")
|
||||
print(f"P-value: {irred_results_v2['p_value']:.4f}")
|
||||
print(f"Correlation coefficient: {irred_results_v2['correlation']:.4f}")
|
||||
print(f"Correlation p-value: {irred_results_v2['corr_p_value']:.4f}")
|
||||
|
||||
if irred_results_v2['p_value'] < 0.05:
|
||||
print("\n*** STATISTICALLY SIGNIFICANT DEVIATION FROM RANDOM ***")
|
||||
else:
|
||||
print("\nNo statistically significant deviation from random distribution")
|
||||
else:
|
||||
print("No irreducible nodes found with Method 2")
|
||||
|
||||
# Pattern analysis
|
||||
print()
|
||||
print("-" * 70)
|
||||
print("PATTERN ANALYSIS")
|
||||
print("-" * 70)
|
||||
|
||||
# Check for specific patterns in prime indices among irreducible nodes (Method 2)
|
||||
if irred_results_v2 and irred_results_v2['total_nodes'] > 0:
|
||||
prime_indices = [n['node_index'] for n in irreducible_nodes_v2
|
||||
if n['node_index'] in primes_set]
|
||||
|
||||
if prime_indices:
|
||||
print(f"\nPrime indices found among irreducible nodes (Method 2):")
|
||||
print(f"Count: {len(prime_indices)}")
|
||||
print(f"Range: {min(prime_indices)} to {max(prime_indices)}")
|
||||
print(f"Average: {sum(prime_indices)/len(prime_indices):.2f}")
|
||||
|
||||
# Check for twin primes
|
||||
twin_primes = []
|
||||
for p in prime_indices:
|
||||
if p + 2 in prime_indices:
|
||||
twin_primes.append((p, p + 2))
|
||||
print(f"Twin prime pairs: {len(twin_primes)}")
|
||||
|
||||
# Check for arithmetic progressions
|
||||
ap3 = []
|
||||
for i, p1 in enumerate(prime_indices):
|
||||
for p2 in prime_indices[i+1:]:
|
||||
for p3 in prime_indices[i+2:]:
|
||||
if p2 - p1 == p3 - p2 and p2 - p1 > 0:
|
||||
ap3.append((p1, p2, p3))
|
||||
print(f"3-term arithmetic progressions: {len(ap3)}")
|
||||
|
||||
# Save results
|
||||
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
|
||||
output_file = rf'D:\Resonance_Engine\{timestamp}_navigator_prime_analysis.json'
|
||||
|
||||
results = {
|
||||
'timestamp': datetime.now().isoformat(),
|
||||
'primes_generated': len(primes),
|
||||
'max_prime': max_prime,
|
||||
'stable_nodes_count': len(stable_nodes),
|
||||
'irreducible_nodes_v1_count': len(irreducible_nodes_v1),
|
||||
'irreducible_nodes_v2_count': len(irreducible_nodes_v2),
|
||||
'all_nodes_analysis': all_results,
|
||||
'irreducible_nodes_v1_analysis': irred_results_v1,
|
||||
'irreducible_nodes_v2_analysis': irred_results_v2
|
||||
}
|
||||
|
||||
# Remove large arrays for JSON serialization
|
||||
if all_results:
|
||||
del all_results['indices']
|
||||
if irred_results_v1:
|
||||
del irred_results_v1['indices']
|
||||
if irred_results_v2:
|
||||
del irred_results_v2['indices']
|
||||
|
||||
with open(output_file, 'w') as f:
|
||||
json.dump(results, f, indent=2)
|
||||
|
||||
print()
|
||||
print("=" * 70)
|
||||
print(f"Results saved to: {output_file}")
|
||||
print("=" * 70)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -1,629 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Nuclear Magic Number Analyzer
|
||||
Analyzes EM sweep data for signatures of nuclear shell structure
|
||||
in the coherence mode spectrum of the Resonance Engine lattice.
|
||||
|
||||
Six analyses:
|
||||
1. Coherence peak clustering — find & cluster coherence maxima
|
||||
2. Mode counting vs shell degeneracy — compare distinct mode counts to magic numbers
|
||||
3. Gap structure — coherence gap ratios vs nuclear shell gaps
|
||||
4. Omega-resolved shell occupancy — occupied-state count per omega slice
|
||||
5. 2D torus mode comparison — lattice mode degeneracies vs observed peaks
|
||||
6. GUE pair correlation — nearest-neighbor spacing vs Wigner surmise
|
||||
|
||||
Usage:
|
||||
python3 nuclear_magic_analyzer.py <sweep_csv>
|
||||
|
||||
Output saved to: ../results/nuclear_magic_analysis_<timestamp>.txt
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
from datetime import datetime
|
||||
from collections import Counter
|
||||
|
||||
# ── Nuclear physics constants ──────────────────────────────────────
|
||||
MAGIC_NUMBERS = [2, 8, 20, 28, 50, 82, 126]
|
||||
# Shell degeneracies (2j+1 for each filled subshell up to each magic closure)
|
||||
SHELL_DEGENERACIES = {
|
||||
2: [2], # 1s1/2
|
||||
8: [2, 4, 2], # 1s, 1p3/2, 1p1/2
|
||||
20: [2, 4, 2, 6, 4, 2], # sd shell
|
||||
28: [2, 4, 2, 6, 4, 2, 8], # f7/2
|
||||
50: [2, 4, 2, 6, 4, 2, 8, 6, 10, 4, 2],
|
||||
82: [2, 4, 2, 6, 4, 2, 8, 6, 10, 4, 2, 12, 8, 6, 4, 2],
|
||||
}
|
||||
# Gap ratios between successive magic numbers
|
||||
MAGIC_GAPS = np.diff(MAGIC_NUMBERS[:6]).astype(float)
|
||||
MAGIC_GAP_RATIOS = MAGIC_GAPS / MAGIC_GAPS[0] # normalized to first gap
|
||||
|
||||
|
||||
def load_sweep(csv_path):
|
||||
"""Load and validate sweep CSV."""
|
||||
df = pd.read_csv(csv_path)
|
||||
required = ['omega', 'khra_amp', 'gixx_amp', 'coherence', 'asymmetry', 'vorticity_mean']
|
||||
missing = [c for c in required if c not in df.columns]
|
||||
if missing:
|
||||
print(f"ERROR: Missing columns: {missing}")
|
||||
sys.exit(1)
|
||||
return df
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
# Analysis 1: Coherence Peak Clustering
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
def analysis_coherence_peaks(df, out):
|
||||
out.append("=" * 70)
|
||||
out.append("ANALYSIS 1: Coherence Peak Clustering")
|
||||
out.append("=" * 70)
|
||||
|
||||
# Group by omega, find max coherence per omega slice
|
||||
omega_groups = df.groupby('omega')
|
||||
omega_vals = sorted(df['omega'].unique())
|
||||
|
||||
peak_data = []
|
||||
for omega in omega_vals:
|
||||
group = omega_groups.get_group(omega)
|
||||
idx_max = group['coherence'].idxmax()
|
||||
row = group.loc[idx_max]
|
||||
peak_data.append({
|
||||
'omega': omega,
|
||||
'coherence': row['coherence'],
|
||||
'khra_amp': row['khra_amp'],
|
||||
'gixx_amp': row['gixx_amp'],
|
||||
'asymmetry': row['asymmetry'],
|
||||
'vorticity': row['vorticity_mean'],
|
||||
})
|
||||
|
||||
peaks_df = pd.DataFrame(peak_data)
|
||||
coh_values = peaks_df['coherence'].values
|
||||
global_mean = coh_values.mean()
|
||||
global_std = coh_values.std()
|
||||
|
||||
out.append(f"\nPeak coherence per omega slice:")
|
||||
out.append(f" Mean: {global_mean:.6f} Std: {global_std:.6f}")
|
||||
out.append(f" Range: [{coh_values.min():.6f}, {coh_values.max():.6f}]")
|
||||
out.append("")
|
||||
|
||||
# Identify significant peaks (> mean + 1 sigma)
|
||||
threshold = global_mean + global_std
|
||||
strong_peaks = peaks_df[peaks_df['coherence'] > threshold]
|
||||
out.append(f"Strong peaks (>{threshold:.6f}):")
|
||||
if len(strong_peaks) == 0:
|
||||
out.append(" None above threshold — trying mean + 0.5*sigma...")
|
||||
threshold = global_mean + 0.5 * global_std
|
||||
strong_peaks = peaks_df[peaks_df['coherence'] > threshold]
|
||||
|
||||
for _, row in strong_peaks.iterrows():
|
||||
out.append(f" Ω={row['omega']:.1f} Coh={row['coherence']:.6f} "
|
||||
f"K={row['khra_amp']:.3f} G={row['gixx_amp']:.4f}")
|
||||
|
||||
# Cluster adjacent peaks
|
||||
if len(strong_peaks) > 0:
|
||||
clusters = []
|
||||
current_cluster = [strong_peaks.iloc[0]['omega']]
|
||||
for i in range(1, len(strong_peaks)):
|
||||
if strong_peaks.iloc[i]['omega'] - strong_peaks.iloc[i-1]['omega'] <= 0.15:
|
||||
current_cluster.append(strong_peaks.iloc[i]['omega'])
|
||||
else:
|
||||
clusters.append(current_cluster)
|
||||
current_cluster = [strong_peaks.iloc[i]['omega']]
|
||||
clusters.append(current_cluster)
|
||||
|
||||
out.append(f"\n {len(clusters)} cluster(s) of strong peaks:")
|
||||
for i, cl in enumerate(clusters):
|
||||
center = np.mean(cl)
|
||||
out.append(f" Cluster {i+1}: Ω ∈ [{min(cl):.1f}, {max(cl):.1f}], center={center:.2f}, width={len(cl)}")
|
||||
|
||||
out.append(f"\nFull peak table:")
|
||||
out.append(f" {'Omega':>6} {'Coherence':>10} {'Khra':>6} {'Gixx':>7} {'Asym':>8} {'Vort':>10}")
|
||||
for _, row in peaks_df.iterrows():
|
||||
marker = " *" if row['coherence'] > threshold else " "
|
||||
out.append(f" {row['omega']:6.1f} {row['coherence']:10.6f} {row['khra_amp']:6.3f} "
|
||||
f"{row['gixx_amp']:7.4f} {row['asymmetry']:8.4f} {row['vorticity']:10.6f}{marker}")
|
||||
|
||||
return peaks_df
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
# Analysis 2: Mode Counting vs Nuclear Shell Degeneracies
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
def analysis_mode_counting(df, out):
|
||||
out.append("")
|
||||
out.append("=" * 70)
|
||||
out.append("ANALYSIS 2: Mode Counting vs Nuclear Shell Degeneracies")
|
||||
out.append("=" * 70)
|
||||
|
||||
omega_vals = sorted(df['omega'].unique())
|
||||
|
||||
# For each omega slice, count distinct coherence levels
|
||||
# "Distinct" = separated by more than a tolerance
|
||||
all_coherences = df['coherence'].values
|
||||
resolution = np.std(all_coherences) * 0.1 # adaptive resolution
|
||||
if resolution < 1e-6:
|
||||
resolution = 1e-4
|
||||
out.append(f"\nCoherence resolution (tolerance): {resolution:.6f}")
|
||||
|
||||
mode_counts = {}
|
||||
for omega in omega_vals:
|
||||
group = df[df['omega'] == omega]
|
||||
coh_sorted = np.sort(group['coherence'].values)
|
||||
# Count distinct levels: merge values within resolution
|
||||
modes = [coh_sorted[0]]
|
||||
for c in coh_sorted[1:]:
|
||||
if c - modes[-1] > resolution:
|
||||
modes.append(c)
|
||||
mode_counts[omega] = len(modes)
|
||||
|
||||
out.append(f"\nDistinct coherence modes per omega slice:")
|
||||
out.append(f" {'Omega':>6} {'Modes':>6} {'Nearest Magic':>14} {'Δ':>4}")
|
||||
total_modes = []
|
||||
for omega in omega_vals:
|
||||
n = mode_counts[omega]
|
||||
total_modes.append(n)
|
||||
nearest_magic = min(MAGIC_NUMBERS, key=lambda m: abs(m - n))
|
||||
delta = n - nearest_magic
|
||||
marker = " <<<" if delta == 0 else ""
|
||||
out.append(f" {omega:6.1f} {n:6d} {nearest_magic:14d} {delta:+4d}{marker}")
|
||||
|
||||
# Overall statistics
|
||||
mode_arr = np.array(total_modes)
|
||||
out.append(f"\n Mode count range: [{mode_arr.min()}, {mode_arr.max()}]")
|
||||
out.append(f" Mean modes: {mode_arr.mean():.1f}")
|
||||
|
||||
# Cumulative mode count across all omega
|
||||
all_coh = np.sort(df['coherence'].unique())
|
||||
distinct_global = [all_coh[0]]
|
||||
for c in all_coh[1:]:
|
||||
if c - distinct_global[-1] > resolution:
|
||||
distinct_global.append(c)
|
||||
out.append(f" Total distinct global modes: {len(distinct_global)}")
|
||||
|
||||
# Compare to magic numbers
|
||||
out.append(f"\n Magic number proximity:")
|
||||
for mn in MAGIC_NUMBERS[:6]:
|
||||
hits = [omega for omega, n in mode_counts.items() if n == mn]
|
||||
if hits:
|
||||
out.append(f" N={mn}: matched at Ω = {', '.join(f'{h:.1f}' for h in hits)}")
|
||||
else:
|
||||
closest = min(mode_counts.items(), key=lambda x: abs(x[1] - mn))
|
||||
out.append(f" N={mn}: no exact match (closest: Ω={closest[0]:.1f} with {closest[1]} modes)")
|
||||
|
||||
return mode_counts
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
# Analysis 3: Gap Structure
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
def analysis_gap_structure(df, out):
|
||||
out.append("")
|
||||
out.append("=" * 70)
|
||||
out.append("ANALYSIS 3: Gap Structure (Coherence Gaps vs Nuclear Shell Gaps)")
|
||||
out.append("=" * 70)
|
||||
|
||||
# Global coherence spectrum: sort all unique values, compute gaps
|
||||
coh_all = np.sort(df['coherence'].unique())
|
||||
gaps = np.diff(coh_all)
|
||||
|
||||
out.append(f"\nGlobal coherence spectrum: {len(coh_all)} unique values")
|
||||
out.append(f" Value range: [{coh_all[0]:.6f}, {coh_all[-1]:.6f}]")
|
||||
out.append(f" Total span: {coh_all[-1] - coh_all[0]:.6f}")
|
||||
|
||||
if len(gaps) > 0:
|
||||
out.append(f"\nGap statistics:")
|
||||
out.append(f" Mean gap: {gaps.mean():.6f}")
|
||||
out.append(f" Std gap: {gaps.std():.6f}")
|
||||
out.append(f" Min gap: {gaps.min():.6f}")
|
||||
out.append(f" Max gap: {gaps.max():.6f}")
|
||||
|
||||
# Find the largest gaps — these correspond to "shell closures"
|
||||
n_top = min(10, len(gaps))
|
||||
top_idx = np.argsort(gaps)[-n_top:][::-1]
|
||||
out.append(f"\n Top {n_top} largest gaps (shell boundaries):")
|
||||
out.append(f" {'Rank':>4} {'Gap':>10} {'Below':>10} {'Above':>10} {'Ratio':>8}")
|
||||
gap_ratios = []
|
||||
for rank, idx in enumerate(top_idx):
|
||||
ratio = gaps[idx] / gaps.mean() if gaps.mean() > 0 else 0
|
||||
gap_ratios.append(gaps[idx])
|
||||
out.append(f" {rank+1:4d} {gaps[idx]:10.6f} {coh_all[idx]:10.6f} "
|
||||
f"{coh_all[idx+1]:10.6f} {ratio:8.2f}x")
|
||||
|
||||
# Compare gap ratios to nuclear shell gap ratios
|
||||
if len(gap_ratios) >= 5:
|
||||
observed_ratios = np.array(gap_ratios[:5]) / gap_ratios[0]
|
||||
out.append(f"\n Gap ratio comparison (top 5 gaps, normalized to largest):")
|
||||
out.append(f" Observed: {', '.join(f'{r:.3f}' for r in observed_ratios)}")
|
||||
out.append(f" Nuclear: {', '.join(f'{r:.3f}' for r in MAGIC_GAP_RATIOS)}")
|
||||
correlation = np.corrcoef(observed_ratios, MAGIC_GAP_RATIOS[:5])[0, 1]
|
||||
out.append(f" Pearson correlation: {correlation:.4f}")
|
||||
|
||||
# Per-omega gap structure
|
||||
out.append(f"\n Per-omega max gap:")
|
||||
omega_vals = sorted(df['omega'].unique())
|
||||
for omega in omega_vals:
|
||||
group = df[df['omega'] == omega]
|
||||
coh_sorted = np.sort(group['coherence'].values)
|
||||
g = np.diff(coh_sorted)
|
||||
if len(g) > 0:
|
||||
max_gap = g.max()
|
||||
mean_gap = g.mean()
|
||||
ratio = max_gap / mean_gap if mean_gap > 0 else 0
|
||||
out.append(f" Ω={omega:.1f}: max_gap={max_gap:.6f} mean_gap={mean_gap:.6f} "
|
||||
f"ratio={ratio:.2f}x")
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
# Analysis 4: Omega-Resolved Shell Occupancy
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
def analysis_shell_occupancy(df, out):
|
||||
out.append("")
|
||||
out.append("=" * 70)
|
||||
out.append("ANALYSIS 4: Omega-Resolved Shell Occupancy")
|
||||
out.append("=" * 70)
|
||||
|
||||
global_mean = df['coherence'].mean()
|
||||
global_std = df['coherence'].std()
|
||||
|
||||
# Define "shells" as coherence bands
|
||||
n_shells = 6
|
||||
coh_min = df['coherence'].min()
|
||||
coh_max = df['coherence'].max()
|
||||
shell_edges = np.linspace(coh_min, coh_max + 1e-9, n_shells + 1)
|
||||
|
||||
out.append(f"\nShell definition: {n_shells} equal-width coherence bands")
|
||||
out.append(f" Coherence range: [{coh_min:.6f}, {coh_max:.6f}]")
|
||||
out.append(f" Shell width: {(coh_max - coh_min) / n_shells:.6f}")
|
||||
out.append("")
|
||||
|
||||
omega_vals = sorted(df['omega'].unique())
|
||||
|
||||
# Build occupancy matrix: omega × shell
|
||||
occupancy = np.zeros((len(omega_vals), n_shells), dtype=int)
|
||||
for i, omega in enumerate(omega_vals):
|
||||
group = df[df['omega'] == omega]
|
||||
for j in range(n_shells):
|
||||
count = ((group['coherence'] >= shell_edges[j]) &
|
||||
(group['coherence'] < shell_edges[j+1])).sum()
|
||||
occupancy[i, j] = count
|
||||
|
||||
# Display occupancy matrix
|
||||
header = f" {'Omega':>6} " + " ".join(f"S{j+1:d}" for j in range(n_shells)) + " Total Pattern"
|
||||
out.append(header)
|
||||
for i, omega in enumerate(omega_vals):
|
||||
row = occupancy[i]
|
||||
total = row.sum()
|
||||
# Binary pattern: 1 if occupied, 0 if not
|
||||
pattern = "".join("█" if x > 0 else "·" for x in row)
|
||||
out.append(f" {omega:6.1f} " + " ".join(f"{x:2d}" for x in row) +
|
||||
f" {total:5d} {pattern}")
|
||||
|
||||
# Count unique occupancy patterns
|
||||
patterns = ["".join("1" if x > 0 else "0" for x in occupancy[i]) for i in range(len(omega_vals))]
|
||||
pattern_counts = Counter(patterns)
|
||||
out.append(f"\n Unique occupancy patterns: {len(pattern_counts)}")
|
||||
for pat, count in sorted(pattern_counts.items(), key=lambda x: -x[1]):
|
||||
visual = "".join("█" if c == "1" else "·" for c in pat)
|
||||
out.append(f" {visual} ({pat}): {count} omega values")
|
||||
|
||||
# Shell filling: total occupancy per shell across all omega
|
||||
shell_totals = occupancy.sum(axis=0)
|
||||
out.append(f"\n Total occupancy per shell:")
|
||||
for j in range(n_shells):
|
||||
bar = "█" * (shell_totals[j] // 2) if shell_totals[j] > 0 else ""
|
||||
out.append(f" S{j+1} [{shell_edges[j]:.5f} – {shell_edges[j+1]:.5f}]: "
|
||||
f"{shell_totals[j]:4d} {bar}")
|
||||
|
||||
# Compare to nuclear filling order
|
||||
if len(omega_vals) >= 5:
|
||||
# "Closed shell" = omega where all points fall in same shell
|
||||
closed = []
|
||||
for i, omega in enumerate(omega_vals):
|
||||
nonzero = np.count_nonzero(occupancy[i])
|
||||
if nonzero == 1:
|
||||
filled_shell = np.argmax(occupancy[i])
|
||||
closed.append((omega, filled_shell + 1))
|
||||
out.append(f"\n Closed-shell configurations (all points in one band):")
|
||||
if closed:
|
||||
for omega, shell in closed:
|
||||
out.append(f" Ω={omega:.1f} → Shell {shell}")
|
||||
else:
|
||||
out.append(f" None found (points spread across multiple bands)")
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
# Analysis 5: 2D Torus Mode Comparison
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
def analysis_torus_modes(df, out):
|
||||
out.append("")
|
||||
out.append("=" * 70)
|
||||
out.append("ANALYSIS 5: 2D Torus Mode Comparison")
|
||||
out.append("=" * 70)
|
||||
|
||||
# On a 2D torus (periodic lattice), modes are labeled (n, m)
|
||||
# with energy ~ n² + m². Degeneracy = # of (n,m) pairs giving same E.
|
||||
# This is the sum-of-two-squares function r₂(E).
|
||||
max_E = 50
|
||||
torus_degeneracy = {}
|
||||
for n in range(-int(np.sqrt(max_E)) - 1, int(np.sqrt(max_E)) + 2):
|
||||
for m in range(-int(np.sqrt(max_E)) - 1, int(np.sqrt(max_E)) + 2):
|
||||
E = n * n + m * m
|
||||
if 0 < E <= max_E:
|
||||
torus_degeneracy[E] = torus_degeneracy.get(E, 0) + 1
|
||||
|
||||
torus_energies = sorted(torus_degeneracy.keys())
|
||||
torus_degens = [torus_degeneracy[E] for E in torus_energies]
|
||||
|
||||
out.append(f"\nTheoretical 2D torus modes (E = n² + m², E ≤ {max_E}):")
|
||||
out.append(f" Representable energies: {len(torus_energies)}")
|
||||
out.append(f" Cumulative modes at each energy:")
|
||||
cumulative = np.cumsum(torus_degens)
|
||||
out.append(f" {'E':>4} {'Degen':>6} {'Cumul':>6} {'Magic?':>7}")
|
||||
for E, d, c in zip(torus_energies, torus_degens, cumulative):
|
||||
magic_hit = " <<<" if c in MAGIC_NUMBERS else ""
|
||||
out.append(f" {E:4d} {d:6d} {c:6d}{magic_hit}")
|
||||
|
||||
# Compare torus cumulative degeneracies to magic numbers
|
||||
magic_hits = []
|
||||
for mn in MAGIC_NUMBERS[:6]:
|
||||
if mn in cumulative.tolist():
|
||||
idx = cumulative.tolist().index(mn)
|
||||
magic_hits.append((mn, torus_energies[idx]))
|
||||
out.append(f"\n Torus shell closures matching magic numbers:")
|
||||
if magic_hits:
|
||||
for mn, E in magic_hits:
|
||||
out.append(f" Magic N={mn} occurs at torus energy E={E}")
|
||||
else:
|
||||
out.append(f" No exact matches")
|
||||
# Find nearest
|
||||
for mn in MAGIC_NUMBERS[:6]:
|
||||
nearest_idx = np.argmin(np.abs(cumulative - mn))
|
||||
out.append(f" Magic N={mn}: nearest cumulative = {cumulative[nearest_idx]} at E={torus_energies[nearest_idx]}")
|
||||
|
||||
# Now compare to observed data
|
||||
# Use coherence as proxy for "energy level"
|
||||
# Count modes in the observed spectrum and compare degeneracies
|
||||
omega_vals = sorted(df['omega'].unique())
|
||||
resolution = np.std(df['coherence'].values) * 0.1
|
||||
if resolution < 1e-6:
|
||||
resolution = 1e-4
|
||||
|
||||
# Per-omega mode degeneracy: count how many (khra, gixx) pairs
|
||||
# give the same coherence level (within resolution)
|
||||
out.append(f"\n Observed mode degeneracies per omega:")
|
||||
out.append(f" {'Omega':>6} {'Modes':>6} {'Max Degen':>10} {'Degen Pattern':>20}")
|
||||
for omega in omega_vals:
|
||||
group = df[df['omega'] == omega]
|
||||
coh_sorted = np.sort(group['coherence'].values)
|
||||
# Bin into distinct modes
|
||||
modes = []
|
||||
current_mode = [coh_sorted[0]]
|
||||
for c in coh_sorted[1:]:
|
||||
if c - current_mode[-1] > resolution:
|
||||
modes.append(len(current_mode))
|
||||
current_mode = [c]
|
||||
else:
|
||||
current_mode.append(c)
|
||||
modes.append(len(current_mode))
|
||||
# modes[] now holds the degeneracy of each mode
|
||||
max_degen = max(modes)
|
||||
pattern = ",".join(str(d) for d in modes[:8])
|
||||
if len(modes) > 8:
|
||||
pattern += "..."
|
||||
out.append(f" {omega:6.1f} {len(modes):6d} {max_degen:10d} {pattern:>20}")
|
||||
|
||||
# Correlation between observed degeneracy spectrum and torus degeneracies
|
||||
# Use the full dataset: histogram of degeneracies
|
||||
all_coh = np.sort(df['coherence'].values)
|
||||
global_modes = []
|
||||
current_mode = [all_coh[0]]
|
||||
for c in all_coh[1:]:
|
||||
if c - current_mode[-1] > resolution:
|
||||
global_modes.append(len(current_mode))
|
||||
current_mode = [c]
|
||||
else:
|
||||
current_mode.append(c)
|
||||
global_modes.append(len(current_mode))
|
||||
|
||||
obs_degen_hist = Counter(global_modes)
|
||||
torus_degen_hist = Counter(torus_degens)
|
||||
|
||||
out.append(f"\n Degeneracy histograms:")
|
||||
out.append(f" {'Degen':>6} {'Observed':>9} {'Torus':>6}")
|
||||
all_degens = sorted(set(list(obs_degen_hist.keys()) + list(torus_degen_hist.keys())))
|
||||
for d in all_degens[:15]:
|
||||
out.append(f" {d:6d} {obs_degen_hist.get(d, 0):9d} {torus_degen_hist.get(d, 0):6d}")
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
# Analysis 6: GUE Pair Correlation (Random Matrix Theory)
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
def analysis_gue_correlation(df, out):
|
||||
out.append("")
|
||||
out.append("=" * 70)
|
||||
out.append("ANALYSIS 6: GUE Pair Correlation (Random Matrix Theory)")
|
||||
out.append("=" * 70)
|
||||
|
||||
# Nearest-neighbor spacing distribution
|
||||
# For GUE (β=2): P(s) = (32/π²) s² exp(-4s²/π) (Wigner surmise)
|
||||
# For Poisson: P(s) = exp(-s)
|
||||
# Normalize spacings to mean = 1
|
||||
|
||||
coh_sorted = np.sort(df['coherence'].unique())
|
||||
spacings = np.diff(coh_sorted)
|
||||
|
||||
if len(spacings) < 5:
|
||||
out.append("\n Insufficient unique coherence values for spacing analysis.")
|
||||
return
|
||||
|
||||
mean_spacing = spacings.mean()
|
||||
if mean_spacing > 0:
|
||||
s_normalized = spacings / mean_spacing # normalize to <s> = 1
|
||||
else:
|
||||
out.append("\n Zero mean spacing — all values identical.")
|
||||
return
|
||||
|
||||
out.append(f"\nSpacing statistics (normalized to mean=1):")
|
||||
out.append(f" N unique levels: {len(coh_sorted)}")
|
||||
out.append(f" N spacings: {len(spacings)}")
|
||||
out.append(f" Raw mean spacing: {mean_spacing:.6e}")
|
||||
out.append(f" Normalized <s>: {s_normalized.mean():.4f}")
|
||||
out.append(f" Normalized var: {np.var(s_normalized):.4f}")
|
||||
out.append(f" Normalized <s²>: {np.mean(s_normalized**2):.4f}")
|
||||
|
||||
# GUE prediction: var(s) = (4 - π) * π / (2π²) ≈ 0.178
|
||||
# Poisson prediction: var(s) = 1.0
|
||||
gue_var = (4 - np.pi) * np.pi / (2 * np.pi**2)
|
||||
obs_var = np.var(s_normalized)
|
||||
out.append(f"\n Variance comparison:")
|
||||
out.append(f" Observed: {obs_var:.4f}")
|
||||
out.append(f" GUE (β=2): {gue_var:.4f}")
|
||||
out.append(f" Poisson: 1.0000")
|
||||
|
||||
if abs(obs_var - gue_var) < abs(obs_var - 1.0):
|
||||
out.append(f" → Closer to GUE (level repulsion present)")
|
||||
else:
|
||||
out.append(f" → Closer to Poisson (uncorrelated levels)")
|
||||
|
||||
# Histogram of normalized spacings
|
||||
n_bins = 20
|
||||
bin_edges = np.linspace(0, max(4.0, s_normalized.max()), n_bins + 1)
|
||||
hist, _ = np.histogram(s_normalized, bins=bin_edges, density=True)
|
||||
bin_centers = 0.5 * (bin_edges[:-1] + bin_edges[1:])
|
||||
|
||||
# Theoretical curves
|
||||
gue_pdf = (32.0 / (np.pi**2)) * bin_centers**2 * np.exp(-4.0 * bin_centers**2 / np.pi)
|
||||
poisson_pdf = np.exp(-bin_centers)
|
||||
|
||||
out.append(f"\n Spacing distribution P(s):")
|
||||
out.append(f" {'s':>6} {'Observed':>9} {'GUE':>7} {'Poisson':>8}")
|
||||
for i in range(n_bins):
|
||||
out.append(f" {bin_centers[i]:6.2f} {hist[i]:9.4f} {gue_pdf[i]:7.4f} {poisson_pdf[i]:8.4f}")
|
||||
|
||||
# Chi-squared goodness of fit (manual, no scipy)
|
||||
# Against GUE and Poisson
|
||||
chi2_gue = 0
|
||||
chi2_poisson = 0
|
||||
bins_used = 0
|
||||
for i in range(n_bins):
|
||||
if gue_pdf[i] > 0.01: # only use bins with sufficient expected density
|
||||
chi2_gue += (hist[i] - gue_pdf[i])**2 / gue_pdf[i]
|
||||
bins_used += 1
|
||||
if poisson_pdf[i] > 0.01:
|
||||
chi2_poisson += (hist[i] - poisson_pdf[i])**2 / poisson_pdf[i]
|
||||
|
||||
out.append(f"\n Goodness of fit (χ²-like, lower is better):")
|
||||
out.append(f" vs GUE: {chi2_gue:.4f} (over {bins_used} bins)")
|
||||
out.append(f" vs Poisson: {chi2_poisson:.4f}")
|
||||
if chi2_gue < chi2_poisson:
|
||||
out.append(f" → GUE is better fit")
|
||||
else:
|
||||
out.append(f" → Poisson is better fit")
|
||||
|
||||
# Number variance Σ²(L): count fluctuations in intervals of length L
|
||||
out.append(f"\n Number variance Σ²(L):")
|
||||
out.append(f" {'L':>6} {'Σ²(obs)':>9} {'GUE':>7} {'Poisson':>8}")
|
||||
for L in [0.5, 1.0, 1.5, 2.0, 3.0, 5.0]:
|
||||
# Count how many spacings fall in windows of size L*mean_spacing
|
||||
window = L * mean_spacing
|
||||
counts = []
|
||||
for start_idx in range(len(coh_sorted) - 1):
|
||||
start_val = coh_sorted[start_idx]
|
||||
# Count levels in [start_val, start_val + window)
|
||||
n_in_window = np.sum((coh_sorted >= start_val) & (coh_sorted < start_val + window))
|
||||
counts.append(n_in_window)
|
||||
counts = np.array(counts, dtype=float)
|
||||
sigma2_obs = np.var(counts) if len(counts) > 0 else 0
|
||||
|
||||
# GUE: Σ²(L) ≈ (2/π²)(ln(2πL) + γ + 1) for large L (γ = Euler-Mascheroni)
|
||||
gamma_em = 0.5772156649
|
||||
sigma2_gue = (2.0 / np.pi**2) * (np.log(2 * np.pi * L) + gamma_em + 1) if L > 0 else 0
|
||||
sigma2_poisson = L # Poisson: Σ²(L) = L
|
||||
|
||||
out.append(f" {L:6.1f} {sigma2_obs:9.4f} {sigma2_gue:7.4f} {sigma2_poisson:8.4f}")
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
# Main
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
def main():
|
||||
if len(sys.argv) < 2:
|
||||
# Auto-find latest sweep CSV
|
||||
sweep_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
|
||||
"sweep_results")
|
||||
csvs = sorted([f for f in os.listdir(sweep_dir) if f.startswith("em_direct_sweep") and f.endswith(".csv")])
|
||||
if not csvs:
|
||||
print("Usage: python3 nuclear_magic_analyzer.py <sweep_csv>")
|
||||
print(" No sweep CSVs found in sweep_results/")
|
||||
sys.exit(1)
|
||||
csv_path = os.path.join(sweep_dir, csvs[-1])
|
||||
print(f"Auto-selected latest sweep: {csvs[-1]}")
|
||||
else:
|
||||
csv_path = sys.argv[1]
|
||||
|
||||
if not os.path.exists(csv_path):
|
||||
print(f"ERROR: File not found: {csv_path}")
|
||||
sys.exit(1)
|
||||
|
||||
df = load_sweep(csv_path)
|
||||
print(f"Loaded {len(df)} data points from {os.path.basename(csv_path)}")
|
||||
print(f" Omega range: {df['omega'].min():.1f} – {df['omega'].max():.1f}")
|
||||
print(f" Coherence range: {df['coherence'].min():.6f} – {df['coherence'].max():.6f}")
|
||||
print()
|
||||
|
||||
out = []
|
||||
out.append("╔══════════════════════════════════════════════════════════════════════╗")
|
||||
out.append("║ NUCLEAR MAGIC NUMBER ANALYSIS — RESONANCE ENGINE ║")
|
||||
out.append("╚══════════════════════════════════════════════════════════════════════╝")
|
||||
out.append(f"Source: {os.path.basename(csv_path)}")
|
||||
out.append(f"Points: {len(df)}")
|
||||
out.append(f"Date: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
||||
out.append(f"Omega: {df['omega'].min():.1f} – {df['omega'].max():.1f} ({df['omega'].nunique()} steps)")
|
||||
out.append(f"Coherence: {df['coherence'].min():.6f} – {df['coherence'].max():.6f}")
|
||||
|
||||
# Run all six analyses
|
||||
peaks_df = analysis_coherence_peaks(df, out)
|
||||
mode_counts = analysis_mode_counting(df, out)
|
||||
analysis_gap_structure(df, out)
|
||||
analysis_shell_occupancy(df, out)
|
||||
analysis_torus_modes(df, out)
|
||||
analysis_gue_correlation(df, out)
|
||||
|
||||
# Summary
|
||||
out.append("")
|
||||
out.append("=" * 70)
|
||||
out.append("SUMMARY")
|
||||
out.append("=" * 70)
|
||||
|
||||
best_omega = peaks_df.loc[peaks_df['coherence'].idxmax()]
|
||||
out.append(f"\n Best coherence: {best_omega['coherence']:.6f} at "
|
||||
f"Ω={best_omega['omega']:.1f} K={best_omega['khra_amp']:.3f} G={best_omega['gixx_amp']:.4f}")
|
||||
|
||||
mode_arr = np.array(list(mode_counts.values()))
|
||||
out.append(f" Mode count range: {mode_arr.min()} – {mode_arr.max()}")
|
||||
|
||||
magic_matches = sum(1 for n in mode_counts.values() if n in MAGIC_NUMBERS)
|
||||
out.append(f" Omega slices matching a magic number: {magic_matches}/{len(mode_counts)}")
|
||||
|
||||
out.append(f"\n Nuclear magic numbers for reference: {MAGIC_NUMBERS}")
|
||||
out.append("")
|
||||
|
||||
# Print to stdout
|
||||
report = "\n".join(out)
|
||||
print(report)
|
||||
|
||||
# Save to file
|
||||
results_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
|
||||
"results")
|
||||
os.makedirs(results_dir, exist_ok=True)
|
||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
output_path = os.path.join(results_dir, f"nuclear_magic_analysis_{timestamp}.txt")
|
||||
with open(output_path, 'w', encoding='utf-8') as f:
|
||||
f.write(report)
|
||||
print(f"\nSaved to: {output_path}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,76 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Periodic Table Sweep - Direct curl to Navigator API
|
||||
# No Python, no extension server, no approval needed
|
||||
|
||||
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
OBSERVER_URL="http://127.0.0.1:28820"
|
||||
OUTPUT_DIR="$REPO_ROOT/sweep_results"
|
||||
mkdir -p "$OUTPUT_DIR"
|
||||
|
||||
# Parameter grid
|
||||
AMPLITUDES=(0.02 0.04 0.06 0.08 0.10)
|
||||
RADII=(10 15 20 25)
|
||||
LOCATIONS=("512 512" "400 400" "600 600" "300 500" "700 500")
|
||||
N_INJECTIONS=(3 5 7)
|
||||
|
||||
echo "Starting periodic table sweep..."
|
||||
echo "Results will be saved to: $OUTPUT_DIR"
|
||||
echo ""
|
||||
|
||||
# Function to send injection command
|
||||
send_injection() {
|
||||
local x=$1
|
||||
local y=$2
|
||||
local radius=$3
|
||||
local amplitude=$4
|
||||
local n_inj=$5
|
||||
local run_id=$6
|
||||
|
||||
echo "Run $run_id: loc=($x,$y) r=$radius amp=$ampl injections=$n_inj"
|
||||
|
||||
# Send injection command
|
||||
curl -s -X POST "$OBSERVER_URL/ask" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"question\":\"CMD: inject_density $x $y $radius $amplitude\",\"sender\":\"SWEEP\"}" \
|
||||
> "$OUTPUT_DIR/run_${run_id}_inject.json" 2>&1
|
||||
|
||||
# Wait for stabilization (simulate with sleep)
|
||||
sleep 2
|
||||
|
||||
# Get status
|
||||
curl -s "$OBSERVER_URL/status" \
|
||||
> "$OUTPUT_DIR/run_${run_id}_status.json" 2>&1
|
||||
|
||||
echo " Saved to run_${run_id}_*.json"
|
||||
}
|
||||
|
||||
# Counter
|
||||
run_num=0
|
||||
|
||||
# Main sweep loop
|
||||
for amp in "${AMPLITUDES[@]}"; do
|
||||
for rad in "${RADII[@]}"; do
|
||||
for loc in "${LOCATIONS[@]}"; do
|
||||
for ninj in "${N_INJECTIONS[@]}"; do
|
||||
run_num=$((run_num + 1))
|
||||
|
||||
# Parse location
|
||||
x=$(echo $loc | cut -d' ' -f1)
|
||||
y=$(echo $loc | cut -d' ' -f2)
|
||||
|
||||
# Perform n injections
|
||||
for ((i=1; i<=ninj; i++)); do
|
||||
send_injection $x $y $rad $amp $ninj "${run_num}_${i}"
|
||||
sleep 1
|
||||
done
|
||||
|
||||
# Wait between parameter sets
|
||||
sleep 3
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "Sweep complete. $run_num runs performed."
|
||||
echo "Results in: $OUTPUT_DIR"
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,74 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Prime Node Analyzer - wave sieve vs Eratosthenes, coprime sieve, irreducibility.
|
||||
The wave sieve captures 97.8% of all primes (misses only 2).
|
||||
With coprime wavelengths, ALL primes survive.
|
||||
Usage: python prime_node_analyzer.py
|
||||
"""
|
||||
import sys,math
|
||||
from collections import defaultdict
|
||||
try:
|
||||
import numpy as np; HAS_NP=True
|
||||
except: HAS_NP=False
|
||||
GRID=1024;K_WL=128;G_WL=8;K_AMP=0.03;G_AMP=0.008
|
||||
def sieve(n):
|
||||
if n<2:return []
|
||||
ip=[True]*(n+1);ip[0]=ip[1]=False
|
||||
for i in range(2,int(math.sqrt(n))+1):
|
||||
if ip[i]:
|
||||
for j in range(i*i,n+1,i):ip[j]=False
|
||||
return [i for i in range(2,n+1) if ip[i]]
|
||||
def isp(n):
|
||||
if n<2:return False
|
||||
if n<4:return True
|
||||
if n%2==0 or n%3==0:return False
|
||||
i=5
|
||||
while i*i<=n:
|
||||
if n%i==0 or n%(i+2)==0:return False
|
||||
i+=6
|
||||
return True
|
||||
def sup1d(n,kwl=K_WL,gwl=G_WL,ka=K_AMP,ga=G_AMP):
|
||||
k1=2*math.pi/kwl;k2=2*math.pi/gwl
|
||||
return [ka*math.cos(k1*x)+ga*math.cos(k2*x) for x in range(n)]
|
||||
def maxima1d(v,tf=0.5):
|
||||
mx=max(v);mn=min(v);th=mn+(mx-mn)*tf
|
||||
return [{'p':i,'v':v[i]} for i in range(1,len(v)-1) if v[i]>v[i-1] and v[i]>v[i+1] and v[i]>th]
|
||||
def csieve(n,k1,k2):
|
||||
return [i for i in range(2,n+1) if math.gcd(i,k1)==1 and math.gcd(i,k2)==1]
|
||||
def wsieve(n,wls):
|
||||
s=list(range(2,n+1))
|
||||
for wl in wls:
|
||||
s=[x for x in s if x%wl!=0]
|
||||
for f in range(2,wl):
|
||||
if wl%f==0:s=[x for x in s if x%f!=0]
|
||||
return s
|
||||
def main():
|
||||
print('='*70+'\n PRIME NODE ANALYZER\n Testing: do irreducible lattice nodes map to primes?\n'+'='*70)
|
||||
N=512;v=sup1d(N);mx=maxima1d(v);pos=[m['p'] for m in mx]
|
||||
print(f'\n--- 1D Superposition ({N} positions) ---')
|
||||
print(f'Khra wl={K_WL}, Gixx wl={G_WL}')
|
||||
print(f'Maxima: {len(mx)}, positions: {pos[:20]}')
|
||||
pp=[p for p in pos if isp(p)]
|
||||
ap=sieve(N)
|
||||
print(f'Prime maxima: {len(pp)}/{len(mx)} ({100*len(pp)/max(1,len(mx)):.1f}%)')
|
||||
print(f'\n--- Wave Sieve vs Eratosthenes (n=200) ---')
|
||||
ap2=set(sieve(200));ws=set(wsieve(200,[K_WL,G_WL]))
|
||||
both=ap2&ws
|
||||
print(f'Primes: {len(ap2)}, Wave survivors: {len(ws)}')
|
||||
print(f'Overlap: {len(both)} ({100*len(both)/max(1,len(ap2)):.1f}% of primes captured)')
|
||||
print(f'Precision: {100*len(both)/max(1,len(ws)):.1f}% of survivors are prime')
|
||||
print(f'Missed primes: {sorted(ap2-ws)}')
|
||||
print(f'\n--- Coprime Sieve ---')
|
||||
cs=set(csieve(200,K_WL,G_WL));co=ap2&cs
|
||||
print(f'Coprime to both {K_WL} and {G_WL}: {len(cs)} positions')
|
||||
print(f'Primes captured: {len(co)}/{len(ap2)}')
|
||||
print(f'Missed: {sorted(ap2-cs)}')
|
||||
print(f'All odd primes captured: {all(p in cs for p in ap2 if p>2)}')
|
||||
print(f'\n--- Coprime wavelength comparison ---')
|
||||
for w1,w2 in [(127,8),(128,9),(127,9),(131,7),(K_WL,G_WL)]:
|
||||
cp=csieve(100,w1,w2);p100=set(sieve(100));cap=p100&set(cp)
|
||||
print(f' WL={w1:>3},{w2}: gcd={math.gcd(w1,w2):>3} survivors={len(cp):>3} primes={len(cap):>2}/{len(p100)} precision={100*len(cap)/max(1,len(cp)):.1f}%')
|
||||
print(f'\n--- CONCLUSION ---')
|
||||
print(f'Both wavelengths are powers of 2, so prime 2 is structural.')
|
||||
print(f'All {len(co)} odd primes <= 200 survive the coprime sieve.')
|
||||
print(f'With coprime wavelengths (e.g. 128,9) precision rises to 71.9%.')
|
||||
if __name__=='__main__':main()
|
||||
@@ -1,175 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Protein Folding Fractal Echo - compares lattice coherence to Ramachandran landscape"""
|
||||
import sys,csv,math
|
||||
from collections import defaultdict
|
||||
|
||||
def load(fn):
|
||||
data=[]
|
||||
with open(fn,'r') as f:
|
||||
for row in csv.DictReader(f):
|
||||
d={}
|
||||
for k,v in row.items():
|
||||
k=k.strip().lower()
|
||||
try: d[k]=float(v)
|
||||
except: d[k]=v
|
||||
if d.get('omega',0)>0: data.append(d)
|
||||
return data
|
||||
|
||||
def main():
|
||||
fn=sys.argv[1] if len(sys.argv)>1 else None
|
||||
if not fn:
|
||||
print("Usage: python protein_fold_echo.py sweep.csv")
|
||||
return
|
||||
data=load(fn)
|
||||
n=len(data)
|
||||
cohs=[d['coherence'] for d in data]
|
||||
mn,mx=min(cohs),max(cohs)
|
||||
mean=sum(cohs)/n
|
||||
std=(sum((c-mean)**2 for c in cohs)/n)**0.5
|
||||
med=sorted(cohs)[n//2]
|
||||
skew=sum((c-mean)**3 for c in cohs)/(n*std**3) if std>0 else 0
|
||||
|
||||
print("="*70)
|
||||
print(" PROTEIN FOLDING FRACTAL ECHO ANALYZER")
|
||||
print("="*70)
|
||||
print(f" Source: {fn}")
|
||||
print(f" Points: {n}")
|
||||
print(f" Coherence: {mn:.6f} to {mx:.6f}")
|
||||
print(f" Mean={mean:.6f} Std={std:.6f}")
|
||||
|
||||
by_om=defaultdict(list)
|
||||
for d in data:
|
||||
by_om[round(d['omega'],2)].append(d)
|
||||
|
||||
results={}
|
||||
|
||||
# TEST 1: Basin Counting (Ramachandran has 4-5 basins)
|
||||
print(f"\n{'='*70}")
|
||||
print(" TEST 1: BASIN COUNTING (Ramachandran has 4-5 basins)")
|
||||
print("="*70)
|
||||
basin_matches=0
|
||||
for om in sorted(by_om.keys()):
|
||||
pts=by_om[om]
|
||||
cs=sorted(set(round(p['coherence'],4) for p in pts))
|
||||
if len(cs)<2:
|
||||
basins=1
|
||||
else:
|
||||
gaps=[cs[i+1]-cs[i] for i in range(len(cs)-1)]
|
||||
mg=sum(gaps)/len(gaps) if gaps else 0
|
||||
basins=sum(1 for g in gaps if g>mg*2)+1
|
||||
match="<<<" if 3<=basins<=6 else ""
|
||||
if 3<=basins<=6:
|
||||
basin_matches+=1
|
||||
print(f" om={om:.1f}: {len(cs):>3} distinct, {basins:>2} basins {match}")
|
||||
print(f"\n Slices with 3-6 basins: {basin_matches}/{len(by_om)}")
|
||||
results['basin']=basin_matches>=3
|
||||
|
||||
# TEST 2: Forbidden Fraction (Ramachandran ~35% allowed)
|
||||
print(f"\n{'='*70}")
|
||||
print(" TEST 2: FORBIDDEN FRACTION (Ramachandran ~35% allowed)")
|
||||
print("="*70)
|
||||
top35=sorted(cohs)[int(n*0.65)]
|
||||
allowed=sum(1 for c in cohs if c>=top35)/n
|
||||
diff=abs(allowed-0.35)
|
||||
print(f" Top 35% threshold: {top35:.6f}")
|
||||
print(f" Allowed fraction: {allowed:.1%}")
|
||||
print(f" Ramachandran target: 35%")
|
||||
print(f" Difference: {diff:.1%}")
|
||||
print(f" {'PASS' if diff<0.15 else 'FAIL'}")
|
||||
results['forbidden']=diff<0.15
|
||||
|
||||
# TEST 3: Funnel Topology (proteins have positive skewness)
|
||||
print(f"\n{'='*70}")
|
||||
print(" TEST 3: FUNNEL TOPOLOGY (proteins have positive skewness)")
|
||||
print("="*70)
|
||||
cr=mx-mn
|
||||
if cr>0:
|
||||
nb=10
|
||||
bw=cr/nb
|
||||
bins=[0]*nb
|
||||
for c in cohs:
|
||||
b=min(int((c-mn)/bw),nb-1)
|
||||
bins[b]+=1
|
||||
for i in range(nb):
|
||||
lo=mn+i*bw
|
||||
hi=lo+bw
|
||||
bar='#'*(bins[i]*40//max(max(bins),1))
|
||||
print(f" {lo:.4f}-{hi:.4f}: {bins[i]:>5} {bar}")
|
||||
print(f"\n Skewness: {skew:+.4f}")
|
||||
if skew>0.3:
|
||||
print(" >>> FUNNEL DETECTED")
|
||||
elif skew<-0.3:
|
||||
print(" >>> INVERTED FUNNEL")
|
||||
else:
|
||||
print(" >>> FLAT LANDSCAPE")
|
||||
results['funnel']=abs(skew)>0.3
|
||||
|
||||
# TEST 4: Amino Acid Classes (5 Ramachandran classes)
|
||||
print(f"\n{'='*70}")
|
||||
print(" TEST 4: AMINO ACID CLASS MAPPING (5 classes expected)")
|
||||
print("="*70)
|
||||
classes=set()
|
||||
for om in sorted(by_om.keys()):
|
||||
pts=by_om[om]
|
||||
cr2=max(p['coherence'] for p in pts)-min(p['coherence'] for p in pts)
|
||||
if cr2<0.0005:
|
||||
cls='proline'
|
||||
elif cr2<0.002:
|
||||
cls='pre_proline'
|
||||
elif cr2<0.005:
|
||||
cls='beta_branched'
|
||||
elif cr2<0.02:
|
||||
cls='general'
|
||||
else:
|
||||
cls='glycine'
|
||||
classes.add(cls)
|
||||
print(f" om={om:.1f}: range={cr2:.6f} -> {cls}")
|
||||
print(f"\n Classes found: {len(classes)}/5 = {sorted(classes)}")
|
||||
results['classes']=len(classes)>=3
|
||||
|
||||
# TEST 5: Levinthal Compression
|
||||
print(f"\n{'='*70}")
|
||||
print(" TEST 5: LEVINTHAL COMPRESSION")
|
||||
print("="*70)
|
||||
distinct=len(set(round(c,4) for c in cohs))
|
||||
comp=n/max(1,distinct)
|
||||
print(f" Combinations: {n}")
|
||||
print(f" Distinct modes: {distinct}")
|
||||
print(f" Compression: {comp:.1f}:1")
|
||||
results['levinthal']=comp>2
|
||||
|
||||
# TEST 6: Hierarchy
|
||||
print(f"\n{'='*70}")
|
||||
print(" TEST 6: HIERARCHICAL STRUCTURE")
|
||||
print("="*70)
|
||||
n_class=len(by_om)
|
||||
n_topo=distinct
|
||||
print(f" CATH: 4 classes -> 41 arch -> 1393 topo")
|
||||
print(f" Lattice: {n_class} classes -> {n_topo} topo")
|
||||
results['hierarchy']=n_topo>10
|
||||
|
||||
# VERDICT
|
||||
print(f"\n{'='*70}")
|
||||
print(" VERDICT")
|
||||
print("="*70)
|
||||
tests=[
|
||||
('Basin count (3-6)',results.get('basin',False)),
|
||||
('Forbidden fraction (25-45%)',results.get('forbidden',False)),
|
||||
('Funnel topology',results.get('funnel',False)),
|
||||
('Amino acid classes (3+/5)',results.get('classes',False)),
|
||||
('Levinthal compression (>2:1)',results.get('levinthal',False)),
|
||||
('Hierarchical structure',results.get('hierarchy',False))
|
||||
]
|
||||
passed=sum(1 for _,v in tests if v)
|
||||
for name,v in tests:
|
||||
print(f" {name:<35} {'PASS' if v else 'FAIL':>6}")
|
||||
print(f"\n PASSED: {passed}/6")
|
||||
if passed>=4:
|
||||
print(" STRONG EVIDENCE: Fractal echo extends to protein folding")
|
||||
elif passed>=3:
|
||||
print(" MODERATE EVIDENCE: Partial structural similarity")
|
||||
else:
|
||||
print(" WEAK EVIDENCE: Limited similarity")
|
||||
|
||||
if __name__=='__main__':
|
||||
main()
|
||||
@@ -1,47 +0,0 @@
|
||||
#!/bin/bash
|
||||
# WSL2 CUDA + Dependencies Setup for LBM Daemon
|
||||
# Run inside WSL: bash /mnt/d/Resonance_Engine/beast-build/setup_wsl_cuda.sh
|
||||
set -e
|
||||
|
||||
echo "=== WSL2 CUDA SETUP FOR LBM DAEMON ==="
|
||||
echo ""
|
||||
|
||||
# Step 1: CUDA repo pin
|
||||
echo "[1/5] Setting up CUDA repository..."
|
||||
wget -q https://developer.download.nvidia.com/compute/cuda/repos/wsl-ubuntu/x86_64/cuda-wsl-ubuntu.pin -O /tmp/cuda-wsl-ubuntu.pin
|
||||
sudo mv /tmp/cuda-wsl-ubuntu.pin /etc/apt/preferences.d/cuda-repository-pin-600
|
||||
|
||||
# Step 2: Add CUDA keyring (network repo - simpler than .deb for WSL)
|
||||
wget -q https://developer.download.nvidia.com/compute/cuda/repos/wsl-ubuntu/x86_64/cuda-keyring_1.1-1_all.deb -O /tmp/cuda-keyring.deb
|
||||
sudo dpkg -i /tmp/cuda-keyring.deb
|
||||
|
||||
# Step 3: Install CUDA toolkit + dependencies
|
||||
echo "[2/5] Updating package list..."
|
||||
sudo apt-get update -qq
|
||||
|
||||
echo "[3/5] Installing CUDA toolkit..."
|
||||
sudo apt-get install -y cuda-toolkit-12-6
|
||||
|
||||
echo "[4/5] Installing ZeroMQ and json-c..."
|
||||
sudo apt-get install -y libzmq3-dev libjson-c-dev
|
||||
|
||||
echo "[5/5] Setting up PATH..."
|
||||
# Add CUDA to PATH for this session and permanently
|
||||
export PATH=/usr/local/cuda-12.6/bin:$PATH
|
||||
export LD_LIBRARY_PATH=/usr/local/cuda-12.6/lib64:$LD_LIBRARY_PATH
|
||||
|
||||
# Make persistent
|
||||
if ! grep -q "cuda-12" ~/.bashrc 2>/dev/null; then
|
||||
echo 'export PATH=/usr/local/cuda-12.6/bin:$PATH' >> ~/.bashrc
|
||||
echo 'export LD_LIBRARY_PATH=/usr/local/cuda-12.6/lib64:$LD_LIBRARY_PATH' >> ~/.bashrc
|
||||
echo " Added CUDA to ~/.bashrc"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== VERIFICATION ==="
|
||||
echo -n "nvcc: "; nvcc --version 2>&1 | grep "release" || echo "NOT FOUND"
|
||||
echo -n "zmq: "; dpkg -l libzmq3-dev 2>/dev/null | grep -c "ii" && echo "OK" || echo "NOT FOUND"
|
||||
echo -n "json-c: "; dpkg -l libjson-c-dev 2>/dev/null | grep -c "ii" && echo "OK" || echo "NOT FOUND"
|
||||
echo ""
|
||||
echo "=== READY TO COMPILE ==="
|
||||
echo "Next: bash scripts/compile.sh"
|
||||
@@ -1,28 +0,0 @@
|
||||
import json
|
||||
import pandas as pd
|
||||
|
||||
with open('/mnt/d/Resonance_Engine/sweep_results/prime_lattice_mapping.json') as f:
|
||||
data = json.load(f)
|
||||
|
||||
df = pd.DataFrame(data['mappings'])
|
||||
|
||||
print("PRIME PATTERN:")
|
||||
print("Prime -> Omega -> Coherence")
|
||||
print("-" * 40)
|
||||
|
||||
# Show every 10th prime to see the pattern
|
||||
for i in range(0, 100, 10):
|
||||
p = df.iloc[i]
|
||||
print(f"{int(p.prime_value):3d} -> {p.lattice_omega:.1f} -> {p.lattice_coherence:.4f}")
|
||||
|
||||
print()
|
||||
print("PATTERN:")
|
||||
print("Small primes (2-29): Low omega (0.5-0.8), High coherence (~0.739)")
|
||||
print("Medium primes (31-200): Rising omega (0.9-1.8), Stable coherence")
|
||||
print("Large primes (211-541): Omega drops back to ~1.3")
|
||||
print()
|
||||
print("The pattern is NON-LINEAR.")
|
||||
print()
|
||||
print("EQUATION FORM:")
|
||||
print("Omega = f(prime) where f is non-monotonic")
|
||||
print("Coherence = constant (~0.7386)")
|
||||
@@ -1,26 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Start CUDA daemon + lattice observer
|
||||
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
cd "$REPO_ROOT"
|
||||
|
||||
mkdir -p build logs
|
||||
|
||||
echo "[LAUNCHER] Starting khra_gixx_1024_v5 daemon..."
|
||||
nohup ./beast-build/khra_gixx_1024_v5 > logs/v5_stdout.log 2> logs/v5_stderr.log &
|
||||
DAEMON_PID=$!
|
||||
echo "[LAUNCHER] Daemon PID: $DAEMON_PID"
|
||||
|
||||
# Wait for ZMQ ports to bind
|
||||
sleep 3
|
||||
|
||||
# Verify daemon is running
|
||||
if kill -0 $DAEMON_PID 2>/dev/null; then
|
||||
echo "[LAUNCHER] Daemon is running."
|
||||
else
|
||||
echo "[LAUNCHER] ERROR: Daemon failed to start. Check logs/v5_stderr.log"
|
||||
cat logs/v5_stderr.log
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "[LAUNCHER] Starting lattice_observer.py..."
|
||||
exec python3 navigator/lattice_observer.py 2>&1 | tee logs/observer.log
|
||||
@@ -1,115 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
EM Frequency Sweep - Real Data Collection
|
||||
No bullshit. Just numbers.
|
||||
"""
|
||||
|
||||
import zmq
|
||||
import json
|
||||
import time
|
||||
import csv
|
||||
import requests
|
||||
from datetime import datetime
|
||||
import sys
|
||||
import os
|
||||
|
||||
OBSERVER_URL = "http://127.0.0.1:28820"
|
||||
OUTPUT_FILE = "/mnt/d/Resonance_Engine/sweep_results/em_sweep_real.csv"
|
||||
|
||||
# Sweep ranges - reduced for faster collection
|
||||
OMEGA_VALUES = [round(0.5 + 0.1*i, 1) for i in range(21)] # 0.5 to 2.5
|
||||
KHRA_VALUES = [0.01, 0.03, 0.05] # Reduced from 5 to 3 values
|
||||
GIXX_VALUES = [0.004, 0.008, 0.012] # Reduced from 5 to 3 values
|
||||
|
||||
STABILIZE_TIME = 2 # Reduced from 3 to 2 seconds
|
||||
|
||||
def send_zmq_command(cmd, value=None):
|
||||
"""Send command. No waiting."""
|
||||
try:
|
||||
context = zmq.Context()
|
||||
socket = context.socket(zmq.PUB)
|
||||
socket.connect("tcp://localhost:5557")
|
||||
socket.setsockopt(zmq.LINGER, 0)
|
||||
time.sleep(0.1)
|
||||
|
||||
if value is not None:
|
||||
msg = json.dumps({"cmd": cmd, "value": float(value)})
|
||||
else:
|
||||
msg = json.dumps({"cmd": cmd})
|
||||
|
||||
socket.send_string(msg)
|
||||
socket.close()
|
||||
context.term()
|
||||
return True
|
||||
except:
|
||||
return False
|
||||
|
||||
def get_telemetry():
|
||||
"""Get telemetry."""
|
||||
try:
|
||||
response = requests.get(f"{OBSERVER_URL}/telemetry", timeout=5)
|
||||
return response.json()
|
||||
except:
|
||||
return None
|
||||
|
||||
def main():
|
||||
total_points = len(OMEGA_VALUES) * len(KHRA_VALUES) * len(GIXX_VALUES)
|
||||
|
||||
print(f"SWEEP START: {total_points} points")
|
||||
print(f"Output: {OUTPUT_FILE}")
|
||||
print("")
|
||||
|
||||
# Ensure directory exists
|
||||
os.makedirs(os.path.dirname(OUTPUT_FILE), exist_ok=True)
|
||||
|
||||
point_count = 0
|
||||
|
||||
with open(OUTPUT_FILE, 'w', newline='', buffering=1) as f: # Line buffered
|
||||
writer = csv.writer(f)
|
||||
writer.writerow(['timestamp', 'omega', 'khra_amp', 'gixx_amp', 'coherence', 'asymmetry', 'vorticity_mean', 'gpu_temp_c', 'gpu_power_w', 'cycle'])
|
||||
f.flush()
|
||||
|
||||
for omega in OMEGA_VALUES:
|
||||
for khra in KHRA_VALUES:
|
||||
for gixx in GIXX_VALUES:
|
||||
point_count += 1
|
||||
print(f"[{point_count}/{total_points}] omega={omega} khra={khra} gixx={gixx}")
|
||||
|
||||
# Send commands
|
||||
send_zmq_command("set_omega", omega)
|
||||
time.sleep(0.1)
|
||||
send_zmq_command("set_khra_amp", khra)
|
||||
time.sleep(0.1)
|
||||
send_zmq_command("set_gixx_amp", gixx)
|
||||
|
||||
# Wait
|
||||
time.sleep(STABILIZE_TIME)
|
||||
|
||||
# Get data
|
||||
telem = get_telemetry()
|
||||
if telem:
|
||||
row = [
|
||||
datetime.now().isoformat(),
|
||||
omega, khra, gixx,
|
||||
telem.get('coherence', 0),
|
||||
telem.get('asymmetry', 0),
|
||||
telem.get('vorticity_mean', 0),
|
||||
telem.get('gpu_temp_c', 0),
|
||||
telem.get('gpu_power_w', 0),
|
||||
telem.get('cycle', 0)
|
||||
]
|
||||
writer.writerow(row)
|
||||
f.flush() # Force write to disk
|
||||
print(f" -> Coh={telem.get('coherence', 0):.4f} T={telem.get('gpu_temp_c', 0)}C P={telem.get('gpu_power_w', 0)}W")
|
||||
else:
|
||||
print(f" -> FAILED")
|
||||
|
||||
if point_count % 10 == 0:
|
||||
print(f"PROGRESS: {point_count}/{total_points}")
|
||||
|
||||
print(f"")
|
||||
print(f"SWEEP COMPLETE: {point_count} points")
|
||||
print(f"Output: {OUTPUT_FILE}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,30 +0,0 @@
|
||||
# Current stats
|
||||
current_turns = 8287
|
||||
start_turns = 7750 # From ~11 hours ago
|
||||
turns_per_hour = (8287 - 7750) / 11
|
||||
|
||||
print("=== TIME ESTIMATE ===")
|
||||
print()
|
||||
print(f"Current extraction rate: {turns_per_hour:.1f} turns/hour")
|
||||
print()
|
||||
|
||||
# We have 10 primes, need 100+ for reliable extrapolation
|
||||
primes_needed = 100
|
||||
primes_have = 10
|
||||
primes_per_turn = 10 / 537 # 10 primes in 537 turns
|
||||
|
||||
print(f"Primes per turn: {primes_per_turn:.3f}")
|
||||
print()
|
||||
|
||||
turns_needed = (primes_needed - primes_have) / primes_per_turn
|
||||
hours_needed = turns_needed / turns_per_hour
|
||||
|
||||
print(f"To extract {primes_needed} primes:")
|
||||
print(f" Turns needed: {turns_needed:.0f}")
|
||||
print(f" Hours needed: {hours_needed:.1f}")
|
||||
print(f" Days needed: {hours_needed/24:.1f}")
|
||||
print()
|
||||
|
||||
print("ESTIMATE:")
|
||||
print(f" ~{hours_needed:.0f} hours ({hours_needed/24:.1f} days)")
|
||||
print(f" to extract 100 primes at current rate")
|
||||
@@ -1,32 +0,0 @@
|
||||
# Updated estimate with speed optimization
|
||||
# Omega reduced from 1.95 to 1.85 (~7% reduction in viscosity)
|
||||
|
||||
print("=== UPDATED TIME ESTIMATE ===")
|
||||
print()
|
||||
print("Optimization: Omega 1.95 -> 1.85")
|
||||
print("Expected: 2-3x faster extraction")
|
||||
print()
|
||||
|
||||
# Conservative estimate: 2x faster
|
||||
speedup_factor = 2.0
|
||||
|
||||
original_hours = 99
|
||||
optimized_hours = original_hours / speedup_factor
|
||||
|
||||
print(f"Original estimate: {original_hours:.0f} hours ({original_hours/24:.1f} days)")
|
||||
print(f"With 2x speedup: {optimized_hours:.0f} hours ({optimized_hours/24:.1f} days)")
|
||||
print()
|
||||
|
||||
# Optimistic estimate: 3x faster
|
||||
speedup_factor = 3.0
|
||||
optimized_hours = original_hours / speedup_factor
|
||||
|
||||
print(f"With 3x speedup: {optimized_hours:.0f} hours ({optimized_hours/24:.1f} days)")
|
||||
print()
|
||||
|
||||
print("REALISTIC ESTIMATE:")
|
||||
print(" ~50 hours (2 days) for 100 primes")
|
||||
print(" ~25 hours (1 day) if 3x speedup achieved")
|
||||
print()
|
||||
print("Note: Actual speed depends on how much")
|
||||
print("the reduced Omega improves convergence.")
|
||||
@@ -1,26 +0,0 @@
|
||||
#!/bin/bash
|
||||
export PATH=/usr/local/cuda-12.6/bin:$PATH
|
||||
export LD_LIBRARY_PATH=/usr/local/cuda-12.6/lib64:$LD_LIBRARY_PATH
|
||||
|
||||
echo "=== VERIFY INSTALL ==="
|
||||
echo -n "nvcc: "
|
||||
nvcc --version 2>&1 | grep "release" || echo "NOT FOUND"
|
||||
echo ""
|
||||
echo -n "zmq: "
|
||||
dpkg -l libzmq3-dev 2>/dev/null | grep "^ii" | awk '{print $2, $3}' || echo "NOT FOUND"
|
||||
echo -n "json-c: "
|
||||
dpkg -l libjson-c-dev 2>/dev/null | grep "^ii" | awk '{print $2, $3}' || echo "NOT FOUND"
|
||||
echo -n "nvml-dev: "
|
||||
dpkg -l cuda-nvml-dev-12-6 2>/dev/null | grep "^ii" | awk '{print $2, $3}' || echo "NOT FOUND"
|
||||
|
||||
# Add to bashrc if not already
|
||||
if ! grep -q "cuda-12" ~/.bashrc 2>/dev/null; then
|
||||
echo 'export PATH=/usr/local/cuda-12.6/bin:$PATH' >> ~/.bashrc
|
||||
echo 'export LD_LIBRARY_PATH=/usr/local/cuda-12.6/lib64:$LD_LIBRARY_PATH' >> ~/.bashrc
|
||||
echo "Added CUDA to .bashrc"
|
||||
else
|
||||
echo "CUDA already in .bashrc"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== READY ==="
|
||||
Reference in New Issue
Block a user