diff --git a/__tests__/FSRSV5.test.ts b/__tests__/FSRSV5.test.ts index b7380d9..9ba851a 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 0507a4c..abff1d1 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 f1a772e..a07c612 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 6c5fb97..f727a9e 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 1a2839b..8d63eda 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) +}