smithery/plurigrid

fokker-planck-analyzer

Layer 5: Convergence to Equilibrium Analysis

Installation

$ npx skills add smithery/plurigrid --skill fokker-planck-analyzer

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from smithery/plurigrid · top by installs.

npx skills add smithery/plurigrid

Browse all from smithery/plurigrid

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Skill metadata

Parsed from SKILL.md frontmatter.

More metadata
trit
0

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 10,513 B
  • docs SUMMARY.md 74 B

History

  1. First recorded snapshot · 0 installs

SKILL.md

fokker-planck-analyzer

Layer 5: Convergence to Equilibrium Analysis

Version: 1.0.0 Trit: -1 (Validator - verifies steady state) Bundle: analysis Status: ✅ New (validates Fokker-Planck convergence)


Overview

Fokker-Planck Analyzer verifies that neural network training via Langevin dynamics has reached equilibrium. It checks whether the empirical weight distribution matches the theoretical Gibbs distribution predicted by Fokker-Planck theory.

Key Insight: Training that stops before reaching mixing time (τ_mix) ends up in different regions of the loss landscape than continuous theory predicts. This skill detects that gap.

The Fokker-Planck Equation

∂p/∂t = ∇·(∇L(θ)·p) + T∆p

Boundary condition: p(θ, 0) = p₀(θ) [initial distribution]
Steady state:      p∞(θ) ∝ exp(-L(θ)/T) [Gibbs distribution]

Where:

  • p(θ, t) = probability density of parameter θ at time t
  • L(θ) = loss function
  • T = temperature (controls noise scale)
  • ∆p = Laplacian (diffusion operator)

Core Concepts

Gibbs Distribution

At equilibrium, weights follow a Boltzmann-like distribution:

p∞(θ) ∝ exp(-L(θ)/T)

Interpretation:
- Lower loss → higher probability
- Temperature T controls sharpness:
  - Low T: Sharp peaks at good minima
  - High T: Broad, flat distribution

Mixing Time (τ_mix)

Time until the distribution converges to Gibbs:

τ_mix ≈ 1 / λ_min(H)

Where H = Hessian of loss landscape at equilibrium

For well-conditioned problems: τ_mix ∝ 1/λ_min
For ill-conditioned problems: τ_mix can be very large

Relative Entropy / KL Divergence

Measure how far current distribution is from Gibbs:

D_KL(p_t || p∞) = ∫ p_t(θ) log(p_t(θ) / p∞(θ)) dθ

At equilibrium: D_KL → 0
During training: D_KL > 0 (decreasing exponentially)

Capabilities

1. check-gibbs-convergence

Verify that trajectory is approaching Gibbs distribution:

from fokker_planck import check_gibbs_convergence

convergence = check_gibbs_convergence(
    trajectory=solution,
    temperature=0.01,
    loss_fn=loss_fn,
    gradient_fn=gradient_fn
)

print("Gibbs Convergence Analysis:")
print(f"  Mean loss (initial): {convergence['mean_initial']:.5f}")
print(f"  Mean loss (final):   {convergence['mean_final']:.5f}")
print(f"  Std dev (final):     {convergence['std_final']:.5f}")
print(f"  Gibbs ratio: {convergence['gibbs_ratio']:.4f}")

if convergence['converged']:
    print("✓ Reached Gibbs equilibrium")
else:
    print("⚠ Did NOT reach equilibrium (more training needed)")

2. estimate-mixing-time

Estimate τ_mix from loss landscape geometry:

from fokker_planck import estimate_mixing_time

# Method 1: From Hessian eigenvalues
hessian = compute_hessian(loss_fn, gradient_fn, current_θ)
eigenvalues = np.linalg.eigvalsh(hessian)
lambda_min = eigenvalues[0]
tau_mix = 1 / lambda_min

print(f"Hessian smallest eigenvalue: {lambda_min:.6f}")
print(f"Estimated mixing time: {tau_mix:.0f} steps")

# Method 2: From empirical convergence rate
convergence_rate = estimate_convergence_rate(trajectory)
tau_mix_empirical = -1 / np.log(convergence_rate)
print(f"Empirical mixing time: {tau_mix_empirical:.0f} steps")

3. measure-kl-divergence

Track distance from Gibbs distribution over time:

from fokker_planck import measure_kl_divergence

kl_history = []
for t in range(0, len(trajectory), skip=10):
    # Empirical distribution at time t
    p_t = estimate_empirical_distribution(
        trajectory[:t],
        bandwidth=0.01
    )

    # Gibbs distribution at equilibrium
    p_inf = gibbs_distribution(loss_fn, temperature=0.01)

    # KL divergence
    kl = compute_kl_divergence(p_t, p_inf)
    kl_history.append((t, kl))

# Plot convergence
import matplotlib.pyplot as plt
times, kls = zip(*kl_history)
plt.semilogy(times, kls)
plt.xlabel("Training steps")
plt.ylabel("D_KL(p_t || p∞)")
plt.title("Convergence to Gibbs Distribution")
plt.show()

4. validate-steady-state

Comprehensive validation that equilibrium has been reached:

from fokker_planck import validate_steady_state

validation = validate_steady_state(
    trajectory=solution,
    loss_fn=loss_fn,
    gradient_fn=gradient_fn,
    temperature=0.01,
    test_set=None  # If provided, checks generalization
)

print("Steady State Validation:")
print(f"  ✓ KL divergence < 0.01: {validation['kl_converged']}")
print(f"  ✓ Gradient norm stable: {validation['grad_stable']}")
print(f"  ✓ Loss variance < threshold: {validation['var_bounded']}")
print(f"  ✓ Gibbs test statistic: {validation['gibbs_stat']:.4f}")

if validation['all_pass']:
    print("\n✅ STEADY STATE VERIFIED")
