Resonance¶
emotional_memory.resonance.ResonanceConfig
¶
Bases: BaseModel
Parameters for resonance link construction and spreading activation.
candidate_multiplier: int = 3
class-attribute
instance-attribute
¶
Pre-filter multiplier for encode-side resonance building.
When the store has more than max_links * candidate_multiplier entries,
search_by_embedding is used to narrow candidates before scoring, keeping
resonance-link construction sub-linear in store size.
causal_semantic_threshold: float = Field(default=0.6, ge=0.0, le=1.0)
class-attribute
instance-attribute
¶
Minimum semantic similarity for causal link classification.
causal_temporal_threshold: float = Field(default=0.7, ge=0.0, le=1.0)
class-attribute
instance-attribute
¶
Minimum temporal proximity for causal link classification.
contrastive_temporal_threshold: float = Field(default=0.5, ge=0.0, le=1.0)
class-attribute
instance-attribute
¶
Minimum temporal proximity for contrastive link classification.
contrastive_valence_threshold: float = Field(default=1.0, ge=0.0, le=2.0)
class-attribute
instance-attribute
¶
Minimum absolute valence difference for contrastive link classification.
hebbian_increment: float = Field(default=0.05, ge=0.0, le=0.5)
class-attribute
instance-attribute
¶
Strength increment applied to links between co-retrieved memories.
"Neurons that fire together wire together" (Hebb, 1949). Set to 0.0 to disable Hebbian strengthening.
max_links: int = 5
class-attribute
instance-attribute
¶
Maximum resonance links per memory (both forward and backward).
propagation_hops: int = Field(default=2, ge=1, le=5)
class-attribute
instance-attribute
¶
Number of hops for spreading activation (Collins & Loftus, 1975).
1 = direct neighbours only (one-hop check, minimal overhead). 2 = two hops, capturing indirect associations with strength decay. Higher values reach more distant associations but with diminishing returns since each hop multiplies by link strength (< 1.0).
temporal_half_life_seconds: float = Field(default=3600.0, gt=0)
class-attribute
instance-attribute
¶
Half-life for temporal proximity decay. Must be positive.
threshold: float = 0.3
class-attribute
instance-attribute
¶
Minimum composite resonance score to create a link.
emotional_memory.resonance.build_resonance_links(new_memory: Memory, candidates: list[Memory], config: ResonanceConfig) -> list[ResonanceLink]
¶
Build resonance links from new_memory to the most resonant candidates.
Excludes self-links. Returns up to config.max_links links above threshold, sorted by strength descending.
Note: This function only builds forward links (new_memory → candidate). The caller is responsible for creating the corresponding backward links on each target memory (candidate → new_memory) to maintain a bidirectional associative network.
Source code in src/emotional_memory/resonance.py
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 | |
emotional_memory.resonance.spreading_activation(seed_ids: set[str], candidates: list[Memory], hops: int = 2) -> dict[str, float]
¶
Compute activation levels via spreading activation from seed memories.
Collins & Loftus (1975): activation spreads from seed nodes through associative links with multiplicative strength decay at each hop. Because each link has strength < 1.0, activation diminishes naturally with distance — no explicit hop-discount factor is needed.
The adjacency is built from every memory's stored resonance_links, which include both forward (new→old) and backward (old→new) links when bidirectional link creation is used at encode time.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
seed_ids
|
set[str]
|
IDs of initially activated memories (e.g. Pass 1 top-k). |
required |
candidates
|
list[Memory]
|
All candidate memories in the retrieval pool. |
required |
hops
|
int
|
Number of propagation steps. 1 = direct neighbours only. |
2
|
Returns:
| Type | Description |
|---|---|
dict[str, float]
|
Mapping memory_id → activation level in (0, 1] for non-seed memories |
dict[str, float]
|
that were reached by activation spreading. Seeds are excluded from |
dict[str, float]
|
the returned map (they are already in the top-k). |
Source code in src/emotional_memory/resonance.py
emotional_memory.resonance.hebbian_strengthen(memory: Memory, co_retrieved_ids: set[str], increment: float) -> list[ResonanceLink]
¶
Strengthen links to co-retrieved memories (Hebb, 1949).
"Neurons that fire together wire together" — when two linked memories are both retrieved in the same query, their associative link is incrementally strengthened up to a maximum of 1.0.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
memory
|
Memory
|
The memory whose links are being updated. |
required |
co_retrieved_ids
|
set[str]
|
IDs of the other memories retrieved in the same query (excluding the memory itself). |
required |
increment
|
float
|
Strength increment per co-retrieval event. |
required |
Returns:
| Type | Description |
|---|---|
list[ResonanceLink]
|
Updated resonance_links list. Returns the original list unchanged |
list[ResonanceLink]
|
if no links were strengthened (avoids unnecessary copies). |
Source code in src/emotional_memory/resonance.py
emotional_memory.resonance.temporal_proximity(t1: datetime, t2: datetime, half_life_seconds: float = 3600.0) -> float
¶
Exponential decay of temporal proximity.
proximity = exp(-|delta_t| * ln(2) / half_life) Returns 1.0 for simultaneous events, approaches 0 for distant events.