Positional CMR

Position-based encoding for repeated items

Positional CMR addresses experiments where items repeat within a study list. Instead of encoding items by their identity, it encodes them by their serial position, giving each presentation of a repeated item a distinct contextual trace.

The Problem with Repeated Items

In standard CMR, each item has a single representation. When an item repeats:

  • At encoding: The same item representation integrates with the current (different) context
  • At retrieval: The item’s context is a blend of both presentations

This blending can’t explain why people sometimes recall the first presentation but not the second, or show different spacing effects depending on which presentation they retrieve.

The Positional Solution

Positional CMR replaces item-based encoding with position-based encoding:

Aspect Standard CMR Positional CMR
Feature layer Item identities Serial positions
A repeated item One representation Separate trace per presentation
Recallability Per-item Per-position
Context reinstatement One context Weighted blend of positions

Mathematical Specification

Encoding

When studying the item at position \(i\):

1. Position representation: \[\mathbf{p}_i = \mathbf{e}_i\]

A one-hot vector for position \(i\), not the item’s identity.

2. Context input: \[\mathbf{c}^{IN}_i = M^{FC} \mathbf{p}_i\]

3. Form associations: \[\Delta M^{FC}_{ij} = \gamma \mathbf{p}_i \mathbf{c}_j\] \[\Delta M^{CF}_{ij} = \phi_i \mathbf{c}_j \mathbf{p}_i\]

The item’s identity is tracked separately: studied[position] = item_id.

Retrieval

When item \(k\) is recalled:

1. Find matching positions: \[\text{positions}_k = \{i : \text{studied}[i] = k\}\]

2. Compute position activations: \[a_i = (M^{CF} \mathbf{c})_i \cdot \mathbf{1}[\text{recallable}[i]]\]

3. Weight for context reinstatement:

Multiple positions may hold the same item. Their relative activations determine the context retrieved:

\[\mathbf{p}_{cue} = \frac{\sum_{i \in \text{positions}_k} a_i \mathbf{p}_i}{\sum_{i \in \text{positions}_k} a_i}\]

Raised to power mfc_sensitivity:

\[\mathbf{p}'_{cue} = \text{power\_scale}(\mathbf{p}_{cue}, \tau_{mfc})\]

4. Reinstate context: \[\mathbf{c}^{IN} = M^{FC} \mathbf{p}'_{cue}\]

Item Probabilities

Item probability pools across all positions:

\[P(item=k) = \frac{\sum_{i : \text{studied}[i]=k} a_i^{\tau}}{\sum_j a_j^{\tau}}\]

Additional Parameters

Parameter Symbol Description
mfc_sensitivity \(\tau_{mfc}\) Controls context reinstatement weighting. Higher = stronger trace wins

Usage

Code
from jaxcmr.models.positional_cmr import CMR

params = {
    "encoding_drift_rate": 0.5,
    "start_drift_rate": 0.5,
    "recall_drift_rate": 0.5,
    "learning_rate": 0.5,
    "primacy_scale": 2.0,
    "primacy_decay": 0.8,
    "shared_support": 0.05,
    "item_support": 0.25,
    "choice_sensitivity": 0.6,
    "mfc_sensitivity": 3.0,  # New parameter
    "stop_probability_scale": 0.05,
    "stop_probability_growth": 0.2,
    "learn_after_context_update": True,
    "allow_repeated_recalls": False,
}

model = CMR(list_length=16, parameters=params)

# Study a list with repetitions: [1, 2, 3, 1, 4, 2, ...]
for item in [1, 2, 3, 1, 4, 2, 5, 6, 7, 8]:
    model = model.experience(item)

# Items 1 and 2 now have two traces each (at different positions)

When To Use

Use Positional CMR when:

  • Items repeat within a study list
  • You want to model which presentation is recalled
  • Spacing effects matter (first vs. second presentation)
  • Source memory is relevant (when was this presented?)

Use standard CMR when:

  • Items are unique within each list
  • Repetitions aren’t theoretically important
  • You want a simpler model

Theoretical Implications

Positional encoding assumes:

  1. Position is primary: Memory traces are fundamentally organized by when things happened
  2. Identity is secondary: Item identity is bound to position, not the reverse
  3. Selective retrieval: People can selectively access specific presentations

This contrasts with item-based encoding where repeated presentations strengthen a single trace.

Implementation Notes

The studied array tracks which item was presented at each position:

Code
self.studied = jnp.zeros(list_length, dtype=int)
# After studying item 5 at position 3:
self.studied[3] = 5  # (using 1-indexed item IDs)

Recallability is tracked per-position:

Code
self.recallable = jnp.zeros(list_length, dtype=bool)
# When item 5 (at positions 3 and 7) is recalled:
# All matching positions become non-recallable
self.recallable = self.recallable * (self.studied != 5)