@cogitator-ai/evals 0.11.0 → 0.13.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 (155) hide show
  1. package/README.md +159 -40
  2. package/dist/calibrate-judge.d.ts +53 -0
  3. package/dist/calibrate-judge.d.ts.map +1 -0
  4. package/dist/calibrate-judge.js +114 -0
  5. package/dist/calibrate-judge.js.map +1 -0
  6. package/dist/comparison-stats.d.ts +104 -0
  7. package/dist/comparison-stats.d.ts.map +1 -0
  8. package/dist/comparison-stats.js +179 -0
  9. package/dist/comparison-stats.js.map +1 -0
  10. package/dist/datasets/dataset.d.ts.map +1 -1
  11. package/dist/datasets/dataset.js +3 -27
  12. package/dist/datasets/dataset.js.map +1 -1
  13. package/dist/eval-comparison.d.ts +30 -10
  14. package/dist/eval-comparison.d.ts.map +1 -1
  15. package/dist/eval-comparison.js +73 -103
  16. package/dist/eval-comparison.js.map +1 -1
  17. package/dist/eval-suite.d.ts +33 -0
  18. package/dist/eval-suite.d.ts.map +1 -1
  19. package/dist/eval-suite.js +81 -2
  20. package/dist/eval-suite.js.map +1 -1
  21. package/dist/index.d.ts +21 -5
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +10 -1
  24. package/dist/index.js.map +1 -1
  25. package/dist/metrics/g-eval.d.ts +29 -0
  26. package/dist/metrics/g-eval.d.ts.map +1 -0
  27. package/dist/metrics/g-eval.js +89 -0
  28. package/dist/metrics/g-eval.js.map +1 -0
  29. package/dist/metrics/index.d.ts +3 -1
  30. package/dist/metrics/index.d.ts.map +1 -1
  31. package/dist/metrics/index.js +1 -0
  32. package/dist/metrics/index.js.map +1 -1
  33. package/dist/metrics/judge-prompt.d.ts +31 -0
  34. package/dist/metrics/judge-prompt.d.ts.map +1 -0
  35. package/dist/metrics/judge-prompt.js +90 -0
  36. package/dist/metrics/judge-prompt.js.map +1 -0
  37. package/dist/metrics/llm-judge.d.ts +96 -9
  38. package/dist/metrics/llm-judge.d.ts.map +1 -1
  39. package/dist/metrics/llm-judge.js +265 -120
  40. package/dist/metrics/llm-judge.js.map +1 -1
  41. package/dist/metrics/types.d.ts +25 -0
  42. package/dist/metrics/types.d.ts.map +1 -1
  43. package/dist/metrics/types.js.map +1 -1
  44. package/dist/options.d.ts +4 -0
  45. package/dist/options.d.ts.map +1 -0
  46. package/dist/options.js +9 -0
  47. package/dist/options.js.map +1 -0
  48. package/dist/pairwise.d.ts +53 -0
  49. package/dist/pairwise.d.ts.map +1 -0
  50. package/dist/pairwise.js +118 -0
  51. package/dist/pairwise.js.map +1 -0
  52. package/dist/reporters/comparison.d.ts +24 -0
  53. package/dist/reporters/comparison.d.ts.map +1 -0
  54. package/dist/reporters/comparison.js +290 -0
  55. package/dist/reporters/comparison.js.map +1 -0
  56. package/dist/reporters/format.d.ts +21 -0
  57. package/dist/reporters/format.d.ts.map +1 -1
  58. package/dist/reporters/format.js +31 -0
  59. package/dist/reporters/format.js.map +1 -1
  60. package/dist/reporters/github.d.ts.map +1 -1
  61. package/dist/reporters/github.js +1 -16
  62. package/dist/reporters/github.js.map +1 -1
  63. package/dist/reporters/html-format.d.ts +11 -0
  64. package/dist/reporters/html-format.d.ts.map +1 -0
  65. package/dist/reporters/html-format.js +111 -0
  66. package/dist/reporters/html-format.js.map +1 -0
  67. package/dist/reporters/html.d.ts +12 -0
  68. package/dist/reporters/html.d.ts.map +1 -0
  69. package/dist/reporters/html.js +119 -0
  70. package/dist/reporters/html.js.map +1 -0
  71. package/dist/reporters/index.d.ts +20 -6
  72. package/dist/reporters/index.d.ts.map +1 -1
  73. package/dist/reporters/index.js +15 -4
  74. package/dist/reporters/index.js.map +1 -1
  75. package/dist/reporters/markdown.d.ts +15 -0
  76. package/dist/reporters/markdown.d.ts.map +1 -0
  77. package/dist/reporters/markdown.js +67 -0
  78. package/dist/reporters/markdown.js.map +1 -0
  79. package/dist/runs/compare.d.ts +103 -0
  80. package/dist/runs/compare.d.ts.map +1 -0
  81. package/dist/runs/compare.js +208 -0
  82. package/dist/runs/compare.js.map +1 -0
  83. package/dist/runs/index.d.ts +9 -0
  84. package/dist/runs/index.d.ts.map +1 -0
  85. package/dist/runs/index.js +5 -0
  86. package/dist/runs/index.js.map +1 -0
  87. package/dist/runs/json.d.ts +11 -0
  88. package/dist/runs/json.d.ts.map +1 -0
  89. package/dist/runs/json.js +58 -0
  90. package/dist/runs/json.js.map +1 -0
  91. package/dist/runs/run.d.ts +44 -0
  92. package/dist/runs/run.d.ts.map +1 -0
  93. package/dist/runs/run.js +136 -0
  94. package/dist/runs/run.js.map +1 -0
  95. package/dist/runs/schema.d.ts +504 -0
  96. package/dist/runs/schema.d.ts.map +1 -0
  97. package/dist/runs/schema.js +171 -0
  98. package/dist/runs/schema.js.map +1 -0
  99. package/dist/runs/store.d.ts +57 -0
  100. package/dist/runs/store.d.ts.map +1 -0
  101. package/dist/runs/store.js +146 -0
  102. package/dist/runs/store.js.map +1 -0
  103. package/dist/schema.d.ts +16 -0
  104. package/dist/schema.d.ts.map +1 -1
  105. package/dist/schema.js +17 -0
  106. package/dist/schema.js.map +1 -1
  107. package/dist/stats/bootstrap.d.ts +22 -0
  108. package/dist/stats/bootstrap.d.ts.map +1 -0
  109. package/dist/stats/bootstrap.js +34 -0
  110. package/dist/stats/bootstrap.js.map +1 -0
  111. package/dist/stats/correlation.d.ts +11 -0
  112. package/dist/stats/correlation.d.ts.map +1 -0
  113. package/dist/stats/correlation.js +42 -0
  114. package/dist/stats/correlation.js.map +1 -0
  115. package/dist/stats/effect-size.d.ts +7 -0
  116. package/dist/stats/effect-size.d.ts.map +1 -0
  117. package/dist/stats/effect-size.js +17 -0
  118. package/dist/stats/effect-size.js.map +1 -0
  119. package/dist/stats/holm.d.ts +7 -0
  120. package/dist/stats/holm.d.ts.map +1 -0
  121. package/dist/stats/holm.js +21 -0
  122. package/dist/stats/holm.js.map +1 -0
  123. package/dist/stats/index.d.ts +10 -2
  124. package/dist/stats/index.d.ts.map +1 -1
  125. package/dist/stats/index.js +7 -1
  126. package/dist/stats/index.js.map +1 -1
  127. package/dist/stats/mcnemar.d.ts +9 -0
  128. package/dist/stats/mcnemar.d.ts.map +1 -1
  129. package/dist/stats/mcnemar.js +27 -13
  130. package/dist/stats/mcnemar.js.map +1 -1
  131. package/dist/stats/normal.d.ts +5 -0
  132. package/dist/stats/normal.d.ts.map +1 -0
  133. package/dist/stats/normal.js +19 -0
  134. package/dist/stats/normal.js.map +1 -0
  135. package/dist/stats/precision.d.ts +12 -0
  136. package/dist/stats/precision.d.ts.map +1 -0
  137. package/dist/stats/precision.js +29 -0
  138. package/dist/stats/precision.js.map +1 -0
  139. package/dist/stats/random.d.ts +6 -0
  140. package/dist/stats/random.d.ts.map +1 -0
  141. package/dist/stats/random.js +25 -0
  142. package/dist/stats/random.js.map +1 -0
  143. package/dist/stats/ranks.d.ts +5 -0
  144. package/dist/stats/ranks.d.ts.map +1 -0
  145. package/dist/stats/ranks.js +24 -0
  146. package/dist/stats/ranks.js.map +1 -0
  147. package/dist/stats/t-test.d.ts +4 -0
  148. package/dist/stats/t-test.d.ts.map +1 -1
  149. package/dist/stats/t-test.js +9 -3
  150. package/dist/stats/t-test.js.map +1 -1
  151. package/dist/stats/wilcoxon.d.ts +19 -0
  152. package/dist/stats/wilcoxon.d.ts.map +1 -0
  153. package/dist/stats/wilcoxon.js +70 -0
  154. package/dist/stats/wilcoxon.js.map +1 -0
  155. package/package.json +1 -1
