Source code for mercurial.hierarchy.transition

"""Level transition operator for constraint propagation between LADDER levels."""

from typing import Optional

import numpy as np

from mercurial.core.patterns import Constraints, Pattern


[docs] class LevelTransitionOperator: """ Implements T_{i→j}[P] = Π_j ◦ Φ_{i→j} ◦ Π_i^{-1}[P] where: - Π_i projects onto level i degrees of freedom - Φ_{i→j} is the constraint propagation map """ def __init__(self, coupling_strength: float = 0.1): self.coupling = coupling_strength
[docs] def project_to_level( self, pattern: Pattern, target_level: int, current_level: Optional[int] = None ) -> np.ndarray: """ Π_j: Project pattern state variables to a different level's dimensionality. Simplified: use linear interpolation/downsampling based on complexity ratio. """ # Estimate current level if not provided if current_level is None: from mercurial.hierarchy.complexity import ComplexityMeasure, LevelClassifier measure = ComplexityMeasure() comp = measure.compute(pattern.V) current_level, _ = LevelClassifier.classify(comp) # Level difference determines scaling factor level_diff = target_level - current_level # Exponential scaling of degrees of freedom (higher levels have more DOF) scale_factor = 2.0**level_diff # heuristic # Flatten pattern flat = pattern.V.flatten() new_size = max(1, int(len(flat) * scale_factor)) if new_size > len(flat): # Upsample: interpolate x_old = np.linspace(0, 1, len(flat)) x_new = np.linspace(0, 1, new_size) projected = np.interp(x_new, x_old, flat) else: # Downsample: take every step step = max(1, len(flat) // new_size) projected = flat[::step][:new_size] return projected
[docs] def constraint_propagation( self, source_state: np.ndarray, target_constraints: Constraints ) -> np.ndarray: """ Φ_{i→j}: Apply constraints from source to target. Simplified: modify target state to satisfy source constraints. """ # Evaluate current constraint violations violations = target_constraints.violation_norm(source_state) if violations == 0: return source_state # Gradient descent to satisfy constraints (simplified) # This is a placeholder – real implementation would use constraint satisfaction new_state = source_state.copy() learning_rate = 0.1 * self.coupling for _ in range(5): grad = np.zeros_like(new_state) # Approximate gradient of constraint violation eps = 1e-6 for i in range(len(new_state)): perturb = np.zeros_like(new_state) perturb[i] = eps v_plus = new_state + perturb v_minus = new_state - perturb v_plus_viol = target_constraints.violation_norm(v_plus) v_minus_viol = target_constraints.violation_norm(v_minus) grad[i] = (v_plus_viol - v_minus_viol) / (2 * eps) new_state -= learning_rate * grad return new_state
[docs] def apply_transition( self, source_pattern: Pattern, target_level: int, target_constraints: Constraints, current_level: Optional[int] = None, ) -> Pattern: """ Apply T_{i→j} to source pattern, producing a pattern at target level. """ # Project to target level's state space projected_state = self.project_to_level(source_pattern, target_level, current_level) # Apply constraint propagation constrained_state = self.constraint_propagation(projected_state, target_constraints) # Create new pattern (simplified stability) return Pattern( constrained_state.reshape(-1, 1), target_constraints, source_pattern.R, label=f"trans_{source_pattern.label}", )