"""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