@@ -0,0 +1,17 @@
1
+ import { mean, stdDev } from './percentiles.js';
2
+ import { isConstant, withoutNoise } from './precision.js';
3
+ /**
4
+ * Cohen's d for paired samples (dz): the mean of the paired differences over their standard
5
+ * deviation, the differences rounded to 12 significant digits. NaN with fewer than 2 differences,
6
+ * plus or minus Infinity when the differences are all the same and not 0, 0 when they are all 0
7
+ */
8
+ export function cohensD(differences) {
9
+ if (differences.length < 2)
10
+ return Number.NaN;
11
+ const values = differences.map(withoutNoise);
12
+ if (isConstant(values)) {
13
+ return values[0] === 0 ? 0 : Math.sign(values[0]) * Number.POSITIVE_INFINITY;
14
+ }
15
+ return mean(values) / stdDev(values);
16
+ }
17
+ //# sourceMappingURL=effect-size.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"effect-size.js","sourceRoot":"","sources":["../../src/stats/effect-size.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEvD;;;;GAIG;AACH,MAAM,UAAU,OAAO,CAAC,WAA8B;IACpD,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,MAAM,CAAC,GAAG,CAAC;IAC9C,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAC7C,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACvB,OAAO,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,iBAAiB,CAAC;IAC/E,CAAC;IACD,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;AACvC,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Holm-Bonferroni adjusted p-values, in the order given: the i-th smallest of m p-values is
3
+ * multiplied by m - i + 1, kept from falling below the ones before it and capped at 1. Rejecting
4
+ * where an adjusted p-value is below alpha keeps the family-wise error rate at alpha
5
+ */
6
+ export declare function holm(pValues: readonly number[]): number[];
7
+ //# sourceMappingURL=holm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"holm.d.ts","sourceRoot":"","sources":["../../src/stats/holm.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,IAAI,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAazD"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Holm-Bonferroni adjusted p-values, in the order given: the i-th smallest of m p-values is
3
+ * multiplied by m - i + 1, kept from falling below the ones before it and capped at 1. Rejecting
4
+ * where an adjusted p-value is below alpha keeps the family-wise error rate at alpha
5
+ */
6
+ export function holm(pValues) {
7
+ for (const p of pValues) {
8
+ if (!(p >= 0 && p <= 1))
9
+ throw new Error(`p-values must be between 0 and 1, got ${p}`);
10
+ }
11
+ const m = pValues.length;
12
+ const order = pValues.map((p, index) => ({ p, index })).sort((a, b) => a.p - b.p);
13
+ const adjusted = new Array(m);
14
+ let running = 0;
15
+ for (const [rank, { p, index }] of order.entries()) {
16
+ running = Math.max(running, Math.min(1, (m - rank) * p));
17
+ adjusted[index] = running;
18
+ }
19
+ return adjusted;
20
+ }
21
+ //# sourceMappingURL=holm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"holm.js","sourceRoot":"","sources":["../../src/stats/holm.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,UAAU,IAAI,CAAC,OAA0B;IAC7C,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,EAAE,CAAC,CAAC;IACzF,CAAC;IACD,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IACzB,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAClF,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAS,CAAC,CAAC,CAAC;IACtC,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,KAAK,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;QACnD,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACzD,QAAQ,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC;IAC5B,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -1,6 +1,14 @@
1
1
  export { percentile, mean, median, stdDev, aggregate } from './percentiles.js';
