Added: start_memorized

This commit is contained in:
Luc Mcgrady 2025-09-01 16:47:02 +01:00
parent c2fdf474dd
commit c0a67c3eaa
No known key found for this signature in database
GPG key ID: 4F3D7A0B17CC3D9C
5 changed files with 17 additions and 9 deletions

View file

@ -522,8 +522,7 @@ deck-config-save-options-to-preset-confirm = Overwrite the options in your curre
# specific date.
deck-config-fsrs-simulator-radio-memorized = Memorized
deck-config-fsrs-simulator-radio-ratio = Time / Memorized Ratio
# $time here is pre-formatted e.g. "10 Seconds"
deck-config-fsrs-simulator-ratio-tooltip = { $time } per memorized card
deck-config-fsrs-simulator-ratio-tooltip = { $time } memorized cards per hour
## Messages related to the FSRS schedulers health check. The health check determines whether the correlation between FSRS predictions and your memory is good or bad. It can be optionally triggered as part of the "Optimize" function.

View file

@ -420,8 +420,9 @@ message SimulateFsrsReviewResponse {
message SimulateFsrsWorkloadResponse {
map<uint32, float> cost = 1;
map<uint32, float> memorized = 2;
map<uint32, uint32> review_count = 3;
float start_memorized = 2;
map<uint32, float> memorized = 3;
map<uint32, uint32> review_count = 4;
}
message ComputeOptimalRetentionResponse {

View file

@ -292,8 +292,7 @@ impl Collection {
Ok((
dr,
(
*result.memorized_cnt_per_day.last().unwrap_or(&0.)
- *result.memorized_cnt_per_day.first().unwrap_or(&0.),
*result.memorized_cnt_per_day.last().unwrap_or(&0.),
result.cost_per_day.iter().sum::<f32>(),
result.review_cnt_per_day.iter().sum::<usize>() as u32
+ result.learn_cnt_per_day.iter().sum::<usize>() as u32,
@ -301,7 +300,11 @@ impl Collection {
))
})
.collect::<Result<HashMap<_, _>>>()?;
let start_memorized = cards
.iter()
.fold(0., |p, c| p + c.retention_on(&req.params, 0.));
Ok(SimulateFsrsWorkloadResponse {
start_memorized,
memorized: dr_workload.iter().map(|(k, v)| (*k, v.0)).collect(),
cost: dr_workload.iter().map(|(k, v)| (*k, v.1)).collect(),
review_count: dr_workload.iter().map(|(k, v)| (*k, v.2)).collect(),

View file

@ -212,6 +212,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
x: parseInt(dr),
timeCost: resp!.cost[dr],
memorized: v,
start_memorized: resp!.startMemorized,
count: resp!.reviewCount[dr],
label: simulationNumber,
learnSpan: simulateFsrsRequest.daysToSimulate,

View file

@ -34,6 +34,7 @@ export interface Point {
export type WorkloadPoint = Point & {
learnSpan: number;
start_memorized: number;
};
export enum SimulateSubgraph {
@ -63,14 +64,17 @@ export function renderWorkloadChart(
.range([bounds.marginLeft, bounds.width - bounds.marginRight]);
const subgraph_data = ({
[SimulateWorkloadSubgraph.ratio]: data.map(d => ({ ...d, y: d.memorized / d.timeCost })),
[SimulateWorkloadSubgraph.ratio]: data.map(d => ({
...d,
y: (60 * 60 * (d.memorized - d.start_memorized)) / d.timeCost,
})),
[SimulateWorkloadSubgraph.time]: data.map(d => ({ ...d, y: d.timeCost / d.learnSpan })),
[SimulateWorkloadSubgraph.count]: data.map(d => ({ ...d, y: d.count / d.learnSpan })),
[SimulateWorkloadSubgraph.memorized]: data.map(d => ({ ...d, y: d.memorized })),
})[subgraph];
const yTickFormat = (n: number): string => {
return subgraph == SimulateWorkloadSubgraph.time || subgraph == SimulateWorkloadSubgraph.ratio
return subgraph == SimulateWorkloadSubgraph.time
? timeSpan(n, true)
: n.toString();
};
@ -84,7 +88,7 @@ export function renderWorkloadChart(
const formatY: (value: number) => string = ({
[SimulateWorkloadSubgraph.ratio]: (value: number) =>
tr.deckConfigFsrsSimulatorRatioTooltip({ time: timeSpan(value) }),
tr.deckConfigFsrsSimulatorRatioTooltip({ time: value.toFixed(2) }),
[SimulateWorkloadSubgraph.time]: (value: number) =>
tr.statisticsMinutesPerDay({ count: parseFloat((value / 60).toPrecision(2)) }),
[SimulateWorkloadSubgraph.count]: (value: number) => tr.statisticsReviewsPerDay({ count: Math.round(value) }),