@reicek/neataptic-ts 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (272) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.md +33 -0
  2. package/.github/ISSUE_TEMPLATE/feature_request.md +27 -0
  3. package/.github/PULL_REQUEST_TEMPLATE.md +28 -0
  4. package/.github/workflows/ci.yml +41 -0
  5. package/.github/workflows/deploy-pages.yml +29 -0
  6. package/.github/workflows/manual_release_pipeline.yml +62 -0
  7. package/.github/workflows/publish.yml +85 -0
  8. package/.github/workflows/release_dispatch.yml +38 -0
  9. package/.travis.yml +5 -0
  10. package/CONTRIBUTING.md +92 -0
  11. package/LICENSE +24 -0
  12. package/ONNX_EXPORT.md +87 -0
  13. package/README.md +1173 -0
  14. package/RELEASE.md +54 -0
  15. package/dist-docs/package.json +1 -0
  16. package/dist-docs/scripts/generate-docs.d.ts +2 -0
  17. package/dist-docs/scripts/generate-docs.d.ts.map +1 -0
  18. package/dist-docs/scripts/generate-docs.js +536 -0
  19. package/dist-docs/scripts/generate-docs.js.map +1 -0
  20. package/dist-docs/scripts/render-docs-html.d.ts +2 -0
  21. package/dist-docs/scripts/render-docs-html.d.ts.map +1 -0
  22. package/dist-docs/scripts/render-docs-html.js +148 -0
  23. package/dist-docs/scripts/render-docs-html.js.map +1 -0
  24. package/docs/FOLDERS.md +14 -0
  25. package/docs/README.md +1173 -0
  26. package/docs/architecture/README.md +1391 -0
  27. package/docs/architecture/index.html +938 -0
  28. package/docs/architecture/network/README.md +1210 -0
  29. package/docs/architecture/network/index.html +908 -0
  30. package/docs/assets/ascii-maze.bundle.js +16542 -0
  31. package/docs/assets/ascii-maze.bundle.js.map +7 -0
  32. package/docs/index.html +1419 -0
  33. package/docs/methods/README.md +670 -0
  34. package/docs/methods/index.html +477 -0
  35. package/docs/multithreading/README.md +274 -0
  36. package/docs/multithreading/index.html +215 -0
  37. package/docs/multithreading/workers/README.md +23 -0
  38. package/docs/multithreading/workers/browser/README.md +39 -0
  39. package/docs/multithreading/workers/browser/index.html +70 -0
  40. package/docs/multithreading/workers/index.html +57 -0
  41. package/docs/multithreading/workers/node/README.md +33 -0
  42. package/docs/multithreading/workers/node/index.html +66 -0
  43. package/docs/neat/README.md +1284 -0
  44. package/docs/neat/index.html +906 -0
  45. package/docs/src/README.md +2659 -0
  46. package/docs/src/index.html +1579 -0
  47. package/jest.config.ts +32 -0
  48. package/package.json +99 -0
  49. package/plans/HyperMorphoNEAT.md +293 -0
  50. package/plans/ONNX_EXPORT_PLAN.md +46 -0
  51. package/scripts/generate-docs.ts +486 -0
  52. package/scripts/render-docs-html.ts +138 -0
  53. package/scripts/types.d.ts +2 -0
  54. package/src/README.md +2659 -0
  55. package/src/architecture/README.md +1391 -0
  56. package/src/architecture/activationArrayPool.ts +135 -0
  57. package/src/architecture/architect.ts +635 -0
  58. package/src/architecture/connection.ts +148 -0
  59. package/src/architecture/group.ts +406 -0
  60. package/src/architecture/layer.ts +804 -0
  61. package/src/architecture/network/README.md +1210 -0
  62. package/src/architecture/network/network.activate.ts +223 -0
  63. package/src/architecture/network/network.connect.ts +157 -0
  64. package/src/architecture/network/network.deterministic.ts +167 -0
  65. package/src/architecture/network/network.evolve.ts +426 -0
  66. package/src/architecture/network/network.gating.ts +186 -0
  67. package/src/architecture/network/network.genetic.ts +247 -0
  68. package/src/architecture/network/network.mutate.ts +624 -0
  69. package/src/architecture/network/network.onnx.ts +463 -0
  70. package/src/architecture/network/network.prune.ts +216 -0
  71. package/src/architecture/network/network.remove.ts +96 -0
  72. package/src/architecture/network/network.serialize.ts +309 -0
  73. package/src/architecture/network/network.slab.ts +262 -0
  74. package/src/architecture/network/network.standalone.ts +246 -0
  75. package/src/architecture/network/network.stats.ts +59 -0
  76. package/src/architecture/network/network.topology.ts +86 -0
  77. package/src/architecture/network/network.training.ts +1278 -0
  78. package/src/architecture/network.ts +1302 -0
  79. package/src/architecture/node.ts +1288 -0
  80. package/src/architecture/onnx.ts +3 -0
  81. package/src/config.ts +83 -0
  82. package/src/methods/README.md +670 -0
  83. package/src/methods/activation.ts +372 -0
  84. package/src/methods/connection.ts +31 -0
  85. package/src/methods/cost.ts +347 -0
  86. package/src/methods/crossover.ts +63 -0
  87. package/src/methods/gating.ts +43 -0
  88. package/src/methods/methods.ts +8 -0
  89. package/src/methods/mutation.ts +300 -0
  90. package/src/methods/rate.ts +257 -0
  91. package/src/methods/selection.ts +65 -0
  92. package/src/multithreading/README.md +274 -0
  93. package/src/multithreading/multi.ts +339 -0
  94. package/src/multithreading/workers/README.md +23 -0
  95. package/src/multithreading/workers/browser/README.md +39 -0
  96. package/src/multithreading/workers/browser/testworker.ts +99 -0
  97. package/src/multithreading/workers/node/README.md +33 -0
  98. package/src/multithreading/workers/node/testworker.ts +72 -0
  99. package/src/multithreading/workers/node/worker.ts +70 -0
  100. package/src/multithreading/workers/workers.ts +22 -0
  101. package/src/neat/README.md +1284 -0
  102. package/src/neat/neat.adaptive.ts +544 -0
  103. package/src/neat/neat.compat.ts +164 -0
  104. package/src/neat/neat.constants.ts +20 -0
  105. package/src/neat/neat.diversity.ts +217 -0
  106. package/src/neat/neat.evaluate.ts +328 -0
  107. package/src/neat/neat.evolve.ts +1026 -0
  108. package/src/neat/neat.export.ts +249 -0
  109. package/src/neat/neat.helpers.ts +235 -0
  110. package/src/neat/neat.lineage.ts +220 -0
  111. package/src/neat/neat.multiobjective.ts +260 -0
  112. package/src/neat/neat.mutation.ts +718 -0
  113. package/src/neat/neat.objectives.ts +157 -0
  114. package/src/neat/neat.pruning.ts +190 -0
  115. package/src/neat/neat.selection.ts +269 -0
  116. package/src/neat/neat.speciation.ts +460 -0
  117. package/src/neat/neat.species.ts +151 -0
  118. package/src/neat/neat.telemetry.exports.ts +469 -0
  119. package/src/neat/neat.telemetry.ts +933 -0
  120. package/src/neat/neat.types.ts +275 -0
  121. package/src/neat.ts +1042 -0
  122. package/src/neataptic.ts +10 -0
  123. package/test/architecture/activationArrayPool.capacity.test.ts +19 -0
  124. package/test/architecture/activationArrayPool.test.ts +46 -0
  125. package/test/architecture/connection.test.ts +290 -0
  126. package/test/architecture/group.test.ts +950 -0
  127. package/test/architecture/layer.test.ts +1535 -0
  128. package/test/architecture/network.pruning.test.ts +65 -0
  129. package/test/architecture/node.test.ts +1602 -0
  130. package/test/examples/asciiMaze/asciiMaze.e2e.test.ts +499 -0
  131. package/test/examples/asciiMaze/asciiMaze.ts +41 -0
  132. package/test/examples/asciiMaze/browser-entry.ts +164 -0
  133. package/test/examples/asciiMaze/browserLogger.ts +221 -0
  134. package/test/examples/asciiMaze/browserTerminalUtility.ts +48 -0
  135. package/test/examples/asciiMaze/colors.ts +119 -0
  136. package/test/examples/asciiMaze/dashboardManager.ts +968 -0
  137. package/test/examples/asciiMaze/evolutionEngine.ts +1248 -0
  138. package/test/examples/asciiMaze/fitness.ts +136 -0
  139. package/test/examples/asciiMaze/index.html +128 -0
  140. package/test/examples/asciiMaze/index.ts +26 -0
  141. package/test/examples/asciiMaze/interfaces.ts +235 -0
  142. package/test/examples/asciiMaze/mazeMovement.ts +996 -0
  143. package/test/examples/asciiMaze/mazeUtils.ts +278 -0
  144. package/test/examples/asciiMaze/mazeVision.ts +402 -0
  145. package/test/examples/asciiMaze/mazeVisualization.ts +585 -0
  146. package/test/examples/asciiMaze/mazes.ts +245 -0
  147. package/test/examples/asciiMaze/networkRefinement.ts +76 -0
  148. package/test/examples/asciiMaze/networkVisualization.ts +901 -0
  149. package/test/examples/asciiMaze/terminalUtility.ts +73 -0
  150. package/test/methods/activation.test.ts +1142 -0
  151. package/test/methods/connection.test.ts +146 -0
  152. package/test/methods/cost.test.ts +1123 -0
  153. package/test/methods/crossover.test.ts +202 -0
  154. package/test/methods/gating.test.ts +144 -0
  155. package/test/methods/mutation.test.ts +451 -0
  156. package/test/methods/optimizers.advanced.test.ts +80 -0
  157. package/test/methods/optimizers.behavior.test.ts +105 -0
  158. package/test/methods/optimizers.formula.test.ts +89 -0
  159. package/test/methods/rate.cosineWarmRestarts.test.ts +44 -0
  160. package/test/methods/rate.linearWarmupDecay.test.ts +41 -0
  161. package/test/methods/rate.reduceOnPlateau.test.ts +45 -0
  162. package/test/methods/rate.test.ts +684 -0
  163. package/test/methods/selection.test.ts +245 -0
  164. package/test/multithreading/activations.functions.test.ts +54 -0
  165. package/test/multithreading/multi.test.ts +290 -0
  166. package/test/multithreading/worker.node.process.test.ts +39 -0
  167. package/test/multithreading/workers.coverage.test.ts +36 -0
  168. package/test/multithreading/workers.dynamic.import.test.ts +8 -0
  169. package/test/neat/neat.adaptive.complexityBudget.test.ts +34 -0
  170. package/test/neat/neat.adaptive.criterion.complexity.test.ts +50 -0
  171. package/test/neat/neat.adaptive.mutation.strategy.test.ts +37 -0
  172. package/test/neat/neat.adaptive.operator.decay.test.ts +31 -0
  173. package/test/neat/neat.adaptive.phasedComplexity.test.ts +25 -0
  174. package/test/neat/neat.adaptive.pruning.test.ts +25 -0
  175. package/test/neat/neat.adaptive.targetSpecies.test.ts +43 -0
  176. package/test/neat/neat.additional.coverage.test.ts +126 -0
  177. package/test/neat/neat.advanced.enhancements.test.ts +85 -0
  178. package/test/neat/neat.advanced.test.ts +589 -0
  179. package/test/neat/neat.diversity.autocompat.test.ts +47 -0
  180. package/test/neat/neat.diversity.metrics.test.ts +21 -0
  181. package/test/neat/neat.diversity.stats.test.ts +44 -0
  182. package/test/neat/neat.enhancements.test.ts +79 -0
  183. package/test/neat/neat.entropy.ancestorAdaptive.test.ts +133 -0
  184. package/test/neat/neat.entropy.compat.csv.test.ts +108 -0
  185. package/test/neat/neat.evolution.pruning.test.ts +39 -0
  186. package/test/neat/neat.fastmode.autotune.test.ts +42 -0
  187. package/test/neat/neat.innovation.test.ts +134 -0
  188. package/test/neat/neat.lineage.antibreeding.test.ts +35 -0
  189. package/test/neat/neat.lineage.entropy.test.ts +56 -0
  190. package/test/neat/neat.lineage.inbreeding.test.ts +49 -0
  191. package/test/neat/neat.lineage.pressure.test.ts +29 -0
  192. package/test/neat/neat.multiobjective.adaptive.test.ts +57 -0
  193. package/test/neat/neat.multiobjective.dynamic.schedule.test.ts +46 -0
  194. package/test/neat/neat.multiobjective.dynamic.test.ts +31 -0
  195. package/test/neat/neat.multiobjective.fastsort.delegation.test.ts +51 -0
  196. package/test/neat/neat.multiobjective.prune.test.ts +39 -0
  197. package/test/neat/neat.multiobjective.test.ts +21 -0
  198. package/test/neat/neat.mutation.undefined.pool.test.ts +24 -0
  199. package/test/neat/neat.objective.events.test.ts +26 -0
  200. package/test/neat/neat.objective.importance.test.ts +21 -0
  201. package/test/neat/neat.objective.lifetimes.test.ts +33 -0
  202. package/test/neat/neat.offspring.allocation.test.ts +22 -0
  203. package/test/neat/neat.operator.bandit.test.ts +17 -0
  204. package/test/neat/neat.operator.phases.test.ts +38 -0
  205. package/test/neat/neat.pruneInactive.behavior.test.ts +54 -0
  206. package/test/neat/neat.reenable.adaptation.test.ts +18 -0
  207. package/test/neat/neat.rng.state.test.ts +22 -0
  208. package/test/neat/neat.spawn.add.test.ts +123 -0
  209. package/test/neat/neat.speciation.test.ts +96 -0
  210. package/test/neat/neat.species.allocation.telemetry.test.ts +26 -0
  211. package/test/neat/neat.species.history.csv.test.ts +24 -0
  212. package/test/neat/neat.telemetry.advanced.test.ts +226 -0
  213. package/test/neat/neat.telemetry.csv.lineage.test.ts +19 -0
  214. package/test/neat/neat.telemetry.parity.test.ts +42 -0
  215. package/test/neat/neat.telemetry.stream.test.ts +19 -0
  216. package/test/neat/neat.telemetry.test.ts +16 -0
  217. package/test/neat/neat.test.ts +422 -0
  218. package/test/neat/neat.utilities.test.ts +44 -0
  219. package/test/network/__suppress_console.ts +9 -0
  220. package/test/network/acyclic.topoorder.test.ts +17 -0
  221. package/test/network/checkpoint.metricshook.test.ts +36 -0
  222. package/test/network/error.handling.test.ts +581 -0
  223. package/test/network/evolution.test.ts +285 -0
  224. package/test/network/genetic.test.ts +208 -0
  225. package/test/network/learning.capability.test.ts +244 -0
  226. package/test/network/mutation.effects.test.ts +492 -0
  227. package/test/network/network.activate.test.ts +115 -0
  228. package/test/network/network.activateBatch.test.ts +30 -0
  229. package/test/network/network.deterministic.test.ts +64 -0
  230. package/test/network/network.evolve.branches.test.ts +75 -0
  231. package/test/network/network.evolve.multithread.branches.test.ts +83 -0
  232. package/test/network/network.evolve.test.ts +100 -0
  233. package/test/network/network.gating.removal.test.ts +93 -0
  234. package/test/network/network.mutate.additional.test.ts +145 -0
  235. package/test/network/network.mutate.edgecases.test.ts +101 -0
  236. package/test/network/network.mutate.test.ts +101 -0
  237. package/test/network/network.prune.earlyexit.test.ts +38 -0
  238. package/test/network/network.remove.errors.test.ts +45 -0
  239. package/test/network/network.slab.fallbacks.test.ts +22 -0
  240. package/test/network/network.stats.test.ts +45 -0
  241. package/test/network/network.training.advanced.test.ts +149 -0
  242. package/test/network/network.training.basic.test.ts +228 -0
  243. package/test/network/network.training.helpers.test.ts +183 -0
  244. package/test/network/onnx.export.test.ts +310 -0
  245. package/test/network/onnx.import.test.ts +129 -0
  246. package/test/network/pruning.topology.test.ts +282 -0
  247. package/test/network/regularization.determinism.test.ts +83 -0
  248. package/test/network/regularization.dropconnect.test.ts +17 -0
  249. package/test/network/regularization.dropconnect.validation.test.ts +18 -0
  250. package/test/network/regularization.stochasticdepth.test.ts +27 -0
  251. package/test/network/regularization.test.ts +843 -0
  252. package/test/network/regularization.weightnoise.test.ts +30 -0
  253. package/test/network/setupTests.ts +2 -0
  254. package/test/network/standalone.test.ts +332 -0
  255. package/test/network/structure.serialization.test.ts +660 -0
  256. package/test/training/training.determinism.mixed-precision.test.ts +134 -0
  257. package/test/training/training.earlystopping.test.ts +91 -0
  258. package/test/training/training.edge-cases.test.ts +91 -0
  259. package/test/training/training.extensions.test.ts +47 -0
  260. package/test/training/training.gradient.features.test.ts +110 -0
  261. package/test/training/training.gradient.refinements.test.ts +170 -0
  262. package/test/training/training.gradient.separate-bias.test.ts +41 -0
  263. package/test/training/training.optimizer.test.ts +48 -0
  264. package/test/training/training.plateau.smoothing.test.ts +58 -0
  265. package/test/training/training.smoothing.types.test.ts +174 -0
  266. package/test/training/training.train.options.coverage.test.ts +52 -0
  267. package/test/utils/console-helper.ts +76 -0
  268. package/test/utils/jest-setup.ts +60 -0
  269. package/test/utils/test-helpers.ts +175 -0
  270. package/tsconfig.docs.json +12 -0
  271. package/tsconfig.json +21 -0
  272. package/webpack.config.js +49 -0
