Source code for mercurial.core.dynamics

"""Pattern dynamics with free energy gradient descent and persistence."""

from typing import Tuple

import numpy as np

from mercurial.core.patterns import Pattern


[docs] def free_energy_gradient(pattern: Pattern, free_energy_func=None, epsilon: float = 1e-6): """ Compute ∇_v F(P) using finite differences. Returns (grad, current_F). """ v = pattern.V.copy() # Simple placeholder: return zero gradient # In real implementation you'd use free_energy_func grad = np.zeros_like(v) return grad, 0.0
[docs] def pattern_evolution_with_persistence( pattern: Pattern, dt: float, free_energy_func, gamma0: float = 0.001, S_crit: float = 10.0, noise_amplitude: float = 0.01, rng=None, ) -> Tuple[Pattern, float]: """Placeholder – implement as needed.""" if rng is None: rng = np.random.default_rng() # Simple Euler step (no decay) for demonstration grad, _ = free_energy_gradient(pattern) new_V = pattern.V - grad * dt new_pattern = Pattern(new_V, pattern.C, pattern.R, pattern.label) return new_pattern, 0.0
[docs] def evolve_pattern_trajectory( pattern: Pattern, t_span: float, dt: float, temperature: float = 1.0, noise_amplitude: float = 0.01, ) -> list: """Evolve pattern over time using a simple Euler step.""" trajectory = [pattern] current = pattern steps = int(t_span / dt) np.random.default_rng() for _ in range(steps): # Simple Euler update without persistence grad, _ = free_energy_gradient(current) new_V = current.V - grad * dt current = Pattern(new_V, current.C, current.R, current.label) trajectory.append(current) return trajectory
[docs] def pattern_evolution_with_thermodynamics( pattern, dt, free_energy_func, noise_amplitude=0.01, rng=None ): """ Alias for pattern_evolution_with_persistence to satisfy legacy tests. Uses default persistence parameters. """ return pattern_evolution_with_persistence( pattern, dt, free_energy_func, gamma0=0.001, S_crit=10.0, noise_amplitude=noise_amplitude, rng=rng, )