CJPT Framework - Interactive Exploration¶

This notebook provides interactive exploration of the Causal-Jacobi Phase Transition framework.

Contents¶

  1. System Initialization
  2. Single Rollout Analysis
  3. f₂ Parameter Scan
  4. Causal Bound Extraction
  5. Phase Diagram Visualization
  6. Custom Analysis
In [ ]:
import sys
sys.path.append('/app/utils')
sys.path.append('/app/src')

import numpy as np
import matplotlib.pyplot as plt
from IPython.display import Image, display

from causal_enforcer import CausalEnforcer
from tensor_cell import TensorCell
from cjpt_system import CJPTSystem
from f2_scanner import F2Scanner
from visualizer import CJPTVisualizer
from cjpt_simulation import CJPTSimulation

# Set up plotting
plt.style.use('default')
%matplotlib inline

print('CJPT Framework loaded successfully!')

1. System Initialization¶

Initialize all CJPT components with default configuration.

In [ ]:
# Initialize simulation
sim = CJPTSimulation()

print('System Configuration:')
print(f"  M_Pl = {sim.cjpt.M_Pl:.3e} GeV")
print(f"  xi_H = {sim.cjpt.xi_H:.3e}")
print(f"  eta = {sim.cjpt.eta}")
print(f"  kappa_mc = {sim.cjpt.kappa_mc}")
print(f"\nCausalEnforcer tolerance: {sim.enforcer.kk_tolerance}")
print(f"TensorCell UUID: {sim.tensor_cell.uuid}")

2. Single Rollout Analysis¶

Run a single rollout at f₂ = 10⁻⁸ (convergence point).

In [ ]:
# Run rollout
f2_target = 1e-8
sim.run_single_rollout(f2=f2_target, n_steps=50)

# Display phase statistics
from collections import Counter
phase_counts = Counter(sim.cjpt.phase_history)

print('\nPhase Distribution:')
for phase, count in phase_counts.items():
    print(f"  {phase:25s}: {count:3d} steps ({100*count/len(sim.cjpt.phase_history):.1f}%)")

# Plot phase evolution
sim.visualizer.plot_phase_diagram(sim.cjpt)
display(Image('/app/outputs/phase_diagram.png'))

3. f₂ Parameter Scan¶

Scan f₂ parameter space from 5×10⁻⁹ to 2×10⁻⁸ to extract bound shape.

In [ ]:
# Run f2 scan
scan_results, bound_shape = sim.run_f2_scan()

# Display 2D contour
print('\n2D Contour Map:')
display(Image('/app/outputs/cjpt_contour_2d.png'))

# Display 3D surface
print('\n3D Surface Plot:')
display(Image('/app/outputs/cjpt_contour_3d.png'))

4. Bound Shape Analysis¶

Extract and analyze the emergent causal bound shape.

In [ ]:
print('Bound Shape Analysis:')
print(f"  f₂ = {bound_shape['f2']:.3e}")
print(f"  J_bound = {bound_shape['J_bound']:.3e}")
print(f"  Δ_c = {bound_shape['delta_c']:.3e}")
print(f"  Boundary points: {len(bound_shape['omega_boundary'])}")

if len(bound_shape['omega_boundary']) > 0:
    print(f"  Ω range: [{bound_shape['omega_boundary'].min():.3e}, {bound_shape['omega_boundary'].max():.3e}] rad/s")
    
    # Plot bound shape
    plt.figure(figsize=(10, 6))
    plt.semilogy(bound_shape['omega_boundary'], 'o-', markersize=4)
    plt.xlabel('Boundary Point Index')
    plt.ylabel('ω (rad/s)')
    plt.title(f"Emergent Bound Shape B(ω; f₂={bound_shape['f2']:.2e})")
    plt.grid(True, alpha=0.3)
    plt.tight_layout()
    plt.savefig('/app/outputs/bound_shape.png', dpi=150)
    plt.show()

5. Diagnostic Dashboard¶

