Skip to content

Commit

Permalink
Feat/update to FSRS-4.5 (#568)
Browse files Browse the repository at this point in the history
  • Loading branch information
L-M-Sherlock authored Dec 26, 2023
1 parent 321d0f8 commit 97b8522
Show file tree
Hide file tree
Showing 4 changed files with 409 additions and 407 deletions.
735 changes: 363 additions & 372 deletions fsrs4anki_optimizer.ipynb

Large diffs are not rendered by default.

23 changes: 13 additions & 10 deletions fsrs4anki_scheduler.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// FSRS4Anki v4.10.0 Scheduler Qt6
// FSRS4Anki v4.11.0 Scheduler Qt6
set_version();
// The latest version will be released on https://github.com/open-spaced-repetition/fsrs4anki/releases/latest

Expand Down Expand Up @@ -74,7 +74,7 @@ if (deck_name = get_deckname()) {
}
}
// Arrange the deckParams of sub-decks in front of their parent decks.
deckParams.sort(function(a, b) {
deckParams.sort(function (a, b) {
return -a.deckName.localeCompare(b.deckName);
});
for (let i = 0; i < deckParams.length; i++) {
Expand All @@ -94,8 +94,8 @@ if (Object.keys(params).length === 0) {
var w = params["w"];
var requestRetention = params["requestRetention"];
var maximumInterval = params["maximumInterval"];
// auto-calculate intervalModifier
const intervalModifier = 9 * (1 / requestRetention - 1);
const DECAY = -0.5;
const FACTOR = 0.9 ** (1 / DECAY) - 1;
// global fuzz factor for all ratings.
const fuzz_factor = set_fuzz_factor();
const ratings = {
Expand Down Expand Up @@ -138,7 +138,7 @@ if (is_new()) {
const interval = states.current.normal?.review.elapsedDays ? states.current.normal.review.elapsedDays : states.current.filtered.rescheduling.originalState.review.elapsedDays;
const last_d = customData.again.d;
const last_s = customData.again.s;
const retrievability = Math.pow(1 + interval / (9 * last_s), -1)
const retrievability = forgetting_curve(interval, last_s);
if (display_memory_state) {
fsrs_status.innerHTML += "<br>D: " + last_d + "<br>S: " + last_s + "<br>R: " + (retrievability * 100).toFixed(2) + "%";
}
Expand Down Expand Up @@ -182,8 +182,11 @@ function apply_fuzz(ivl) {
}
return Math.floor(fuzz_factor * (max_ivl - min_ivl + 1) + min_ivl);
}
function forgetting_curve(elpased_days, stability) {
return Math.pow(1 + FACTOR * elpased_days / stability, DECAY);
}
function next_interval(stability) {
const new_interval = apply_fuzz(stability * intervalModifier);
const new_interval = apply_fuzz(stability / FACTOR * Math.pow(requestRetention, (1 / DECAY) - 1));
return Math.min(Math.max(Math.round(new_interval), 1), maximumInterval);
}
function next_difficulty(d, rating) {
Expand All @@ -204,9 +207,9 @@ function next_recall_stability(d, s, r, rating) {
easyBonus)).toFixed(2);
}
function next_forget_stability(d, s, r) {
return +Math.min(w[11] *
Math.pow(d, -w[12]) *
(Math.pow(s + 1, w[13]) - 1) *
return +Math.min(w[11] *
Math.pow(d, -w[12]) *
(Math.pow(s + 1, w[13]) - 1) *
Math.exp((1 - r) * w[14]), s).toFixed(2);
}
function init_states() {
Expand Down Expand Up @@ -292,7 +295,7 @@ function is_empty() {
return !customData.again.d | !customData.again.s | !customData.hard.d | !customData.hard.s | !customData.good.d | !customData.good.s | !customData.easy.d | !customData.easy.s;
}
function set_version() {
const version = "v4.10.0";
const version = "v4.11.0";
customData.again.v = version;
customData.hard.v = version;
customData.good.v = version;
Expand Down
15 changes: 9 additions & 6 deletions fsrs4anki_scheduler_qt5.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// FSRS4Anki v4.10.0 Scheduler Qt5
// FSRS4Anki v4.11.0 Scheduler Qt5
set_version();
// The latest version will be released on https://github.com/open-spaced-repetition/fsrs4anki/releases/latest

Expand Down Expand Up @@ -96,8 +96,8 @@ if (Object.keys(params).length === 0) {
const w = params["w"];
const requestRetention = params["requestRetention"];
const maximumInterval = params["maximumInterval"];
// auto-calculate intervalModifier
const intervalModifier = 9 * (1 / requestRetention - 1);
const DECAY = -0.5;
const FACTOR = 0.9 ** (1 / DECAY) - 1;
// global fuzz factor for all ratings.
const fuzz_factor = set_fuzz_factor();
const ratings = {
Expand Down Expand Up @@ -143,7 +143,7 @@ if (is_new()) {
const interval = (_states$current$norma = states.current.normal) !== null && _states$current$norma !== void 0 && _states$current$norma.review.elapsedDays ? states.current.normal.review.elapsedDays : states.current.filtered.rescheduling.originalState.review.elapsedDays;
const last_d = customData.again.d;
const last_s = customData.again.s;
const retrievability = Math.pow(1 + interval / (9 * last_s), -1);
const retrievability = forgetting_curve(interval, last_s);
if (display_memory_state) {
fsrs_status.innerHTML += "<br>D: " + last_d + "<br>S: " + last_s + "<br>R: " + (retrievability * 100).toFixed(2) + "%";
}
Expand Down Expand Up @@ -188,8 +188,11 @@ function apply_fuzz(ivl) {
}
return Math.floor(fuzz_factor * (max_ivl - min_ivl + 1) + min_ivl);
}
function forgetting_curve(elpased_days, stability) {
return Math.pow(1 + FACTOR * elpased_days / stability, DECAY);
}
function next_interval(stability) {
const new_interval = apply_fuzz(stability * intervalModifier);
const new_interval = apply_fuzz(stability / FACTOR * Math.pow(requestRetention, (1 / DECAY) - 1));
return Math.min(Math.max(Math.round(new_interval), 1), maximumInterval);
}
function next_difficulty(d, rating) {
Expand Down Expand Up @@ -301,7 +304,7 @@ function is_empty() {
return !customData.again.d | !customData.again.s | !customData.hard.d | !customData.hard.s | !customData.good.d | !customData.good.s | !customData.easy.d | !customData.easy.s;
}
function set_version() {
const version = "v4.10.0";
const version = "v4.11.0";
customData.again.v = version;
customData.hard.v = version;
customData.good.v = version;
Expand Down
43 changes: 24 additions & 19 deletions fsrs4anki_simulator.ipynb

Large diffs are not rendered by default.

0 comments on commit 97b8522

Please sign in to comment.