2
2
  export { pairedTTest } from './t-test.js';
3
3
  export type { TTestResult } from './t-test.js';
4
- export { mcnemarsTest } from './mcnemar.js';
5
- export type { McNemarResult } from './mcnemar.js';
4
+ export { mcnemarsTest, mcnemarExact } from './mcnemar.js';
5
+ export type { McNemarResult, McNemarExactResult } from './mcnemar.js';
6
+ export { wilcoxonSignedRank } from './wilcoxon.js';
7
+ export type { WilcoxonResult } from './wilcoxon.js';
8
+ export { bootstrapCI } from './bootstrap.js';
9
+ export type { BootstrapOptions, BootstrapInterval } from './bootstrap.js';
10
+ export { cohensD } from './effect-size.js';
11
+ export { holm } from './holm.js';
12
+ export { pearson, spearman } from './correlation.js';
13
+ export { seededRandom } from './random.js';
6
14
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/stats/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC5E,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,YAAY,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/stats/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC5E,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACvD,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACvE,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC"}
@@ -1,4 +1,10 @@
1
1
  export { percentile, mean, median, stdDev, aggregate } from './percentiles.js';
2
2
  export { pairedTTest } from './t-test.js';
3
- export { mcnemarsTest } from './mcnemar.js';
3
+ export { mcnemarsTest, mcnemarExact } from './mcnemar.js';
4
+ export { wilcoxonSignedRank } from './wilcoxon.js';
5
+ export { bootstrapCI } from './bootstrap.js';
6
+ export { cohensD } from './effect-size.js';
7
+ export { holm } from './holm.js';
8
+ export { pearson, spearman } from './correlation.js';
9
+ export { seededRandom } from './random.js';
4
10
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/stats/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC5E,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAEvC,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/stats/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC5E,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAEvC,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEhD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC"}
@@ -4,4 +4,13 @@ export interface McNemarResult {
4
4
  significant: boolean;
5
5
  }
6
6
  export declare function mcnemarsTest(pairsACorrect_BIncorrect: number, pairsAIncorrect_BCorrect: number): McNemarResult;
7
+ export interface McNemarExactResult {
8
+ pValue: number;
9
+ significant: boolean;
10
+ }
11
+ /**
12
+ * Exact McNemar test: the two-sided binomial test of `b` against `b + c` discordant pairs at
13
+ * one half. Preferred over `mcnemarsTest` when there are few discordant pairs (below 25)
14
+ */
15
+ export declare function mcnemarExact(b: number, c: number): McNemarExactResult;
7
16
  //# sourceMappingURL=mcnemar.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mcnemar.d.ts","sourceRoot":"","sources":["../../src/stats/mcnemar.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,OAAO,CAAC;CACtB;AAuBD,wBAAgB,YAAY,CAC1B,wBAAwB,EAAE,MAAM,EAChC,wBAAwB,EAAE,MAAM,GAC/B,aAAa,CAiBf"}
