The 1cycle policy (fast.ai, OneCycleLR) warms the learning rate up from max_lr / div to max_lr over the first pct_start of training, then anneals it down to max_lr / (div * final_div) with a cosine. Momentum moves the opposite way between max_mom and min_mom.
Implement one_cycle(step, total, max_lr, pct_start=0.3, div=25, final_div=1e4, min_mom=0.85, max_mom=0.95) returning (lr, momentum). Use cosine interpolation in both phases: cos_interp(a, b, p) = b + (a - b) * (1 + cos(pi p)) / 2 for progress p in [0, 1]. The warm-up phase covers steps 0 .. warm where warm = pct_start * total, and the anneal phase covers warm .. total.