else:
    print("\n⚠️ STEADY STATE NOT REACHED")
    for check, passed in validation['details'].items():
        status = "✓" if passed else "✗"
        print(f"  {status} {check}")

5. temperature-sensitivity-analysis

Study how different temperatures affect equilibrium:

from fokker_planck import analyze_temperature_sensitivity

analysis = {}
for T in [0.001, 0.01, 0.1]:
    convergence = check_gibbs_convergence(
        trajectory=solutions[T],
        temperature=T,
        loss_fn=loss_fn,
        gradient_fn=gradient_fn
    )

    analysis[T] = {
        'mean_loss': convergence['mean_final'],
        'std_loss': convergence['std_final'],
        'gibbs_ratio': convergence['gibbs_ratio'],
        'converged': convergence['converged']
    }

print("Temperature Sensitivity Analysis:")
for T, metrics in analysis.items():
    print(f"\nT = {T}:")
    print(f"  Mean loss: {metrics['mean_loss']:.5f}")
    print(f"  Std: {metrics['std_loss']:.5f}")
    print(f"  Gibbs ratio: {metrics['gibbs_ratio']:.4f}")
    print(f"  Converged: {metrics['converged']}")

# Pattern:
# Low T → Sharp equilibrium, poor generalization
# High T → Flat equilibrium, better generalization

6. compare-solvers

Compare convergence across different discretization schemes:

from fokker_planck import compare_solver_convergence

solver_comparison = {}
for solver_name, (solution, tracking) in solutions.items():
    validation = validate_steady_state(
        trajectory=solution,
        loss_fn=loss_fn,
        gradient_fn=gradient_fn,
        temperature=0.01
    )

    solver_comparison[solver_name] = {
        'converged': validation['all_pass'],
        'kl_divergence': validation['kl'],
        'steps_to_convergence': tracking['convergence_step'],
        'final_loss': solution.parameters[-1]
    }

print("Solver Convergence Comparison:")
for solver, results in solver_comparison.items():
    print(f"\n{solver}:")
    print(f"  Converged: {results['converged']}")
    print(f"  KL divergence: {results['kl_divergence']:.4f}")
    print(f"  Steps to convergence: {results['steps_to_convergence']}")
    print(f"  Final loss: {results['final_loss']:.5f}")

Integration with Langevin Dynamics Skill

Works hand-in-hand with langevin-dynamics-skill:

langevin-dynamics-skill          fokker-planck-analyzer
      (Analysis)        ←→           (Validation)
- Solves SDE                   - Verifies convergence
- Multiple solvers             - Estimates mixing time
- Instruments noise            - Measures KL divergence
- Compares discretizations     - Validates steady state

Empirical Results from Minimal Test

Logistic Regression (1D)

Temperature T = 0.01, 1000 steps, dt = 0.001:

Initial mean loss: 0.52118
Final mean loss:   0.55465
Final std dev:     0.00656

Gibbs distribution prediction (T = 0.01):
  p(final) / p(initial) = exp(-(0.55465 - 0.52118) / 0.01)
                        = exp(-33.47)
                        ≈ 3.5e-15

Interpretation: Final loss has ~3.5e-15 relative probability
But it's part of the equilibrium distribution!
This validates Fokker-Planck theory ✓

Convergence Pattern

Step 0-100: Rapid convergence toward equilibrium
Step 100-500: Gradual approach to Gibbs
Step 500+: Small fluctuations around steady state

→ Mixing time τ_mix ≈ 100-200 steps for this problem

GF(3) Triad Assignment

Trit Skill Role
-1 fokker-planck-analyzer Validates equilibrium
0 langevin-dynamics-skill Analyzes dynamics
+1 unworld-skill Generates patterns

Conservation: (-1) + (0) + (+1) = 0 ✓

Validation Checklist

  • KL Divergence: DKL(pt || p∞) < ε for small ε
  • Gradient Norm: |∇L| stable and small
  • Loss Variance: Var(L) < threshold
  • Gibbs Test: Observed distribution matches p∞
  • Temperature Control: Different T → different equilibria
  • Solver Consistency: All solvers converge to same distribution

Configuration

# fokker-planck-analyzer.yaml
convergence:
  kl_threshold: 0.01        # Max KL divergence
  grad_norm_threshold: 1e-3 # Max gradient norm
  variance_threshold: 1e-4  # Max loss variance

estimation:
  hessian_method: numerical # or analytical
  eigenvalue_method: eig    # Matrix eigendecomposition
  bandwidth: 0.01           # For density estimation

validation:
  test_set: null            # Optional held-out set
  compute_gibbs_ratio: true # Likelihood ratio test
  plot_convergence: true    # Generate visualizations

Example Workflow

# 1. Run Langevin dynamics
just langevin-solve net=network T=0.01 n_steps=1000

# 2. Check Fokker-Planck convergence
just fokker-check-convergence

# 3. Estimate mixing time
just fokker-estimate-mixing-time

# 4. Measure KL divergence
just fokker-measure-kl

# 5. Validate steady state
just fokker-validate

# 6. Temperature sensitivity
just fokker-temperature-sweep

# 7. Compare different solvers
just fokker-solver-comparison

Related Skills

  • langevin-dynamics-skill (Analysis) - Solves the SDE
  • entropy-sequencer (Layer 5) - Optimizes sequences
  • gay-mcp (Infrastructure) - Deterministic seeding
  • spi-parallel-verify (Verification) - Checks GF(3)

Skill Name: fokker-planck-analyzer Type: Validation / Verification Trit: -1 (MINUS - critical/validating) Key Property: Verifies that Langevin training has reached Gibbs equilibrium Status: ✅ Production Ready Theory: Fokker-Planck PDE, Gibbs distribution, mixing time estimation