#!/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()