mirror of
https://github.com/ankitects/anki.git
synced 2025-09-25 01:06:35 -04:00
rename sm2 retention to historical retention (#3101)
* rename sm2 retention to historical retention * ninja format * keep sm2_retention in DeckConfSchema11 * update wording * Update schema11.rs
This commit is contained in:
parent
c1877f9df6
commit
15506328e9
8 changed files with 50 additions and 34 deletions
|
@ -350,7 +350,7 @@ deck-config-ignore-before = Ignore reviews before
|
||||||
deck-config-optimize-all-tip = You can optimize all presets at once by using the dropdown button next to "Save".
|
deck-config-optimize-all-tip = You can optimize all presets at once by using the dropdown button next to "Save".
|
||||||
deck-config-evaluate-button = Evaluate
|
deck-config-evaluate-button = Evaluate
|
||||||
deck-config-desired-retention = Desired retention
|
deck-config-desired-retention = Desired retention
|
||||||
deck-config-sm2-retention = SM2 retention
|
deck-config-historical-retention = Historical Retention
|
||||||
deck-config-smaller-is-better = Smaller numbers indicate a better fit to your review history.
|
deck-config-smaller-is-better = Smaller numbers indicate a better fit to your review history.
|
||||||
deck-config-steps-too-large-for-fsrs = When FSRS is enabled, steps of 1 day or more are not recommended.
|
deck-config-steps-too-large-for-fsrs = When FSRS is enabled, steps of 1 day or more are not recommended.
|
||||||
deck-config-get-params = Get Params
|
deck-config-get-params = Get Params
|
||||||
|
@ -377,11 +377,19 @@ deck-config-desired-retention-tooltip =
|
||||||
less frequently, and you will forget more of them. Be conservative when adjusting this - higher
|
less frequently, and you will forget more of them. Be conservative when adjusting this - higher
|
||||||
values will greatly increase your workload, and lower values can be demoralizing when you forget
|
values will greatly increase your workload, and lower values can be demoralizing when you forget
|
||||||
a lot of material.
|
a lot of material.
|
||||||
deck-config-sm2-retention-tooltip =
|
deck-config-historical-retention-tooltip =
|
||||||
If your actual retention before switching to FSRS was significantly different from 0.9, adjusting
|
When some of your review history is missing, FSRS needs to fill in the gaps. By default, it will
|
||||||
this value will allow Anki to better estimate your memory state when it encounters cards that are
|
assume that when you did those old reviews, you remembered 90% of the material. If your old retention
|
||||||
missing review logs. Since review logs typically won't be missing unless you explicitly deleted them
|
was appreciably higher or lower than 90%, adjusting this option will allow FSRS to better approximate
|
||||||
to free up space, most users will not need to adjust this.
|
the missing reviews.
|
||||||
|
|
||||||
|
Your review history may be incomplete for two reasons:
|
||||||
|
1. Because you've used the 'ignore reviews before' option.
|
||||||
|
2. Because you previously deleted review logs to free up space, or imported material from a different
|
||||||
|
SRS program.
|
||||||
|
|
||||||
|
The latter is quite rare, so unless you've used the former option, you probably don't need to adjust
|
||||||
|
this setting.
|
||||||
deck-config-weights-tooltip =
|
deck-config-weights-tooltip =
|
||||||
FSRS parameters affect how cards are scheduled. Anki will start with default parameters. Once
|
FSRS parameters affect how cards are scheduled. Anki will start with default parameters. Once
|
||||||
you've accumulated 1000+ reviews, you can use the option below to optimize the parameters to best
|
you've accumulated 1000+ reviews, you can use the option below to optimize the parameters to best
|
||||||
|
|
|
@ -157,7 +157,7 @@ message DeckConfig {
|
||||||
string ignore_revlogs_before_date = 46;
|
string ignore_revlogs_before_date = 46;
|
||||||
// used for fsrs_reschedule in the past
|
// used for fsrs_reschedule in the past
|
||||||
reserved 39;
|
reserved 39;
|
||||||
float sm2_retention = 40;
|
float historical_retention = 40;
|
||||||
string weight_search = 45;
|
string weight_search = 45;
|
||||||
|
|
||||||
bytes other = 255;
|
bytes other = 255;
|
||||||
|
|
|
@ -75,7 +75,7 @@ const DEFAULT_DECK_CONFIG_INNER: DeckConfigInner = DeckConfigInner {
|
||||||
fsrs_weights: vec![],
|
fsrs_weights: vec![],
|
||||||
desired_retention: 0.9,
|
desired_retention: 0.9,
|
||||||
other: Vec::new(),
|
other: Vec::new(),
|
||||||
sm2_retention: 0.9,
|
historical_retention: 0.9,
|
||||||
weight_search: String::new(),
|
weight_search: String::new(),
|
||||||
ignore_revlogs_before_date: String::new(),
|
ignore_revlogs_before_date: String::new(),
|
||||||
};
|
};
|
||||||
|
@ -282,7 +282,12 @@ pub(crate) fn ensure_deck_config_values_valid(config: &mut DeckConfigInner) {
|
||||||
0.7,
|
0.7,
|
||||||
0.99,
|
0.99,
|
||||||
);
|
);
|
||||||
ensure_f32_valid(&mut config.sm2_retention, default.sm2_retention, 0.7, 0.97)
|
ensure_f32_valid(
|
||||||
|
&mut config.historical_retention,
|
||||||
|
default.historical_retention,
|
||||||
|
0.7,
|
||||||
|
0.97,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ensure_f32_valid(val: &mut f32, default: f32, min: f32, max: f32) {
|
fn ensure_f32_valid(val: &mut f32, default: f32, min: f32, max: f32) {
|
||||||
|
|
|
@ -86,6 +86,7 @@ pub struct DeckConfSchema11 {
|
||||||
#[serde(default = "wait_for_audio_default")]
|
#[serde(default = "wait_for_audio_default")]
|
||||||
wait_for_audio: bool,
|
wait_for_audio: bool,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
|
/// historical retention
|
||||||
sm2_retention: f32,
|
sm2_retention: f32,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
weight_search: String,
|
weight_search: String,
|
||||||
|
@ -373,7 +374,7 @@ impl From<DeckConfSchema11> for DeckConfig {
|
||||||
fsrs_weights: c.fsrs_weights,
|
fsrs_weights: c.fsrs_weights,
|
||||||
ignore_revlogs_before_date: c.ignore_revlogs_before_date,
|
ignore_revlogs_before_date: c.ignore_revlogs_before_date,
|
||||||
desired_retention: c.desired_retention,
|
desired_retention: c.desired_retention,
|
||||||
sm2_retention: c.sm2_retention,
|
historical_retention: c.sm2_retention,
|
||||||
weight_search: c.weight_search,
|
weight_search: c.weight_search,
|
||||||
other: other_bytes,
|
other: other_bytes,
|
||||||
},
|
},
|
||||||
|
@ -479,7 +480,7 @@ impl From<DeckConfig> for DeckConfSchema11 {
|
||||||
bury_interday_learning: i.bury_interday_learning,
|
bury_interday_learning: i.bury_interday_learning,
|
||||||
fsrs_weights: i.fsrs_weights,
|
fsrs_weights: i.fsrs_weights,
|
||||||
desired_retention: i.desired_retention,
|
desired_retention: i.desired_retention,
|
||||||
sm2_retention: i.sm2_retention,
|
sm2_retention: i.historical_retention,
|
||||||
weight_search: i.weight_search,
|
weight_search: i.weight_search,
|
||||||
ignore_revlogs_before_date: i.ignore_revlogs_before_date,
|
ignore_revlogs_before_date: i.ignore_revlogs_before_date,
|
||||||
}
|
}
|
||||||
|
|
|
@ -263,7 +263,7 @@ impl Collection {
|
||||||
desired_retention: c.inner.desired_retention,
|
desired_retention: c.inner.desired_retention,
|
||||||
max_interval: c.inner.maximum_review_interval,
|
max_interval: c.inner.maximum_review_interval,
|
||||||
reschedule: req.fsrs_reschedule,
|
reschedule: req.fsrs_reschedule,
|
||||||
sm2_retention: c.inner.sm2_retention,
|
historical_retention: c.inner.historical_retention,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
|
@ -382,10 +382,10 @@ impl Collection {
|
||||||
&fsrs,
|
&fsrs,
|
||||||
revlog,
|
revlog,
|
||||||
timing.next_day_at,
|
timing.next_day_at,
|
||||||
config.inner.sm2_retention,
|
config.inner.historical_retention,
|
||||||
ignore_revlogs_before_ms_from_config(&config)?,
|
ignore_revlogs_before_ms_from_config(&config)?,
|
||||||
)?;
|
)?;
|
||||||
card.set_memory_state(&fsrs, item, config.inner.sm2_retention)?;
|
card.set_memory_state(&fsrs, item, config.inner.historical_retention)?;
|
||||||
}
|
}
|
||||||
let days_elapsed = self
|
let days_elapsed = self
|
||||||
.storage
|
.storage
|
||||||
|
|
|
@ -32,7 +32,7 @@ pub struct ComputeMemoryProgress {
|
||||||
pub(crate) struct UpdateMemoryStateRequest {
|
pub(crate) struct UpdateMemoryStateRequest {
|
||||||
pub weights: Weights,
|
pub weights: Weights,
|
||||||
pub desired_retention: f32,
|
pub desired_retention: f32,
|
||||||
pub sm2_retention: f32,
|
pub historical_retention: f32,
|
||||||
pub max_interval: u32,
|
pub max_interval: u32,
|
||||||
pub reschedule: bool,
|
pub reschedule: bool,
|
||||||
}
|
}
|
||||||
|
@ -70,12 +70,12 @@ impl Collection {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
let fsrs = FSRS::new(req.as_ref().map(|w| &w.weights[..]).or(Some([].as_slice())))?;
|
let fsrs = FSRS::new(req.as_ref().map(|w| &w.weights[..]).or(Some([].as_slice())))?;
|
||||||
let sm2_retention = req.as_ref().map(|w| w.sm2_retention);
|
let historical_retention = req.as_ref().map(|w| w.historical_retention);
|
||||||
let items = fsrs_items_for_memory_state(
|
let items = fsrs_items_for_memory_state(
|
||||||
&fsrs,
|
&fsrs,
|
||||||
revlog,
|
revlog,
|
||||||
timing.next_day_at,
|
timing.next_day_at,
|
||||||
sm2_retention.unwrap_or(0.9),
|
historical_retention.unwrap_or(0.9),
|
||||||
ignore_before,
|
ignore_before,
|
||||||
)?;
|
)?;
|
||||||
let desired_retention = req.as_ref().map(|w| w.desired_retention);
|
let desired_retention = req.as_ref().map(|w| w.desired_retention);
|
||||||
|
@ -86,7 +86,7 @@ impl Collection {
|
||||||
let mut card = self.storage.get_card(card_id)?.or_not_found(card_id)?;
|
let mut card = self.storage.get_card(card_id)?.or_not_found(card_id)?;
|
||||||
let original = card.clone();
|
let original = card.clone();
|
||||||
if let Some(req) = &req {
|
if let Some(req) = &req {
|
||||||
card.set_memory_state(&fsrs, item, sm2_retention.unwrap())?;
|
card.set_memory_state(&fsrs, item, historical_retention.unwrap())?;
|
||||||
card.desired_retention = desired_retention;
|
card.desired_retention = desired_retention;
|
||||||
// if rescheduling
|
// if rescheduling
|
||||||
if let Some(reviews) = &last_revlog_info {
|
if let Some(reviews) = &last_revlog_info {
|
||||||
|
@ -153,17 +153,17 @@ impl Collection {
|
||||||
.get_deck_config(conf_id)?
|
.get_deck_config(conf_id)?
|
||||||
.or_not_found(conf_id)?;
|
.or_not_found(conf_id)?;
|
||||||
let desired_retention = config.inner.desired_retention;
|
let desired_retention = config.inner.desired_retention;
|
||||||
let sm2_retention = config.inner.sm2_retention;
|
let historical_retention = config.inner.historical_retention;
|
||||||
let fsrs = FSRS::new(Some(&config.inner.fsrs_weights))?;
|
let fsrs = FSRS::new(Some(&config.inner.fsrs_weights))?;
|
||||||
let revlog = self.revlog_for_srs(SearchNode::CardIds(card.id.to_string()))?;
|
let revlog = self.revlog_for_srs(SearchNode::CardIds(card.id.to_string()))?;
|
||||||
let item = single_card_revlog_to_item(
|
let item = single_card_revlog_to_item(
|
||||||
&fsrs,
|
&fsrs,
|
||||||
revlog,
|
revlog,
|
||||||
self.timing_today()?.next_day_at,
|
self.timing_today()?.next_day_at,
|
||||||
sm2_retention,
|
historical_retention,
|
||||||
ignore_revlogs_before_ms_from_config(&config)?,
|
ignore_revlogs_before_ms_from_config(&config)?,
|
||||||
)?;
|
)?;
|
||||||
card.set_memory_state(&fsrs, item, sm2_retention)?;
|
card.set_memory_state(&fsrs, item, historical_retention)?;
|
||||||
Ok(ComputeMemoryStateResponse {
|
Ok(ComputeMemoryStateResponse {
|
||||||
state: card.memory_state.map(Into::into),
|
state: card.memory_state.map(Into::into),
|
||||||
desired_retention,
|
desired_retention,
|
||||||
|
@ -176,7 +176,7 @@ impl Card {
|
||||||
&mut self,
|
&mut self,
|
||||||
fsrs: &FSRS,
|
fsrs: &FSRS,
|
||||||
item: Option<FsrsItemWithStartingState>,
|
item: Option<FsrsItemWithStartingState>,
|
||||||
sm2_retention: f32,
|
historical_retention: f32,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let memory_state = if let Some(i) = item {
|
let memory_state = if let Some(i) = item {
|
||||||
Some(fsrs.memory_state(i.item, i.starting_state)?)
|
Some(fsrs.memory_state(i.item, i.starting_state)?)
|
||||||
|
@ -187,7 +187,7 @@ impl Card {
|
||||||
Some(fsrs.memory_state_from_sm2(
|
Some(fsrs.memory_state_from_sm2(
|
||||||
self.ease_factor(),
|
self.ease_factor(),
|
||||||
self.interval as f32,
|
self.interval as f32,
|
||||||
sm2_retention,
|
historical_retention,
|
||||||
)?)
|
)?)
|
||||||
};
|
};
|
||||||
self.memory_state = memory_state.map(Into::into);
|
self.memory_state = memory_state.map(Into::into);
|
||||||
|
@ -209,7 +209,7 @@ pub(crate) fn fsrs_items_for_memory_state(
|
||||||
fsrs: &FSRS,
|
fsrs: &FSRS,
|
||||||
revlogs: Vec<RevlogEntry>,
|
revlogs: Vec<RevlogEntry>,
|
||||||
next_day_at: TimestampSecs,
|
next_day_at: TimestampSecs,
|
||||||
sm2_retention: f32,
|
historical_retention: f32,
|
||||||
ignore_revlogs_before: TimestampMillis,
|
ignore_revlogs_before: TimestampMillis,
|
||||||
) -> Result<Vec<(CardId, Option<FsrsItemWithStartingState>)>> {
|
) -> Result<Vec<(CardId, Option<FsrsItemWithStartingState>)>> {
|
||||||
revlogs
|
revlogs
|
||||||
|
@ -223,7 +223,7 @@ pub(crate) fn fsrs_items_for_memory_state(
|
||||||
fsrs,
|
fsrs,
|
||||||
group.collect(),
|
group.collect(),
|
||||||
next_day_at,
|
next_day_at,
|
||||||
sm2_retention,
|
historical_retention,
|
||||||
ignore_revlogs_before,
|
ignore_revlogs_before,
|
||||||
)?,
|
)?,
|
||||||
))
|
))
|
||||||
|
@ -277,7 +277,7 @@ pub(crate) fn single_card_revlog_to_item(
|
||||||
fsrs: &FSRS,
|
fsrs: &FSRS,
|
||||||
entries: Vec<RevlogEntry>,
|
entries: Vec<RevlogEntry>,
|
||||||
next_day_at: TimestampSecs,
|
next_day_at: TimestampSecs,
|
||||||
sm2_retention: f32,
|
historical_retention: f32,
|
||||||
ignore_revlogs_before: TimestampMillis,
|
ignore_revlogs_before: TimestampMillis,
|
||||||
) -> Result<Option<FsrsItemWithStartingState>> {
|
) -> Result<Option<FsrsItemWithStartingState>> {
|
||||||
struct FirstReview {
|
struct FirstReview {
|
||||||
|
@ -310,7 +310,7 @@ pub(crate) fn single_card_revlog_to_item(
|
||||||
let starting_state = fsrs.memory_state_from_sm2(
|
let starting_state = fsrs.memory_state_from_sm2(
|
||||||
first_review.ease_factor,
|
first_review.ease_factor,
|
||||||
first_review.interval,
|
first_review.interval,
|
||||||
sm2_retention,
|
historical_retention,
|
||||||
)?;
|
)?;
|
||||||
item.reviews.remove(0);
|
item.reviews.remove(0);
|
||||||
if item.reviews.is_empty() {
|
if item.reviews.is_empty() {
|
||||||
|
|
|
@ -33,9 +33,9 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
help: tr.deckConfigMaximumIntervalTooltip(),
|
help: tr.deckConfigMaximumIntervalTooltip(),
|
||||||
url: HelpPage.DeckOptions.maximumInterval,
|
url: HelpPage.DeckOptions.maximumInterval,
|
||||||
},
|
},
|
||||||
sm2Retention: {
|
historicalRetention: {
|
||||||
title: tr.deckConfigSm2Retention(),
|
title: tr.deckConfigHistoricalRetention(),
|
||||||
help: tr.deckConfigSm2RetentionTooltip(),
|
help: tr.deckConfigHistoricalRetentionTooltip(),
|
||||||
sched: HelpItemScheduler.FSRS,
|
sched: HelpItemScheduler.FSRS,
|
||||||
},
|
},
|
||||||
startingEase: {
|
startingEase: {
|
||||||
|
@ -201,16 +201,18 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
</Item>
|
</Item>
|
||||||
{:else}
|
{:else}
|
||||||
<SpinBoxFloatRow
|
<SpinBoxFloatRow
|
||||||
bind:value={$config.sm2Retention}
|
bind:value={$config.historicalRetention}
|
||||||
defaultValue={defaults.sm2Retention}
|
defaultValue={defaults.historicalRetention}
|
||||||
min={0.5}
|
min={0.5}
|
||||||
max={1.0}
|
max={1.0}
|
||||||
>
|
>
|
||||||
<SettingTitle
|
<SettingTitle
|
||||||
on:click={() =>
|
on:click={() =>
|
||||||
openHelpModal(Object.keys(settings).indexOf("sm2Retention"))}
|
openHelpModal(
|
||||||
|
Object.keys(settings).indexOf("historicalRetention"),
|
||||||
|
)}
|
||||||
>
|
>
|
||||||
{tr.deckConfigSm2Retention()}
|
{tr.deckConfigHistoricalRetention()}
|
||||||
</SettingTitle>
|
</SettingTitle>
|
||||||
</SpinBoxFloatRow>
|
</SpinBoxFloatRow>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
Loading…
Reference in a new issue