@@ -0,0 +1,89 @@
1
+ import Network from '../../src/architecture/network';
2
+
3
+ // Deterministic tiny dataset y=2x
4
+ const data = Array.from({ length: 3 }, (_, i) => ({
5
+ input: [i + 1],
6
+ output: [2 * (i + 1)],
7
+ }));
8
+
9
+ function buildNet() {
10
+ const net = new Network(1, 1);
11
+ net.connections.forEach((c) => (c.weight = 0.5));
12
+ net.nodes.filter((n) => n.type !== 'input').forEach((n) => (n.bias = 0));
13
+ return net;
14
+ }
15
+
16
+ // Utility to run one iteration and capture internal optimizer state
17
+ function trainSteps(net: Network, opt: any, iterations: number, rate = 0.01) {
18
+ net.train(data, {
19
+ iterations,
20
+ rate,
21
+ optimizer: opt,
22
+ batchSize: 1,
23
+ error: 0,
24
+ cost: {
25
+ fn: (t: number[], o: number[]) => (o[0] - t[0]) ** 2,
26
+ calculate: (t: number[], o: number[]) => (o[0] - t[0]) ** 2,
27
+ },
28
+ });
29
+ }
30
+
31
+ describe('Optimizer formula characteristics', () => {
32
+ describe('adamax infinity norm vs adam second moment', () => {
33
+ const netA = buildNet();
34
+ const netB = buildNet();
35
+ trainSteps(netA, { type: 'adamax' }, 2);
36
+ trainSteps(netB, { type: 'adam' }, 2);
37
+ const connA: any = netA.connections[0];
38
+ const connB: any = netB.connections[0];
39
+ it('maintains opt_u (infinity norm) different from sqrt(v)', () => {
40
+ expect(connA.opt_u).not.toBeUndefined();
41
+ });
42
+ });
43
+
44
+ describe('nadam nesterov lookahead produces larger early step than adam', () => {
45
+ const netN = buildNet();
46
+ const netA = buildNet();
47
+ trainSteps(netN, { type: 'nadam' }, 1); // single step
48
+ trainSteps(netA, { type: 'adam' }, 1);
49
+ const deltaN = netN.connections[0].weight - 0.5;
50
+ const deltaA = netA.connections[0].weight - 0.5;
51
+ it('has different first step magnitude from adam', () => {
52
+ expect(Math.abs(deltaN - deltaA)).toBeGreaterThan(0);
53
+ });
54
+ });
55
+
56
+ describe('radam early unrectified vs later rectified variance', () => {
57
+ const netEarly = buildNet();
58
+ const netLate = buildNet();
59
+ trainSteps(netEarly, { type: 'radam' }, 1);
60
+ trainSteps(netLate, { type: 'radam' }, 10);
61
+ const earlyDelta = Math.abs(netEarly.connections[0].weight - 0.5);
62
+ const lateDelta = Math.abs(netLate.connections[0].weight - 0.5);
63
+ it('late step magnitude differs from very early step', () => {
64
+ expect(Math.abs(lateDelta - earlyDelta)).toBeGreaterThan(0);
65
+ });
66
+ });
67
+
68
+ describe('adabelief variance differs from adam given same gradients', () => {
69
+ const netBelief = buildNet();
70
+ const netAdam = buildNet();
71
+ trainSteps(netBelief, { type: 'adabelief' }, 2);
72
+ trainSteps(netAdam, { type: 'adam' }, 2);
73
+ const cB: any = netBelief.connections[0];
74
+ const cA: any = netAdam.connections[0];
75
+ it('maintains distinct second moment estimate', () => {
76
+ expect(cB.opt_v).not.toBe(cA.opt_v);
77
+ });
78
+ });
79
+
80
+ describe('lookahead defaults', () => {
81
+ const net = buildNet();
82
+ // Provide only type to trigger default baseType and params
83
+ trainSteps(net, { type: 'lookahead' }, 3);
84
+ const conn: any = net.connections[0];
85
+ it('creates shadow weight with default params', () => {
86
+ expect(conn._la_shadowWeight).toBeDefined();
87
+ });
88
+ });
89
+ });
@@ -0,0 +1,44 @@
1
+ import Rate from '../../src/methods/rate';
2
+
3
+ describe('Rate.cosineAnnealingWarmRestarts', () => {
4
+ const base = 0.1;
5
+ const period = 5;
6
+ const min = 0.001;
7
+ const tMult = 2;
8
+ const fn = Rate.cosineAnnealingWarmRestarts(period, min, tMult);
9
+
10
+ describe('First cycle peak at iteration 0', () => {
11
+ const value = fn(base, 0);
12
+ it('returns ~base at start of first cycle', () => {
13
+ expect(value).toBeCloseTo(base, 10);
14
+ });
15
+ });
16
+
17
+ describe('First cycle mid (iteration 2)', () => {
18
+ const value = fn(base, 2);
19
+ it('returns value between min and base', () => {
20
+ expect(value).toBeLessThan(base);
21
+ });
22
+ });
23
+
24
+ describe('End of first cycle (iteration 4)', () => {
25
+ const value = fn(base, 4);
26
+ it('returns near min at end of cycle', () => {
27
+ expect(value).toBeLessThanOrEqual(base * 0.51); // rough check downward
28
+ });
29
+ });
30
+
31
+ describe('Start of second (restart) cycle (iteration 5)', () => {
32
+ const value = fn(base, 5);
33
+ it('resets close to base after restart', () => {
34
+ expect(value).toBeCloseTo(base, 2);
35
+ });
36
+ });
37
+
38
+ describe('Within second (longer) cycle (iteration 8)', () => {
39
+ const value = fn(base, 8);
40
+ it('still between min and base mid second cycle', () => {
41
+ expect(value).toBeGreaterThan(min);
42
+ });
43
+ });
44
+ });
@@ -0,0 +1,41 @@
1
+ import Rate from '../../src/methods/rate';
2
+
3
+ describe('Rate.linearWarmupDecay', () => {
4
+ const base = 0.2;
5
+ const fn = Rate.linearWarmupDecay(20, 5, 0.01);
6
+
7
+ describe('Warmup start (iter 0)', () => {
8
+ const value = fn(base, 0);
9
+ it('starts near 0', () => {
10
+ expect(value).toBeCloseTo(0, 5);
11
+ });
12
+ });
13
+
14
+ describe('Warmup mid (iter 3)', () => {
15
+ const value = fn(base, 3);
16
+ it('increases during warmup', () => {
17
+ expect(value).toBeGreaterThan(0);
18
+ });
19
+ });
20
+
21
+ describe('End warmup (iter 5)', () => {
22
+ const value = fn(base, 5);
23
+ it('reaches base at end warmup', () => {
24
+ expect(value).toBeCloseTo(base, 5);
25
+ });
26
+ });
27
+
28
+ describe('Decay mid (iter 10)', () => {
29
+ const value = fn(base, 10);
30
+ it('decays after warmup', () => {
31
+ expect(value).toBeLessThan(base);
32
+ });
33
+ });
34
+
35
+ describe('Final step (iter 20)', () => {
36
+ const value = fn(base, 20);
37
+ it('hits endRate at totalSteps', () => {
38
+ expect(value).toBeCloseTo(0.01, 5);
39
+ });
40
+ });
41
+ });
@@ -0,0 +1,45 @@
1
+ import Rate from '../../src/methods/rate';
2
+
3
+ describe('Rate.reduceOnPlateau', () => {
4
+ const base = 0.05;
5
+ const rop = Rate.reduceOnPlateau({
6
+ patience: 2,
7
+ factor: 0.5,
8
+ minRate: 0.005,
9
+ });
10
+
11
+ // simulate sequence of errors
12
+ const seq = [0.5, 0.45, 0.46, 0.47, 0.4, 0.41, 0.41, 0.39];
13
+ const rates: number[] = [];
14
+ seq.forEach((err, i) => {
15
+ rates.push(rop(base, i, err));
16
+ });
17
+
18
+ describe('Initial rate (iter 0)', () => {
19
+ const value = rates[0];
20
+ it('starts at base', () => {
21
+ expect(value).toBeCloseTo(base, 10);
22
+ });
23
+ });
24
+
25
+ describe('No reduction before patience (iter 1)', () => {
26
+ const value = rates[1];
27
+ it('unchanged early', () => {
28
+ expect(value).toBe(base);
29
+ });
30
+ });
31
+
32
+ describe('Reduction triggered after patience (iter 3)', () => {
33
+ const value = rates[3];
34
+ it('reduced after plateau', () => {
35
+ expect(value).toBeLessThan(base);
36
+ });
37
+ });
38
+
39
+ describe('Further improvement resets wait (iter 4)', () => {
40
+ const value = rates[4];
41
+ it('stays at reduced rate until new plateau', () => {
42
+ expect(value).toBe(rates[3]);
43
+ });
44
+ });
45
+ });