diff --git a/apps/api/src/scripts/analyze.ts b/apps/api/src/scripts/analyze.ts deleted file mode 100644 index cc997a4..0000000 --- a/apps/api/src/scripts/analyze.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { - type Levels, -} from "@blade-and-brawn/calculator"; -import { Activity, clamp, Gender, range } from "@blade-and-brawn/domain"; -import { levenbergMarquardt as LM } from "ml-levenberg-marquardt"; -import { CalculatorService } from "../services/calculator"; -import { DEFAULT_NAME } from "../util"; - -const calculator = new CalculatorService(DEFAULT_NAME); -const standardsConfig = await calculator.Standards.Config.get(); -for (const activity of Object.values(Activity)) { - const DATASET_MAX_LEVEL = 5; - const NEW_LEVEL_COUNT = 2; - const RATIO_CLAMP = 1.4; - - function expDecayModel([A, B, C]: number[]) { - return (i: number) => A! * Math.exp(-B! * i) + C!; - } - - for (const gender of Object.values(Gender)) { - const standardsByGender = standardsConfig.data[ - activity - ].standards.filter((s) => s["metrics"].gender === gender); - const ages = [...new Set(standardsByGender.map((s) => s.metrics.age))]; - for (const age of ages) { - const standards = standardsByGender.filter( - (s) => s.metrics.age === age, - ); - - const data = { - x: [] as number[], - y: [] as number[], - }; - - const isIncreasing = - standards[0]!.levels["2"]! > standards[0]!.levels["1"]!; - - for (const i of range(DATASET_MAX_LEVEL).slice(0, -1)) { - const level = i + 1; - const progressionRatios: number[] = []; - for (const standard of standards) { - const curr = standard.levels[level]!; - const next = standard.levels[level]!; - progressionRatios.push( - isIncreasing ? next / curr : curr / next, - ); - } - - const sum = progressionRatios.reduce((p, c) => p + c, 0); - const progressionRatioAvg = sum / progressionRatios.length; - - data.x.push(i); - data.y.push(progressionRatioAvg); - } - - const fittedParams = LM(data, expDecayModel, { - initialValues: [0.4, 0.5, 1.1], - minValues: [0.0, 0.0, 1.02], - maxValues: [1.0, 2.0, 1.25], - maxIterations: 200, - }); - const getDecayRatio = (i: number) => - clamp( - expDecayModel(fittedParams.parameterValues)(i), - 1, - RATIO_CLAMP, - ); - - // UPDATE THE DATA - for (const standard of standards) { - const newLevels: Levels = {}; - - let prev = standard.levels["1"]!; - for (const i of range(NEW_LEVEL_COUNT)) { - const level = i + 1; - const ratio = getDecayRatio(level - NEW_LEVEL_COUNT); - prev = isIncreasing ? prev / ratio : prev * ratio; - newLevels[level] = Math.round(prev); - } - - const oldLevels = standard.levels as Levels; - for (const i of range(DATASET_MAX_LEVEL)) { - const level = i + 1; - newLevels[level + NEW_LEVEL_COUNT] = oldLevels[level]!; - } - standard.levels = newLevels; - } - } - } -}