1
+ {"version":3,"file":"mcnemar.d.ts","sourceRoot":"","sources":["../../src/stats/mcnemar.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,OAAO,CAAC;CACtB;AAOD,wBAAgB,YAAY,CAC1B,wBAAwB,EAAE,MAAM,EAChC,wBAAwB,EAAE,MAAM,GAC/B,aAAa,CAiBf;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,OAAO,CAAC;CACtB;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,kBAAkB,CAoBrE"}
@@ -1,16 +1,4 @@
1
- function erfc(x) {
2
- const a1 = 0.254829592;
3
- const a2 = -0.284496736;
4
- const a3 = 1.421413741;
5
- const a4 = -1.453152027;
6
- const a5 = 1.061405429;
7
- const p = 0.3275911;
8
- const sign = x < 0 ? -1 : 1;
9
- const absX = Math.abs(x);
10
- const t = 1.0 / (1.0 + p * absX);
11
- const y = 1.0 - ((((a5 * t + a4) * t + a3) * t + a2) * t + a1) * t * Math.exp(-absX * absX);
12
- return 1.0 - sign * y;
13
- }
1
+ import { erfc } from './normal.js';
14
2
  function chiSquareSurvival(x) {
15
3
  if (x <= 0)
16
4
  return 1;
@@ -31,4 +19,30 @@ export function mcnemarsTest(pairsACorrect_BIncorrect, pairsAIncorrect_BCorrect)
31
19
  significant: pValue < 0.05,
32
20
  };
33
21
  }
22
+ /**
23
+ * Exact McNemar test: the two-sided binomial test of `b` against `b + c` discordant pairs at
24
+ * one half. Preferred over `mcnemarsTest` when there are few discordant pairs (below 25)
25
+ */
26
+ export function mcnemarExact(b, c) {
27
+ for (const [label, count] of [
28
+ ['b', b],
29
+ ['c', c],
30
+ ]) {
31
+ if (!Number.isInteger(count) || count < 0) {
32
+ throw new Error(`${label} must be a non-negative integer, got ${count}`);
33
+ }
34
+ }
35
+ const n = b + c;
36
+ if (n === 0)
37
+ return { pValue: 1, significant: false };
38
+ const k = Math.min(b, c);
39
+ let logPmf = -n * Math.LN2;
40
+ let tail = 0;
41
+ for (let i = 0; i <= k; i++) {
42
+ tail += Math.exp(logPmf);
43
+ logPmf += Math.log((n - i) / (i + 1));
44
+ }
45
+ const pValue = Math.min(1, 2 * tail);
46
+ return { pValue, significant: pValue < 0.05 };
47
+ }
34
48
  //# sourceMappingURL=mcnemar.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mcnemar.js","sourceRoot":"","sources":["../../src/stats/mcnemar.ts"],"names":[],"mappings":"AAMA,SAAS,IAAI,CAAC,CAAS;IACrB,MAAM,EAAE,GAAG,WAAW,CAAC;IACvB,MAAM,EAAE,GAAG,CAAC,WAAW,CAAC;IACxB,MAAM,EAAE,GAAG,WAAW,CAAC;IACvB,MAAM,EAAE,GAAG,CAAC,WAAW,CAAC;IACxB,MAAM,EAAE,GAAG,WAAW,CAAC;IACvB,MAAM,CAAC,GAAG,SAAS,CAAC;IAEpB,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACzB,MAAM,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;IACjC,MAAM,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IAE5F,OAAO,GAAG,GAAG,IAAI,GAAG,CAAC,CAAC;AACxB,CAAC;AAED,SAAS,iBAAiB,CAAC,CAAS;IAClC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IACrB,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,YAAY,CAC1B,wBAAgC,EAChC,wBAAgC;IAEhC,MAAM,CAAC,GAAG,wBAAwB,CAAC;IACnC,MAAM,CAAC,GAAG,wBAAwB,CAAC;IAEnC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QAChB,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;IACzD,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9C,MAAM,SAAS,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC;IAE5C,OAAO;QACL,SAAS;QACT,MAAM;QACN,WAAW,EAAE,MAAM,GAAG,IAAI;KAC3B,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"mcnemar.js","sourceRoot":"","sources":["../../src/stats/mcnemar.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAQhC,SAAS,iBAAiB,CAAC,CAAS;IAClC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IACrB,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,YAAY,CAC1B,wBAAgC,EAChC,wBAAgC;IAEhC,MAAM,CAAC,GAAG,wBAAwB,CAAC;IACnC,MAAM,CAAC,GAAG,wBAAwB,CAAC;IAEnC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QAChB,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;IACzD,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9C,MAAM,SAAS,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC;IAE5C,OAAO;QACL,SAAS;QACT,MAAM;QACN,WAAW,EAAE,MAAM,GAAG,IAAI;KAC3B,CAAC;AACJ,CAAC;AAOD;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,CAAS,EAAE,CAAS;IAC/C,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI;QAC3B,CAAC,GAAG,EAAE,CAAC,CAAC;QACR,CAAC,GAAG,EAAE,CAAC,CAAC;KACA,EAAE,CAAC;QACX,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YAC1C,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,wCAAwC,KAAK,EAAE,CAAC,CAAC;QAC3E,CAAC;IACH,CAAC;IACD,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAChB,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;IACtD,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACzB,IAAI,MAAM,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC;IAC3B,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACzB,MAAM,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACxC,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;IACrC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,EAAE,CAAC;AAChD,CAAC"}
