From 242e8d76624e128cd149f17137622a02967bcd74 Mon Sep 17 00:00:00 2001 From: ishiko Date: Fri, 20 Sep 2024 01:07:07 +1000 Subject: [PATCH] Fix/stability not restrict maximun and minimun (#126) --- __tests__/FSRSV5.test.ts | 2 +- package.json | 2 +- src/fsrs/algorithm.ts | 36 +++++++++++++++++++++--------------- src/fsrs/default.ts | 2 +- src/fsrs/help.ts | 4 ++++ 5 files changed, 28 insertions(+), 18 deletions(-) diff --git a/__tests__/FSRSV5.test.ts b/__tests__/FSRSV5.test.ts index b7380d98..9ba851ac 100644 --- a/__tests__/FSRSV5.test.ts +++ b/__tests__/FSRSV5.test.ts @@ -166,7 +166,7 @@ describe('get retrievability', () => { let card = createEmptyCard() let now = new Date() let i = 0 - while (i < 10 ** 3) { + while (i < 5) { card = fsrs.next(card, now, Rating.Again).card now = card.due i++ diff --git a/package.json b/package.json index 0507a4ce..abff1d1b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ts-fsrs", - "version": "4.3.0", + "version": "4.3.1", "description": "ts-fsrs is a versatile package based on TypeScript that supports ES modules, CommonJS, and UMD. It implements the Free Spaced Repetition Scheduler (FSRS) algorithm, enabling developers to integrate FSRS into their flashcard applications to enhance the user learning experience.", "main": "dist/index.cjs", "umd": "dist/index.umd.js", diff --git a/src/fsrs/algorithm.ts b/src/fsrs/algorithm.ts index f1a772e2..a07c6127 100644 --- a/src/fsrs/algorithm.ts +++ b/src/fsrs/algorithm.ts @@ -1,7 +1,7 @@ import { generatorParameters } from './default' import { FSRSParameters, Grade, Rating } from './models' import type { int } from './types' -import { get_fuzz_range } from './help' +import { clamp, get_fuzz_range } from './help' import { alea } from './alea' /** @@ -213,15 +213,17 @@ export class FSRSAlgorithm { next_recall_stability(d: number, s: number, r: number, g: Grade): number { const hard_penalty = Rating.Hard === g ? this.param.w[15] : 1 const easy_bound = Rating.Easy === g ? this.param.w[16] : 1 - return +( + return +clamp( s * - (1 + - Math.exp(this.param.w[8]) * - (11 - d) * - Math.pow(s, -this.param.w[9]) * - (Math.exp((1 - r) * this.param.w[10]) - 1) * - hard_penalty * - easy_bound) + (1 + + Math.exp(this.param.w[8]) * + (11 - d) * + Math.pow(s, -this.param.w[9]) * + (Math.exp((1 - r) * this.param.w[10]) - 1) * + hard_penalty * + easy_bound), + 0.01, + 36500.0 ).toFixed(8) } @@ -234,11 +236,13 @@ export class FSRSAlgorithm { * @return {number} S^\prime_f new stability after forgetting */ next_forget_stability(d: number, s: number, r: number): number { - return +( + return +clamp( this.param.w[11] * - Math.pow(d, -this.param.w[12]) * - (Math.pow(s + 1, this.param.w[13]) - 1) * - Math.exp((1 - r) * this.param.w[14]) + Math.pow(d, -this.param.w[12]) * + (Math.pow(s + 1, this.param.w[13]) - 1) * + Math.exp((1 - r) * this.param.w[14]), + 0.01, + 36500.0 ).toFixed(8) } @@ -249,8 +253,10 @@ export class FSRSAlgorithm { * @param {Grade} g Grade (Rating[0.again,1.hard,2.good,3.easy]) */ next_short_term_stability(s: number, g: Grade): number { - return +( - s * Math.exp(this.param.w[17] * (g - 3 + this.param.w[18])) + return +clamp( + s * Math.exp(this.param.w[17] * (g - 3 + this.param.w[18])), + 0.01, + 36500.0 ).toFixed(8) } diff --git a/src/fsrs/default.ts b/src/fsrs/default.ts index 6c5fb975..f727a9ec 100644 --- a/src/fsrs/default.ts +++ b/src/fsrs/default.ts @@ -11,7 +11,7 @@ export const default_w = [ export const default_enable_fuzz = false export const default_enable_short_term = true -export const FSRSVersion: string = 'v4.3.0 using FSRS V5.0' +export const FSRSVersion: string = 'v4.3.1 using FSRS V5.0' export const generatorParameters = ( props?: Partial diff --git a/src/fsrs/help.ts b/src/fsrs/help.ts index 1a2839b8..8d63eda4 100644 --- a/src/fsrs/help.ts +++ b/src/fsrs/help.ts @@ -187,3 +187,7 @@ export function get_fuzz_range( min_ivl = Math.min(min_ivl, max_ivl) return { min_ivl, max_ivl } } + +export function clamp(value: number, min: number, max: number): number { + return Math.min(Math.max(value, min), max) +}