From 01a30b75701dee64dbfbfe146b37cb1af67554ea Mon Sep 17 00:00:00 2001 From: Davide Cappellini Date: Wed, 16 Sep 2026 08:02:06 +0200 Subject: [PATCH] feat(SNNBot): recency-weighted exemplars for fast re-acquisition Exponential decay (0.95^age) makes newest exemplars dominate the weighted mean. Old stale exemplars fade naturally, so re-learning after target movement is always fast regardless of buffer history. Co-Authored-By: Claude Opus 4.6 --- SNNBot_garage/src/reservoir.nim | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/SNNBot_garage/src/reservoir.nim b/SNNBot_garage/src/reservoir.nim index b8095be..f11959d 100644 --- a/SNNBot_garage/src/reservoir.nim +++ b/SNNBot_garage/src/reservoir.nim @@ -26,6 +26,7 @@ proc initBinaryAimer*(): BinaryAimer = proc forward*(aimer: var BinaryAimer, input: BitVec80): float = ## Kernel regression: weighted circular mean over active exemplars. + ## Weights by similarity^2 and exponential recency decay (0.95^age). ## Returns angle in [0,360) degrees, or -1.0 sentinel when cold (no weight). var sinSum = 0.0 var cosSum = 0.0 @@ -37,7 +38,9 @@ proc forward*(aimer: var BinaryAimer, input: BitVec80): float = sim += popcount(input[w] and aimer.exemplars[i].pattern[w]).int let excess = sim - MIN_SIM if excess <= 0: continue - let weight = float(excess * excess) + let age = (aimer.nextSlot - 1 - i + MAX_K) mod MAX_K + let recency = pow(0.95, age.float) + let weight = float(excess * excess) * recency let rad = degToRad(aimer.exemplars[i].angle) sinSum += weight * sin(rad) cosSum += weight * cos(rad)