@@ -0,0 +1,5 @@
1
+ /** Complementary error function (Abramowitz and Stegun 7.1.26, absolute error below 1.5e-7) */
2
+ export declare function erfc(x: number): number;
3
+ /** Two-sided p-value of a standard normal statistic `z` */
4
+ export declare function normalTwoSidedP(z: number): number;
5
+ //# sourceMappingURL=normal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normal.d.ts","sourceRoot":"","sources":["../../src/stats/normal.ts"],"names":[],"mappings":"AAAA,+FAA+F;AAC/F,wBAAgB,IAAI,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CActC;AAED,2DAA2D;AAC3D,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAEjD"}
@@ -0,0 +1,19 @@
1
+ /** Complementary error function (Abramowitz and Stegun 7.1.26, absolute error below 1.5e-7) */
2
+ export function erfc(x) {
3
+ const a1 = 0.254829592;
4
+ const a2 = -0.284496736;
5
+ const a3 = 1.421413741;
6
+ const a4 = -1.453152027;
7
+ const a5 = 1.061405429;
8
+ const p = 0.3275911;
9
+ const sign = x < 0 ? -1 : 1;
10
+ const absX = Math.abs(x);
11
+ const t = 1.0 / (1.0 + p * absX);
12
+ const y = 1.0 - ((((a5 * t + a4) * t + a3) * t + a2) * t + a1) * t * Math.exp(-absX * absX);
13
+ return 1.0 - sign * y;
14
+ }
15
+ /** Two-sided p-value of a standard normal statistic `z` */
16
+ export function normalTwoSidedP(z) {
17
+ return Math.min(1, erfc(Math.abs(z) / Math.SQRT2));
18
+ }
19
+ //# sourceMappingURL=normal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normal.js","sourceRoot":"","sources":["../../src/stats/normal.ts"],"names":[],"mappings":"AAAA,+FAA+F;AAC/F,MAAM,UAAU,IAAI,CAAC,CAAS;IAC5B,MAAM,EAAE,GAAG,WAAW,CAAC;IACvB,MAAM,EAAE,GAAG,CAAC,WAAW,CAAC;IACxB,MAAM,EAAE,GAAG,WAAW,CAAC;IACvB,MAAM,EAAE,GAAG,CAAC,WAAW,CAAC;IACxB,MAAM,EAAE,GAAG,WAAW,CAAC;IACvB,MAAM,CAAC,GAAG,SAAS,CAAC;IAEpB,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACzB,MAAM,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;IACjC,MAAM,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IAE5F,OAAO,GAAG,GAAG,IAAI,GAAG,CAAC,CAAC;AACxB,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,eAAe,CAAC,CAAS;IACvC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;AACrD,CAAC"}
@@ -0,0 +1,12 @@
1
+ /** A value rounded to 12 significant digits, so float noise such as 0.29999999999999993 reads 0.3 */
2
+ export declare function withoutNoise(value: number): number;
3
+ /**
4
+ * `a - b` on a grid of 12 significant digits of the larger of `a` and `b`, where the float noise
5
+ * of the subtraction lives, so `0.7 - 0.4` and `0.6 - 0.9` tie in magnitude, so do
6
+ * `12345.9 - 12345.7` and `98765.7 - 98765.5`, and two means of the same trials differ by nothing.
7
+ * An infinite or NaN difference stays as it is.
8
+ */
9
+ export declare function pairedDifference(a: number, b: number): number;
10
+ /** Whether every value is the same */
11
+ export declare function isConstant(values: readonly number[]): boolean;
12
+ //# sourceMappingURL=precision.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"precision.d.ts","sourceRoot":"","sources":["../../src/stats/precision.ts"],"names":[],"mappings":"AAEA,qGAAqG;AACrG,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIlD;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAQ7D;AAED,sCAAsC;AACtC,wBAAgB,UAAU,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAE7D"}
@@ -0,0 +1,29 @@
1
+ const SIGNIFICANT_DIGITS = 12;
2
+ /** A value rounded to 12 significant digits, so float noise such as 0.29999999999999993 reads 0.3 */
3
+ export function withoutNoise(value) {
4
+ return value === 0 || !Number.isFinite(value)
5
+ ? value
6
+ : Number(value.toPrecision(SIGNIFICANT_DIGITS));
7
+ }
8
+ /**
9
+ * `a - b` on a grid of 12 significant digits of the larger of `a` and `b`, where the float noise
10
+ * of the subtraction lives, so `0.7 - 0.4` and `0.6 - 0.9` tie in magnitude, so do
11
+ * `12345.9 - 12345.7` and `98765.7 - 98765.5`, and two means of the same trials differ by nothing.
12
+ * An infinite or NaN difference stays as it is.
13
+ */
14
+ export function pairedDifference(a, b) {
15
+ const difference = a - b;
16
+ if (!Number.isFinite(difference))
17
+ return difference;
18
+ const scale = Math.max(Math.abs(a), Math.abs(b));
19
+ if (scale === 0)
20
+ return 0;
21
+ const step = 10 ** (Math.floor(Math.log10(scale)) - (SIGNIFICANT_DIGITS - 1));
22
+ const snapped = Math.round(difference / step) * step;
23
+ return snapped === 0 ? 0 : withoutNoise(snapped);
24
+ }
25
+ /** Whether every value is the same */
26
+ export function isConstant(values) {
27
+ return values.every((value) => value === values[0]);
28
+ }
29
+ //# sourceMappingURL=precision.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"precision.js","sourceRoot":"","sources":["../../src/stats/precision.ts"],"names":[],"mappings":"AAAA,MAAM,kBAAkB,GAAG,EAAE,CAAC;AAE9B,qGAAqG;AACrG,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,OAAO,KAAK,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAC3C,CAAC,CAAC,KAAK;QACP,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC,CAAC;AACpD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,CAAS,EAAE,CAAS;IACnD,MAAM,UAAU,GAAG,CAAC,GAAG,CAAC,CAAC;IACzB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC;QAAE,OAAO,UAAU,CAAC;IACpD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACjD,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAC1B,MAAM,IAAI,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,kBAAkB,GAAG,CAAC,CAAC,CAAC,CAAC;IAC9E,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IACrD,OAAO,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;AACnD,CAAC;AAED,sCAAsC;AACtC,MAAM,UAAU,UAAU,CAAC,MAAyB;IAClD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AACtD,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * `Math.random`, or a mulberry32 generator seeded by the FNV-1a hash of `seed`, so every number
3
+ * and string seeds its own sequence (`1.2` and `1.7`, `-1` and `2 ** 32 - 1` alike)
4
+ */
5
+ export declare function seededRandom(seed: number | string | undefined): () => number;
6
+ //# sourceMappingURL=random.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"random.d.ts","sourceRoot":"","sources":["../../src/stats/random.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,MAAM,CAU5E"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * `Math.random`, or a mulberry32 generator seeded by the FNV-1a hash of `seed`, so every number
3
+ * and string seeds its own sequence (`1.2` and `1.7`, `-1` and `2 ** 32 - 1` alike)
4
+ */
5
+ export function seededRandom(seed) {
6
+ if (seed === undefined)
7
+ return Math.random;
8
+ let state = hashSeed(String(seed));
9
+ return () => {
10
+ state = (state + 0x6d2b79f5) >>> 0;
11
+ let t = state;
12
+ t = Math.imul(t ^ (t >>> 15), t | 1);
13
+ t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
14
+ return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
15
+ };
16
+ }
17
+ function hashSeed(seed) {
18
+ let hash = 0x811c9dc5;
19
+ for (let i = 0; i < seed.length; i++) {
20
+ hash ^= seed.charCodeAt(i);
21
+ hash = Math.imul(hash, 0x01000193) >>> 0;
22
+ }
23
+ return hash;
24
+ }
25
+ //# sourceMappingURL=random.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"random.js","sourceRoot":"","sources":["../../src/stats/random.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,IAAiC;IAC5D,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC,MAAM,CAAC;IAC3C,IAAI,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IACnC,OAAO,GAAG,EAAE;QACV,KAAK,GAAG,CAAC,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,CAAC,GAAG,KAAK,CAAC;QACd,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACrC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;QAC1C,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,UAAU,CAAC;IAC/C,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY;IAC5B,IAAI,IAAI,GAAG,UAAU,CAAC;IACtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QAC3B,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,5 @@
1
+ /** The rank of each value from 1 up, tied values sharing the mean of their ranks */
2
+ export declare function averageRanks(values: readonly number[]): number[];
3
+ /** The sizes of the groups of tied values, groups of one left out */
4
+ export declare function tieGroups(values: readonly number[]): number[];
5
+ //# sourceMappingURL=ranks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ranks.d.ts","sourceRoot":"","sources":["../../src/stats/ranks.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAYhE;AAED,qEAAqE;AACrE,wBAAgB,SAAS,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAI7D"}
@@ -0,0 +1,24 @@
1
+ /** The rank of each value from 1 up, tied values sharing the mean of their ranks */
2
+ export function averageRanks(values) {
3
+ const order = values.map((value, index) => ({ value, index })).sort((a, b) => a.value - b.value);
4
+ const ranks = new Array(values.length);
5
+ let start = 0;
6
+ while (start < order.length) {
7
+ let end = start;
8
+ while (end + 1 < order.length && order[end + 1].value === order[start].value)
9
+ end++;
10
+ const rank = (start + end) / 2 + 1;
11
+ for (let at = start; at <= end; at++)
12
+ ranks[order[at].index] = rank;
13
+ start = end + 1;
14
+ }
15
+ return ranks;
16
+ }
17
+ /** The sizes of the groups of tied values, groups of one left out */
18
+ export function tieGroups(values) {
19
+ const counts = new Map();
20
+ for (const value of values)
21
+ counts.set(value, (counts.get(value) ?? 0) + 1);
22
+ return [...counts.values()].filter((count) => count > 1);
23
+ }
24
+ //# sourceMappingURL=ranks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ranks.js","sourceRoot":"","sources":["../../src/stats/ranks.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,MAAM,UAAU,YAAY,CAAC,MAAyB;IACpD,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IACjG,MAAM,KAAK,GAAG,IAAI,KAAK,CAAS,MAAM,CAAC,MAAM,CAAC,CAAC;IAC/C,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,OAAO,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;QAC5B,IAAI,GAAG,GAAG,KAAK,CAAC;QAChB,OAAO,GAAG,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,CAAC,CAAC,KAAK;YAAE,GAAG,EAAE,CAAC;QACpF,MAAM,IAAI,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACnC,KAAK,IAAI,EAAE,GAAG,KAAK,EAAE,EAAE,IAAI,GAAG,EAAE,EAAE,EAAE;YAAE,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;QACpE,KAAK,GAAG,GAAG,GAAG,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,SAAS,CAAC,MAAyB;IACjD,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,KAAK,MAAM,KAAK,IAAI,MAAM;QAAE,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5E,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;AAC3D,CAAC"}
@@ -5,5 +5,9 @@ export interface TTestResult {
5
5
  significant: boolean;
6
6
  confidenceInterval: [number, number];
7
7
  }
