app / app.py
antonypamo's picture
Update app.py
d656cfe verified
#!/usr/bin/env python3
"""
RRF Φ5.2 - Resonance of Reality Framework
Hugging Face Spaces Interactive Application - FIXED FOR HF COMPATIBILITY
Author: A. Padilla Morales
ORCID: 0009-0000-3530-2146
"""
import numpy as np
import pandas as pd
import warnings
warnings.filterwarnings('ignore')
from scipy import sparse, linalg
import networkx as nx
import matplotlib.pyplot as plt
import gradio as gr
# ============================================================================
# RRF CONFIGURATION & INITIALIZATION
# ============================================================================
class RRFConfig:
"""RRF Φ5.2 configuration"""
def __init__(self):
self.model_version = "Phi 5.2"
self.manifold_type = "Subdivided Icosahedral"
self.num_nodes = 12
self.dirac_gap_ev = 0.092
self.fiedler_n12 = 2.974914
self.mean_sparc_coherence = 0.8163
self.symmetry_breaking_threshold = 0.000204
class IcosahedralManifold:
"""12-node icosahedral discrete manifold"""
def __init__(self, num_nodes=12):
self.num_nodes = num_nodes
self.eigenvalues = None
self.eigenvectors = None
self._construct()
def _construct(self):
"""Build icosahedron"""
phi = (1 + np.sqrt(5)) / 2
vertices = np.array([
[1, phi, 0], [-1, phi, 0], [1, -phi, 0], [-1, -phi, 0],
[0, 1, phi], [0, -1, phi], [0, 1, -phi], [0, -1, -phi],
[phi, 0, 1], [-phi, 0, 1], [phi, 0, -1], [-phi, 0, -1]
])
vertices = vertices / np.linalg.norm(vertices[0])
# Build adjacency
adjacency = np.zeros((self.num_nodes, self.num_nodes))
threshold = 1.1
for i in range(self.num_nodes):
for j in range(i+1, self.num_nodes):
dist = np.linalg.norm(vertices[i] - vertices[j])
if dist < threshold:
adjacency[i, j] = 1.0
adjacency[j, i] = 1.0
# Laplacian
degrees = adjacency.sum(axis=1)
degree_matrix = np.diag(degrees)
laplacian = degree_matrix - adjacency
# Eigendecomposition
eigenvalues, eigenvectors = np.linalg.eigh(laplacian)
self.eigenvalues = eigenvalues
self.eigenvectors = eigenvectors
class CoherenceAnalyzer:
"""Compute resonance coherence"""
def __init__(self, manifold):
self.manifold = manifold
def analyze(self, velocity_curve):
"""Compute coherence score"""
# Interpolate to 12 nodes
indices = np.linspace(0, len(velocity_curve)-1, self.manifold.num_nodes)
signal_interp = np.interp(indices, np.arange(len(velocity_curve)), velocity_curve)
# Project onto eigenbasis
coefficients = self.manifold.eigenvectors.T @ signal_interp
reconstructed = self.manifold.eigenvectors @ coefficients
# Interpolate back
indices_back = np.linspace(0, len(reconstructed)-1, len(velocity_curve))
reconstructed_interp = np.interp(indices_back, np.arange(len(reconstructed)), reconstructed)
# Calculate coherence
residuals = velocity_curve - reconstructed_interp
mse = np.mean(residuals**2)
signal_variance = np.var(velocity_curve)
if signal_variance > 0:
normalized_error = mse / signal_variance
coherence = 1.0 / (1.0 + normalized_error)
else:
coherence = 0.5
# Energy concentration
total_energy = np.sum(coefficients**2)
low_mode_energy = np.sum(coefficients[:3]**2)
energy_concentration = low_mode_energy / total_energy if total_energy > 0 else 0.0
return {
'coherence': float(coherence),
'rmse': float(np.sqrt(mse)),
'energy_concentration': float(energy_concentration),
'reconstructed': reconstructed_interp,
'residuals': residuals
}
# ============================================================================
# INITIALIZE FRAMEWORK
# ============================================================================
config = RRFConfig()
manifold = IcosahedralManifold()
analyzer = CoherenceAnalyzer(manifold)
# ============================================================================
# ANALYSIS FUNCTIONS
# ============================================================================
def analyze_rotation_curve(velocity_input):
"""Main analysis function"""
try:
# Parse input
if isinstance(velocity_input, str):
velocity_data = np.array([float(x.strip()) for x in velocity_input.split(',')])
else:
velocity_data = np.array(velocity_input).flatten()
if len(velocity_data) < 5:
return "Error: Need at least 5 velocity measurements", None
# Normalize
velocity_data = (velocity_data - np.mean(velocity_data)) / (np.std(velocity_data) + 1e-6)
# Analyze
results = analyzer.analyze(velocity_data)
# Create visualization
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
# Fit plot
r = np.linspace(0, 20, len(velocity_data))
axes[0].plot(r, velocity_data, 'o-', label='Observed', linewidth=2, markersize=5, color='black')
axes[0].plot(r, results['reconstructed'], 's--', label='RRF Fit', linewidth=2, color='blue')
axes[0].set_xlabel('Radius (kpc)', fontsize=11)
axes[0].set_ylabel('Velocity (km/s)', fontsize=11)
axes[0].set_title(f'Spectral Fit (Coherence: {results["coherence"]:.4f})', fontsize=12, fontweight='bold')
axes[0].legend(fontsize=10)
axes[0].grid(True, alpha=0.3)
# Residuals plot
axes[1].bar(r, results['residuals'], color='steelblue', alpha=0.7, edgecolor='black')
axes[1].axhline(y=0, color='red', linestyle='--', linewidth=2)
axes[1].set_xlabel('Radius (kpc)', fontsize=11)
axes[1].set_ylabel('Residuals', fontsize=11)
axes[1].set_title(f'Fit Residuals (RMSE: {results["rmse"]:.4f})', fontsize=12, fontweight='bold')
axes[1].grid(True, alpha=0.3, axis='y')
plt.tight_layout()
# Classification
if results['coherence'] > 0.95:
stability = "🟢 Golden Standard"
elif results['coherence'] > config.mean_sparc_coherence + 0.05:
stability = "🟢 High Stability"
elif results['coherence'] > config.mean_sparc_coherence:
stability = "🟡 Above Baseline"
else:
stability = "🟠 Near Baseline"
report = f"""## RRF Φ5.2 Results
**Coherence**: {results['coherence']:.4f}
**Baseline**: {config.mean_sparc_coherence:.4f}
**Change**: {((results['coherence']/config.mean_sparc_coherence - 1) * 100):+.1f}%
**Stability**: {stability}
**RMSE**: {results['rmse']:.4f}
**Energy Concentration**: {results['energy_concentration']:.2%}
---
Framework: {config.model_version} | Manifold: {config.manifold_type}
"""
return report, fig
except Exception as e:
return f"**Error**: {str(e)}", None
# ============================================================================
# GRADIO INTERFACE
# ============================================================================
with gr.Blocks(title="RRF Φ5.2") as demo:
gr.Markdown("""
# 🌍 RRF Φ5.2 Resonance Analysis
Discrete topological approach to galactic coherence
**A. Padilla Morales** | ORCID: 0009-0000-3530-2146
""")
with gr.Row():
with gr.Column():
velocity_input = gr.Textbox(
label="Velocity Data (comma-separated)",
placeholder="200, 210, 215, ...",
lines=4
)
btn = gr.Button("Analyze", size="lg", variant="primary")
with gr.Column():
results = gr.Markdown()
plot = gr.Plot()
btn.click(fn=analyze_rotation_curve, inputs=[velocity_input], outputs=[results, plot])
with gr.Accordion("Example Data"):
gr.Markdown("""
**NGC 7331**:
```
200, 210, 215, 218, 220, 221, 222, 222, 223, 223, 224, 224, 224, 225, 225, 225, 225, 226, 226, 226, 226, 227, 227, 227, 227, 227, 228, 228, 228, 228, 228, 228, 229, 229, 229, 229
```
""")
if __name__ == "__main__":
demo.launch()