test_decay_models.pyβ’2.48 kB
"""Tests for multiple decay models (power-law, exponential, two-component)."""
from __future__ import annotations
import time
import pytest
from mnemex.config import Config, set_config
from mnemex.core.decay import (
calculate_decay_lambda,
calculate_score,
time_until_threshold,
)
def test_power_law_halflife_matches_config():
now = int(time.time())
cfg = Config(
decay_model="power_law",
pl_alpha=1.1,
pl_halflife_days=3.0,
decay_beta=0.6,
)
set_config(cfg)
# With current_score = 1.0 and threshold=0.5, time_until_threshold ~= half-life
remaining = time_until_threshold(
current_score=1.0,
threshold=0.5,
last_used=now,
)
assert remaining is not None
assert remaining == pytest.approx(3 * 86400, rel=0.2)
def test_power_law_heavier_tail_than_exponential():
now = int(time.time())
days = 21
dt = days * 86400
# Configure power-law 3-day half-life
cfg = Config(decay_model="power_law", pl_alpha=1.1, pl_halflife_days=3.0, decay_beta=0.6)
set_config(cfg)
# Power-law score at dt
s_pl = calculate_score(use_count=1, last_used=now - dt, strength=1.0, now=now, beta=0.6)
# Exponential score with 3-day half-life
lam = calculate_decay_lambda(3.0)
s_exp = calculate_score(
use_count=1,
last_used=now - dt,
strength=1.0,
now=now,
lambda_=lam, # force exponential path
beta=0.6,
)
assert s_pl > s_exp # power-law should retain more at long times
def test_two_component_limits_match_single_exponential():
now = int(time.time())
lam_3d = calculate_decay_lambda(3.0)
lam_7d = calculate_decay_lambda(7.0)
# w=1.0 => effectively single exponential with fast lambda
cfg_fast = Config(
decay_model="two_component",
tc_lambda_fast=lam_3d,
tc_lambda_slow=lam_7d,
tc_weight_fast=1.0,
decay_beta=0.6,
)
set_config(cfg_fast)
rem_fast = time_until_threshold(1.0, 0.5, now)
assert rem_fast == pytest.approx(3 * 86400, rel=0.2)
# w=0.0 => effectively single exponential with slow lambda
cfg_slow = Config(
decay_model="two_component",
tc_lambda_fast=lam_3d,
tc_lambda_slow=lam_7d,
tc_weight_fast=0.0,
decay_beta=0.6,
)
set_config(cfg_slow)
rem_slow = time_until_threshold(1.0, 0.5, now)
assert rem_slow == pytest.approx(7 * 86400, rel=0.2)