8
+ /**
9
+ * Paired t-test, two-sided. The differences `a - b` are rounded to 12 significant digits first,
10
+ * so a constant difference with float noise counts as constant
11
+ */
8
12
  export declare function pairedTTest(samplesA: number[], samplesB: number[]): TTestResult;
9
13
  //# sourceMappingURL=t-test.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"t-test.d.ts","sourceRoot":"","sources":["../../src/stats/t-test.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,OAAO,CAAC;IACrB,kBAAkB,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACtC;AAkGD,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,WAAW,CA4C/E"}
1
+ {"version":3,"file":"t-test.d.ts","sourceRoot":"","sources":["../../src/stats/t-test.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,OAAO,CAAC;IACrB,kBAAkB,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACtC;AAkGD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,WAAW,CA6C/E"}
@@ -1,4 +1,5 @@
1
1
  import { mean, stdDev } from './percentiles.js';
2
+ import { isConstant, pairedDifference } from './precision.js';
2
3
  function lnGamma(z) {
3
4
  const g = 7;
4
5
  const coefficients = [
@@ -88,6 +89,10 @@ function tDistQuantile(p, df) {
88
89
  }
89
90
  return (lo + hi) / 2;
90
91
  }
92
+ /**
93
+ * Paired t-test, two-sided. The differences `a - b` are rounded to 12 significant digits first,
94
+ * so a constant difference with float noise counts as constant
95
+ */
91
96
  export function pairedTTest(samplesA, samplesB) {
92
97
  if (samplesA.length !== samplesB.length) {
93
98
  throw new Error('Sample arrays must have equal length');
@@ -98,10 +103,11 @@ export function pairedTTest(samplesA, samplesB) {
98
103
  const n = samplesA.length;
99
104
  const diffs = new Array(n);
100
105
  for (let i = 0; i < n; i++) {
101
- diffs[i] = samplesA[i] - samplesB[i];
106
+ diffs[i] = pairedDifference(samplesA[i], samplesB[i]);
102
107
  }
103
- const meanD = mean(diffs);
104
- const sdD = stdDev(diffs);
108
+ const constant = isConstant(diffs);
109
+ const meanD = constant ? diffs[0] : mean(diffs);
110
+ const sdD = constant ? 0 : stdDev(diffs);
105
111
  const df = n - 1;
106
112
  if (sdD === 0) {
107
113
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"t-test.js","sourceRoot":"","sources":["../../src/stats/t-test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"t-test.js","sourceRoot":"","sources":["../../src/stats/t-test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ export interface WilcoxonResult {
2
+ /** W+: the sum of the ranks of the positive differences `a - b` */
3
+ statistic: number;
4
+ /** Pairs left once the zero differences are dropped */
5
+ n: number;
6
+ pValue: number;
7
+ significant: boolean;
8
+ /** `exact` for up to 20 pairs, `normal` (with tie and continuity corrections) above */
9
+ method: 'exact' | 'normal';
10
+ }
11
+ /**
12
+ * Wilcoxon signed-rank test of paired samples, two-sided. The differences `a - b` are rounded to
13
+ * 12 significant digits first, so float noise neither splits ties nor hides a zero. Zero differences are dropped
14
+ * (Wilcoxon's handling, not Pratt's), tied absolute differences share their mean rank. The
15
+ * p-value is exact for up to 20 nonzero pairs, ties included, and from the normal approximation
16
+ * with tie and continuity corrections above
17
+ */
18
+ export declare function wilcoxonSignedRank(samplesA: readonly number[], samplesB: readonly number[]): WilcoxonResult;
19
+ //# sourceMappingURL=wilcoxon.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wilcoxon.d.ts","sourceRoot":"","sources":["../../src/stats/wilcoxon.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,cAAc;IAC7B,mEAAmE;IACnE,SAAS,EAAE,MAAM,CAAC;IAClB,uDAAuD;IACvD,CAAC,EAAE,MAAM,CAAC;IACV,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,OAAO,CAAC;IACrB,uFAAuF;IACvF,MAAM,EAAE,OAAO,GAAG,QAAQ,CAAC;CAC5B;AAID;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,SAAS,MAAM,EAAE,EAC3B,QAAQ,EAAE,SAAS,MAAM,EAAE,GAC1B,cAAc,CAuBhB"}
@@ -0,0 +1,70 @@
1
+ import { normalTwoSidedP } from './normal.js';
2
+ import { averageRanks, tieGroups } from './ranks.js';
3
+ import { pairedDifference } from './precision.js';
4
+ const EXACT_UP_TO = 20;
5
+ /**
6
+ * Wilcoxon signed-rank test of paired samples, two-sided. The differences `a - b` are rounded to
7
+ * 12 significant digits first, so float noise neither splits ties nor hides a zero. Zero differences are dropped
8
+ * (Wilcoxon's handling, not Pratt's), tied absolute differences share their mean rank. The
9
+ * p-value is exact for up to 20 nonzero pairs, ties included, and from the normal approximation
10
+ * with tie and continuity corrections above
11
+ */
12
+ export function wilcoxonSignedRank(samplesA, samplesB) {
13
+ if (samplesA.length !== samplesB.length) {
14
+ throw new Error('Sample arrays must have equal length');
15
+ }
16
+ const differences = samplesA
17
+ .map((a, i) => pairedDifference(a, samplesB[i]))
18
+ .filter((d) => d !== 0);
19
+ const n = differences.length;
20
+ if (n === 0)
21
+ return { statistic: 0, n: 0, pValue: 1, significant: false, method: 'exact' };
22
+ const magnitudes = differences.map(Math.abs);
23
+ const ranks = averageRanks(magnitudes);
24
+ const statistic = ranks.reduce((sum, rank, i) => (differences[i] > 0 ? sum + rank : sum), 0);
25
+ const pValue = n <= EXACT_UP_TO ? exactP(ranks, statistic) : normalP(n, statistic, tieGroups(magnitudes));
26
+ return {
27
+ statistic,
28
+ n,
29
+ pValue,
30
+ significant: pValue < 0.05,
31
+ method: n <= EXACT_UP_TO ? 'exact' : 'normal',
32
+ };
33
+ }
34
+ /**
35
+ * The exact two-sided p-value of W+ over every assignment of signs to the ranks, counted on
36
+ * doubled ranks so mean ranks of ties stay integers
37
+ */
38
+ function exactP(ranks, statistic) {
39
+ const doubled = ranks.map((rank) => Math.round(rank * 2));
40
+ const total = doubled.reduce((sum, r) => sum + r, 0);
41
+ let counts = new Array(total + 1).fill(0);
42
+ counts[0] = 1;
43
+ for (const r of doubled) {
44
+ const next = [...counts];
45
+ for (let s = 0; s + r <= total; s++)
46
+ next[s + r] += counts[s];
47
+ counts = next;
48
+ }
49
+ const observed = Math.round(statistic * 2);
50
+ const outcomes = 2 ** ranks.length;
51
+ let lower = 0;
52
+ let upper = 0;
53
+ for (let s = 0; s <= total; s++) {
54
+ if (s <= observed)
55
+ lower += counts[s];
56
+ if (s >= observed)
57
+ upper += counts[s];
58
+ }
59
+ return Math.min(1, (2 * Math.min(lower, upper)) / outcomes);
60
+ }
61
+ function normalP(n, statistic, ties) {
62
+ const expected = (n * (n + 1)) / 4;
63
+ const tieCorrection = ties.reduce((sum, t) => sum + (t ** 3 - t), 0) / 48;
64
+ const variance = (n * (n + 1) * (2 * n + 1)) / 24 - tieCorrection;
65
+ if (variance <= 0)
66
+ return 1;
67
+ const distance = Math.max(0, Math.abs(statistic - expected) - 0.5);
68
+ return normalTwoSidedP(distance / Math.sqrt(variance));
69
+ }
70
+ //# sourceMappingURL=wilcoxon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wilcoxon.js","sourceRoot":"","sources":["../../src/stats/wilcoxon.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cogitator-ai/evals",
3
- "version": "0.11.0",
3
+ "version": "0.13.0",
4
4
  "description": "Evaluation framework for Cogitator AI agents",
5
5
  "keywords": [
6
6
  "cogitator",