Source code for mercurial.spectral.binding

"""Cross‑modal binding via phase synchronization tags."""

from dataclasses import dataclass
from typing import Dict, List

import numpy as np

from mercurial.spectral.quantum_fields import ModalityField, UnifiedField


[docs] @dataclass class BindingTag: """Synchronization tag linking modalities.""" phase: float frequency: float modalities: List[ModalityField]
[docs] class CrossModalBinding: """ Implements phase‑locking between modalities to create unified percepts. The binding strength between modalities i and j is: B_ij = exp(-|φ_i - φ_j| / φ_coh) * exp(-|ω_i - ω_j| / ω_coh) """
[docs] def __init__(self, phase_coherence: float = 0.5, freq_coherence: float = 10.0): """ Parameters ---------- phase_coherence : float φ_coh – characteristic phase difference for binding. freq_coherence : float ω_coh – characteristic frequency difference for binding (Hz). """ self.phi_coh = phase_coherence self.omega_coh = freq_coherence self.tags: Dict[ModalityField, BindingTag] = {}
[docs] def add_tag( self, modality: ModalityField, phase: float, frequency: float, linked_modalities: List[ModalityField], ): """Add a binding tag for a modality.""" self.tags[modality] = BindingTag(phase, frequency, linked_modalities)
[docs] def binding_strength(self, mod_i: ModalityField, mod_j: ModalityField) -> float: """Compute B_ij.""" if mod_i not in self.tags or mod_j not in self.tags: return 0.0 tag_i = self.tags[mod_i] tag_j = self.tags[mod_j] # Check if they are intended to bind if mod_j not in tag_i.modalities and mod_i not in tag_j.modalities: return 0.0 dphi = abs(tag_i.phase - tag_j.phase) % (2 * np.pi) dphi = min(dphi, 2 * np.pi - dphi) dfreq = abs(tag_i.frequency - tag_j.frequency) phase_factor = np.exp(-dphi / self.phi_coh) freq_factor = np.exp(-dfreq / self.omega_coh) return phase_factor * freq_factor
[docs] def apply_coupling(self, unified_field: UnifiedField, dt: float): """ Couple field amplitudes according to binding strengths. dA_i/dt += Σ_j B_ij (A_j - A_i) """ modalities = list(unified_field.fields.keys()) n = len(modalities) # Compute coupling matrix B = np.zeros((n, n)) for i, mi in enumerate(modalities): for j, mj in enumerate(modalities): B[i, j] = self.binding_strength(mi, mj) # Apply to each field's amplitudes for i, mi in enumerate(modalities): field = unified_field.fields[mi] for j, mj in enumerate(modalities): if i != j and B[i, j] > 0: other_field = unified_field.fields[mj] # Couple the first mode for simplicity diff = other_field.amplitudes[0] - field.amplitudes[0] field.amplitudes[0] += B[i, j] * diff * dt
[docs] def create_percept(self, unified_field: UnifiedField) -> Dict[ModalityField, float]: """ Create a unified percept by applying binding to field strengths. Returns a dictionary of bound field strengths (the percept). """ strengths = unified_field.get_field_strengths() bound_strengths = {} for mi, si in strengths.items(): # Enhance strength if strongly bound to others total_binding = 0.0 for mj in strengths: if mi != mj: total_binding += self.binding_strength(mi, mj) # Binding boosts the perceived strength bound_strengths[mi] = si * (1.0 + total_binding) return bound_strengths