Preserve observed progression steps in exercise forecasts

This commit is contained in:
Peter Stockings
2026-09-06 22:46:07 +10:00
parent dc0f41cd27
commit 9612d322eb
5 changed files with 58 additions and 8 deletions
+9 -1
View File
@@ -134,11 +134,19 @@ class TransitionModel:
probabilities = np.exp(-distance) * 0.5 ** (self.age / 8)
increase = self.dw > 0.01
decrease = self.dw < -0.01
# Preserve the observed mix of increments; the mode alone can turn
# alternating small/large plate jumps into permanently tiny steps.
ordinary_increase = self.dw <= self.source_w * 0.15
probabilities[:, increase & ~ordinary_increase] = 0
probabilities[:, increase] *= (reps >= self.profile['ceiling'])[:, None]
# A rep-building transition is not evidence of stalling at the ceiling.
# Exclude it there instead of clipping its gain into an artificial repeat.
rep_gain = (abs(self.dw) < 0.01) & (self.dr > 0)
probabilities[:, rep_gain] *= (reps < self.profile['ceiling'])[:, None]
# Calendar horizons beyond ~12 sessions are scenarios. Damp the rate of
# further load advances rather than extrapolating beginner gains forever.
probabilities[:, increase] *= 0.98 ** max(0, step - 12)
delta_w = np.where(increase, self.profile['increment'], self.dw)
delta_w = self.dw
delta_w = np.maximum(delta_w, -weights[:, None] * 0.15)
out_w = np.maximum(weights[:, None] + delta_w, 0.5)
out_r = np.clip(reps[:, None] + self.dr, 1, 20)