Source code for mercurial.impressions.dynamic_formation
"""Dynamic impression formation with emotional salience, repetition, and attention."""
from typing import Tuple
[docs]
class EmotionalSalience:
"""Dynamic emotional salience ℰ(t)."""
def __init__(
self, initial: float = 0.0, decay_rate: float = 0.1, arousal_sensitivity: float = 1.0
):
self.value = initial
self.decay = decay_rate
self.sensitivity = arousal_sensitivity
[docs]
def update(self, dt: float, arousal: float) -> float:
"""dℰ/dt = -α_ℰ ℰ + β_ℰ * arousal."""
dE_dt = -self.decay * self.value + self.sensitivity * arousal
self.value += dE_dt * dt
self.value = max(0.0, min(1.0, self.value)) # clamp to [0,1]
return self.value
[docs]
class RepetitionCounter:
"""Dynamic repetition strength 𝒮(t)."""
def __init__(
self, initial: float = 0.0, accumulation_rate: float = 0.1, forgetting_rate: float = 0.05
):
self.value = initial
self.accumulation = accumulation_rate
self.forgetting = forgetting_rate
[docs]
def update(self, dt: float, event_occurred: bool) -> float:
"""d𝒮/dt = +γ_acc (if event) - γ_forget * 𝒮."""
dS_dt = -self.forgetting * self.value
if event_occurred:
dS_dt += self.accumulation
self.value += dS_dt * dt
self.value = max(0.0, min(1.0, self.value))
return self.value
[docs]
class AttentionFocus:
"""Dynamic attention 𝒜(t)."""
def __init__(
self,
initial: float = 0.0,
baseline: float = 0.1,
focus_rate: float = 0.2,
distract_rate: float = 0.1,
):
self.value = initial
self.baseline = baseline
self.focus_rate = focus_rate
self.distract_rate = distract_rate
[docs]
def update(self, dt: float, focused: bool) -> float:
"""d𝒜/dt = +γ_focus (if focused) - γ_distract (𝒜 - baseline)."""
dA_dt = -self.distract_rate * (self.value - self.baseline)
if focused:
dA_dt += self.focus_rate * (1.0 - self.value)
self.value += dA_dt * dt
self.value = max(0.0, min(1.0, self.value))
return self.value
[docs]
class DynamicImpressionFormation:
"""
Implements dI/dt = α * ℰ * 𝒮 * 𝒜 - γ I.
Where ℰ, 𝒮, 𝒜 evolve dynamically based on context.
"""
def __init__(self, alpha_form: float = 0.1, gamma_form: float = 0.01):
self.alpha = alpha_form
self.gamma = gamma_form
self.salience = EmotionalSalience()
self.repetition = RepetitionCounter()
self.attention = AttentionFocus()
self.impression_intensity = 0.0
[docs]
def update(
self, dt: float, arousal: float, event_occurred: bool, focused: bool
) -> Tuple[float, dict]:
"""
Update all dynamic variables and impression intensity.
Returns
-------
intensity : float
Current impression intensity I(t).
state : dict
Current values of ℰ, 𝒮, 𝒜 for monitoring.
"""
# Update dynamic variables
E = self.salience.update(dt, arousal)
S = self.repetition.update(dt, event_occurred)
A = self.attention.update(dt, focused)
# Impression formation ODE
dI_dt = self.alpha * E * S * A - self.gamma * self.impression_intensity
self.impression_intensity += dI_dt * dt
self.impression_intensity = max(0.0, self.impression_intensity)
return self.impression_intensity, {"salience": E, "repetition": S, "attention": A}
[docs]
def reset(self):
"""Reset all state variables."""
self.salience.value = 0.0
self.repetition.value = 0.0
self.attention.value = 0.0
self.impression_intensity = 0.0