View comprehensive system diagnostics.

In [ ]:
# Generate dashboard
sim.visualizer.plot_diagnostic_dashboard(sim.cjpt, sim.tensor_cell, sim.enforcer)

# Display
display(Image('/app/outputs/diagnostic_dashboard.png'))

6. Custom Analysis: Causal Deviation vs f₂¶

Explore how maximum causal deviation scales with f₂.

In [ ]:
# Extract max deviation for each f2
f2_values = scan_results['f2_values']
delta_kk_max = np.max(scan_results['delta_kk_grid'], axis=1)
J_bound_values = scan_results['J_bound_values']

# Plot scaling
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 8), sharex=True)

# Max deviation
ax1.loglog(f2_values, delta_kk_max, 'o-', label='max(Δ_KK)', markersize=6)
ax1.loglog(f2_values, J_bound_values, 's--', label='J_bound', markersize=5, alpha=0.7)
ax1.set_ylabel('Amplitude', fontsize=12)
ax1.legend(fontsize=11)
ax1.grid(True, alpha=0.3)
ax1.set_title('Causal Deviation Scaling with f₂', fontsize=14)

# Ratio
ratio = delta_kk_max / J_bound_values
ax2.semilogx(f2_values, ratio, 'd-', color='purple', markersize=6)
ax2.axhline(0.8, color='orange', linestyle='--', label='η = 0.8 (boundary)')
ax2.axhline(1.2, color='red', linestyle='--', label='1.2 (dual emergence)')
ax2.set_xlabel('f₂ (dimensionless)', fontsize=12)
ax2.set_ylabel('max(Δ_KK) / J_bound', fontsize=12)
ax2.legend(fontsize=11)
ax2.grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig('/app/outputs/f2_scaling_analysis.png', dpi=150)
plt.show()

# Find convergence point
convergence_idx = np.argmin(np.abs(ratio - 1.0))
f2_convergence = f2_values[convergence_idx]
print(f'\nConvergence point: f₂ ≈ {f2_convergence:.3e}')
print(f'Ratio at convergence: {ratio[convergence_idx]:.3f}')

7. Dual-Field Emergence Verification¶

Check for dual-field emergence signatures.

In [ ]:
verification = sim.verify_dual_field_emergence()

print('\nDual-Field Emergence Verification:')
print('='*50)

# Analyze trap door history
if sim.cjpt.g_trap_history:
    g_trap_array = np.array(sim.cjpt.g_trap_history)
    in_window = np.sum((g_trap_array >= 1.0) & (g_trap_array <= 1.5))
    total = len(g_trap_array)
    
    print(f'Trap Door Analysis:')
    print(f'  Steps in [1.0, 1.5] window: {in_window}/{total} ({100*in_window/total:.1f}%)')
    print(f'  Mean G_trap: {np.mean(g_trap_array):.3f}')
    print(f'  Max G_trap: {np.max(g_trap_array):.3f}')

# Phase statistics
dual_count = sim.cjpt.phase_history.count('DUAL_EMERGENCE')
bound_count = sim.cjpt.phase_history.count('BOUND_RECONSTRUCTION')
total_phases = len(sim.cjpt.phase_history)

print(f'\nPhase Statistics:')
print(f'  DUAL_EMERGENCE: {dual_count}/{total_phases} ({100*dual_count/total_phases:.1f}%)')
print(f'  BOUND_RECONSTRUCTION: {bound_count}/{total_phases} ({100*bound_count/total_phases:.1f}%)')

if dual_count > 0:
    print('\n✅ Dual-field emergence detected!')
else:
    print('\n❌ No dual-field emergence in current run.')
    print('   Try increasing rollout steps or adjusting f₂ range.')

Summary¶

All outputs are saved to /app/outputs/.

In [ ]:
from pathlib import Path

output_dir = Path('/app/outputs')
print('Generated Files:')
for f in sorted(output_dir.glob('*.png')):
    print(f'  - {f.name}')