pragmastat 6.0.0 → 7.0.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 (54) hide show
  1. package/README.md +33 -23
  2. package/dist/assumptions.d.ts +13 -10
  3. package/dist/assumptions.d.ts.map +1 -1
  4. package/dist/assumptions.js +22 -16
  5. package/dist/assumptions.js.map +1 -1
  6. package/dist/distributions/additive.d.ts +1 -1
  7. package/dist/distributions/additive.js +1 -1
  8. package/dist/distributions/exp.d.ts +1 -1
  9. package/dist/distributions/exp.js +1 -1
  10. package/dist/distributions/multiplic.d.ts +1 -1
  11. package/dist/distributions/multiplic.js +1 -1
  12. package/dist/distributions/power.d.ts +1 -1
  13. package/dist/distributions/power.js +1 -1
  14. package/dist/distributions/uniform.d.ts +1 -1
  15. package/dist/distributions/uniform.js +1 -1
  16. package/dist/estimators.d.ts +17 -0
  17. package/dist/estimators.d.ts.map +1 -1
  18. package/dist/estimators.js +98 -25
  19. package/dist/estimators.js.map +1 -1
  20. package/dist/fastCenterQuantiles.d.ts +15 -0
  21. package/dist/fastCenterQuantiles.d.ts.map +1 -0
  22. package/dist/fastCenterQuantiles.js +125 -0
  23. package/dist/fastCenterQuantiles.js.map +1 -0
  24. package/dist/fastShift.js +2 -2
  25. package/dist/fastShift.js.map +1 -1
  26. package/dist/gaussCdf.d.ts +16 -0
  27. package/dist/gaussCdf.d.ts.map +1 -0
  28. package/dist/gaussCdf.js +76 -0
  29. package/dist/gaussCdf.js.map +1 -0
  30. package/dist/index.d.ts +2 -2
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +5 -3
  33. package/dist/index.js.map +1 -1
  34. package/dist/minMisrate.d.ts +23 -0
  35. package/dist/minMisrate.d.ts.map +1 -0
  36. package/dist/minMisrate.js +58 -0
  37. package/dist/minMisrate.js.map +1 -0
  38. package/dist/pairwiseMargin.d.ts +1 -1
  39. package/dist/pairwiseMargin.d.ts.map +1 -1
  40. package/dist/pairwiseMargin.js +14 -75
  41. package/dist/pairwiseMargin.js.map +1 -1
  42. package/dist/rng.d.ts +15 -8
  43. package/dist/rng.d.ts.map +1 -1
  44. package/dist/rng.js +29 -8
  45. package/dist/rng.js.map +1 -1
  46. package/dist/signedRankMargin.d.ts +17 -0
  47. package/dist/signedRankMargin.d.ts.map +1 -0
  48. package/dist/signedRankMargin.js +114 -0
  49. package/dist/signedRankMargin.js.map +1 -0
  50. package/package.json +5 -5
  51. package/dist/utils.d.ts +0 -10
  52. package/dist/utils.d.ts.map +0 -1
  53. package/dist/utils.js +0 -25
  54. package/dist/utils.js.map +0 -1
package/README.md CHANGED
@@ -3,10 +3,10 @@
3
3
  Install from npm:
4
4
 
5
5
  ```bash
6
- npm i pragmastat@6.0.0
6
+ npm i pragmastat@7.0.0
7
7
  ```
8
8
 
9
- Source code: https://github.com/AndreyAkinshin/pragmastat/tree/v6.0.0/ts
9
+ Source code: https://github.com/AndreyAkinshin/pragmastat/tree/v7.0.0/ts
10
10
 
11
11
  Pragmastat on npm: https://www.npmjs.com/package/pragmastat
12
12
 
@@ -14,47 +14,49 @@ Pragmastat on npm: https://www.npmjs.com/package/pragmastat
14
14
 
15
15
  ```typescript
16
16
  import {
17
- median, center, spread, relSpread, shift, ratio, avgSpread, disparity, shiftBounds, ratioBounds, pairwiseMargin,
17
+ median, center, spread, relSpread, shift, ratio, avgSpread, disparity,
18
+ signedRankMargin, pairwiseMargin,
19
+ centerBounds, shiftBounds, ratioBounds,
18
20
  Rng, Uniform, Additive, Exp, Power, Multiplic
19
21
  } from '../src';
20
22
 
21
23
  function main() {
22
24
  // --- Randomization ---
23
25
 
24
- let rng = new Rng(1729);
25
- console.log(rng.uniform()); // 0.3943034703296536
26
- console.log(rng.uniform()); // 0.5730893757071377
26
+ let rng = new Rng("demo-uniform");
27
+ console.log(rng.uniform()); // 0.2640554428629759
28
+ console.log(rng.uniform()); // 0.9348534835582796
27
29
 
28
- rng = new Rng("experiment-1");
29
- console.log(rng.uniform()); // 0.9535207726895857
30
+ rng = new Rng("demo-sample");
31
+ console.log(rng.sample([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 3)); // [3, 8, 9]
30
32
 
31
- rng = new Rng(1729);
32
- console.log(rng.sample([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 3)); // [6, 8, 9]
33
-
34
- rng = new Rng(1729);
33
+ rng = new Rng("demo-shuffle");
35
34
  console.log(rng.shuffle([1, 2, 3, 4, 5])); // [4, 2, 3, 5, 1]
36
35
 
36
+ rng = new Rng("demo-resample");
37
+ console.log(rng.resample([1, 2, 3, 4, 5], 7)); // [5, 1, 1, 3, 3, 4, 5]
38
+
37
39
  // --- Distribution Sampling ---
38
40
 
39
- rng = new Rng(1729);
41
+ rng = new Rng("demo-dist-uniform");
40
42
  let dist = new Uniform(0, 10);
41
- console.log(dist.sample(rng)); // 3.9430347032965365
43
+ console.log(dist.sample(rng)); // 6.54043657816832
42
44
 
43
- rng = new Rng(1729);
45
+ rng = new Rng("demo-dist-additive");
44
46
  let addDist = new Additive(0, 1);
45
- console.log(addDist.sample(rng)); // -1.222932972163442
47
+ console.log(addDist.sample(rng)); // 0.17410448679568188
46
48
 
47
- rng = new Rng(1729);
49
+ rng = new Rng("demo-dist-exp");
48
50
  let expDist = new Exp(1);
49
- console.log(expDist.sample(rng)); // 0.5013761944646019
51
+ console.log(expDist.sample(rng)); // 0.6589065267276553
50
52
 
51
- rng = new Rng(1729);
53
+ rng = new Rng("demo-dist-power");
52
54
  let powDist = new Power(1, 2);
53
- console.log(powDist.sample(rng)); // 1.284909255071668
55
+ console.log(powDist.sample(rng)); // 1.023677535537084
54
56
 
55
- rng = new Rng(1729);
57
+ rng = new Rng("demo-dist-multiplic");
56
58
  let mulDist = new Multiplic(0, 1);
57
- console.log(mulDist.sample(rng)); // 0.2943655336550937
59
+ console.log(mulDist.sample(rng)); // 1.1273244602673853
58
60
 
59
61
  // --- Single-Sample Statistics ---
60
62
 
@@ -83,7 +85,15 @@ function main() {
83
85
  console.log(ratio(x, y)); // 0.5
84
86
  console.log(ratio(y, x)); // 2
85
87
 
86
- // --- Confidence Bounds ---
88
+ // --- One-Sample Bounds ---
89
+
90
+ x = Array.from({ length: 10 }, (_, i) => i + 1);
91
+
92
+ console.log(signedRankMargin(10, 0.05)); // 18
93
+ console.log(center(x)); // 5.5
94
+ console.log(centerBounds(x, 0.05)); // { lower: 3.5, upper: 7.5 }
95
+
96
+ // --- Two-Sample Bounds ---
87
97
 
88
98
  x = Array.from({ length: 30 }, (_, i) => i + 1);
89
99
  y = Array.from({ length: 30 }, (_, i) => i + 21);
@@ -3,19 +3,21 @@
3
3
  *
4
4
  * Assumption IDs (canonical priority order):
5
5
  * 1. validity - non-empty input with finite defined real values
6
- * 2. positivity - values must be strictly positive
7
- * 3. sparity - sample must be non tie-dominant (Spread > 0)
6
+ * 2. domain - parameter is outside its valid domain
7
+ * 3. positivity - values must be strictly positive
8
+ * 4. sparity - sample must be non tie-dominant (Spread > 0)
8
9
  *
9
10
  * When multiple assumptions are violated, the violation with highest priority
10
11
  * is reported. For two-sample functions, subject X is checked before Y.
11
12
  */
12
13
  export declare const AssumptionId: {
13
14
  readonly VALIDITY: "validity";
15
+ readonly DOMAIN: "domain";
14
16
  readonly POSITIVITY: "positivity";
15
17
  readonly SPARITY: "sparity";
16
18
  };
17
19
  export type AssumptionId = (typeof AssumptionId)[keyof typeof AssumptionId];
18
- export type Subject = 'x' | 'y';
20
+ export type Subject = 'x' | 'y' | 'misrate';
19
21
  export interface Violation {
20
22
  id: AssumptionId;
21
23
  subject: Subject;
@@ -23,15 +25,16 @@ export interface Violation {
23
25
  export declare class AssumptionError extends Error {
24
26
  readonly violation: Violation;
25
27
  constructor(violation: Violation);
26
- static validity(_functionName: string, subject: Subject): AssumptionError;
27
- static positivity(_functionName: string, subject: Subject): AssumptionError;
28
- static sparity(_functionName: string, subject: Subject): AssumptionError;
28
+ static validity(subject: Subject): AssumptionError;
29
+ static positivity(subject: Subject): AssumptionError;
30
+ static sparity(subject: Subject): AssumptionError;
31
+ static domain(subject: Subject): AssumptionError;
29
32
  }
30
- export declare function checkValidity(values: number[], subject: Subject, functionName: string): void;
31
- export declare function checkPositivity(values: number[], subject: Subject, functionName: string): void;
32
- export declare function checkSparity(values: number[], subject: Subject, functionName: string): void;
33
+ export declare function checkValidity(values: number[], subject: Subject): void;
34
+ export declare function checkPositivity(values: number[], subject: Subject): void;
35
+ export declare function checkSparity(values: number[], subject: Subject): void;
33
36
  /**
34
37
  * Log-transforms an array. Throws AssumptionError if any value is non-positive.
35
38
  */
36
- export declare function log(values: number[], subject: Subject, functionName: string): number[];
39
+ export declare function log(values: number[], subject: Subject): number[];
37
40
  //# sourceMappingURL=assumptions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"assumptions.d.ts","sourceRoot":"","sources":["../src/assumptions.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AAEH,eAAO,MAAM,YAAY;;;;CAIf,CAAC;AAEX,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,OAAO,YAAY,CAAC,CAAC;AAE5E,MAAM,MAAM,OAAO,GAAG,GAAG,GAAG,GAAG,CAAC;AAEhC,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,YAAY,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,qBAAa,eAAgB,SAAQ,KAAK;IACxC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;gBAElB,SAAS,EAAE,SAAS;IAMhC,MAAM,CAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,eAAe;IAIzE,MAAM,CAAC,UAAU,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,eAAe;IAI3E,MAAM,CAAC,OAAO,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,eAAe;CAGzE;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAO5F;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAI9F;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAQ3F;AAED;;GAEG;AACH,wBAAgB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,EAAE,CAStF"}
1
+ {"version":3,"file":"assumptions.d.ts","sourceRoot":"","sources":["../src/assumptions.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;GAWG;AAEH,eAAO,MAAM,YAAY;;;;;CAKf,CAAC;AAEX,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,OAAO,YAAY,CAAC,CAAC;AAE5E,MAAM,MAAM,OAAO,GAAG,GAAG,GAAG,GAAG,GAAG,SAAS,CAAC;AAE5C,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,YAAY,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,qBAAa,eAAgB,SAAQ,KAAK;IACxC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;gBAElB,SAAS,EAAE,SAAS;IAOhC,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,eAAe;IAIlD,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,eAAe;IAIpD,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,eAAe;IAIjD,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,eAAe;CAGjD;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAOtE;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAIxE;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAQrE;AAED;;GAEG;AACH,wBAAgB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,EAAE,CAShE"}
@@ -11,64 +11,70 @@ const fastSpread_1 = require("./fastSpread");
11
11
  *
12
12
  * Assumption IDs (canonical priority order):
13
13
  * 1. validity - non-empty input with finite defined real values
14
- * 2. positivity - values must be strictly positive
15
- * 3. sparity - sample must be non tie-dominant (Spread > 0)
14
+ * 2. domain - parameter is outside its valid domain
15
+ * 3. positivity - values must be strictly positive
16
+ * 4. sparity - sample must be non tie-dominant (Spread > 0)
16
17
  *
17
18
  * When multiple assumptions are violated, the violation with highest priority
18
19
  * is reported. For two-sample functions, subject X is checked before Y.
19
20
  */
20
21
  exports.AssumptionId = {
21
22
  VALIDITY: 'validity',
23
+ DOMAIN: 'domain',
22
24
  POSITIVITY: 'positivity',
23
25
  SPARITY: 'sparity',
24
26
  };
25
27
  class AssumptionError extends Error {
26
28
  constructor(violation) {
27
- super(`${violation.id}(${violation.subject})`);
29
+ const violationStr = `${violation.id}(${violation.subject})`;
30
+ super(violationStr);
28
31
  this.name = 'AssumptionError';
29
32
  this.violation = violation;
30
33
  }
31
- static validity(_functionName, subject) {
34
+ static validity(subject) {
32
35
  return new AssumptionError({ id: exports.AssumptionId.VALIDITY, subject });
33
36
  }
34
- static positivity(_functionName, subject) {
37
+ static positivity(subject) {
35
38
  return new AssumptionError({ id: exports.AssumptionId.POSITIVITY, subject });
36
39
  }
37
- static sparity(_functionName, subject) {
40
+ static sparity(subject) {
38
41
  return new AssumptionError({ id: exports.AssumptionId.SPARITY, subject });
39
42
  }
43
+ static domain(subject) {
44
+ return new AssumptionError({ id: exports.AssumptionId.DOMAIN, subject });
45
+ }
40
46
  }
41
47
  exports.AssumptionError = AssumptionError;
42
- function checkValidity(values, subject, functionName) {
48
+ function checkValidity(values, subject) {
43
49
  if (values.length === 0) {
44
- throw AssumptionError.validity(functionName, subject);
50
+ throw AssumptionError.validity(subject);
45
51
  }
46
52
  if (!values.every((v) => Number.isFinite(v))) {
47
- throw AssumptionError.validity(functionName, subject);
53
+ throw AssumptionError.validity(subject);
48
54
  }
49
55
  }
50
- function checkPositivity(values, subject, functionName) {
56
+ function checkPositivity(values, subject) {
51
57
  if (values.some((v) => v <= 0)) {
52
- throw AssumptionError.positivity(functionName, subject);
58
+ throw AssumptionError.positivity(subject);
53
59
  }
54
60
  }
55
- function checkSparity(values, subject, functionName) {
61
+ function checkSparity(values, subject) {
56
62
  if (values.length < 2) {
57
- throw AssumptionError.sparity(functionName, subject);
63
+ throw AssumptionError.sparity(subject);
58
64
  }
59
65
  const spread = (0, fastSpread_1.fastSpread)(values);
60
66
  if (spread <= 0) {
61
- throw AssumptionError.sparity(functionName, subject);
67
+ throw AssumptionError.sparity(subject);
62
68
  }
63
69
  }
64
70
  /**
65
71
  * Log-transforms an array. Throws AssumptionError if any value is non-positive.
66
72
  */
67
- function log(values, subject, functionName) {
73
+ function log(values, subject) {
68
74
  const result = new Array(values.length);
69
75
  for (let i = 0; i < values.length; i++) {
70
76
  if (values[i] <= 0) {
71
- throw AssumptionError.positivity(functionName, subject);
77
+ throw AssumptionError.positivity(subject);
72
78
  }
73
79
  result[i] = Math.log(values[i]);
74
80
  }
@@ -1 +1 @@
1
- {"version":3,"file":"assumptions.js","sourceRoot":"","sources":["../src/assumptions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"assumptions.js","sourceRoot":"","sources":["../src/assumptions.ts"],"names":[],"mappings":"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"}
@@ -9,7 +9,7 @@ import { Distribution } from './distribution';
9
9
  * Uses the Box-Muller transform to generate samples.
10
10
  *
11
11
  * @example
12
- * const rng = new Rng(1729);
12
+ * const rng = new Rng("demo-dist-additive");
13
13
  * const dist = new Additive(0, 1); // Standard normal
14
14
  * const sample = dist.sample(rng);
15
15
  */
@@ -11,7 +11,7 @@ const constants_1 = require("../constants");
11
11
  * Uses the Box-Muller transform to generate samples.
12
12
  *
13
13
  * @example
14
- * const rng = new Rng(1729);
14
+ * const rng = new Rng("demo-dist-additive");
15
15
  * const dist = new Additive(0, 1); // Standard normal
16
16
  * const sample = dist.sample(rng);
17
17
  */
@@ -9,7 +9,7 @@ import { Distribution } from './distribution';
9
9
  * The mean of this distribution is 1/rate.
10
10
  *
11
11
  * @example
12
- * const rng = new Rng(1729);
12
+ * const rng = new Rng("demo-dist-exp");
13
13
  * const dist = new Exp(1); // rate=1, mean=1
14
14
  * const sample = dist.sample(rng);
15
15
  */
@@ -11,7 +11,7 @@ const constants_1 = require("../constants");
11
11
  * The mean of this distribution is 1/rate.
12
12
  *
13
13
  * @example
14
- * const rng = new Rng(1729);
14
+ * const rng = new Rng("demo-dist-exp");
15
15
  * const dist = new Exp(1); // rate=1, mean=1
16
16
  * const sample = dist.sample(rng);
17
17
  */
@@ -9,7 +9,7 @@ import { Distribution } from './distribution';
9
9
  * The logarithm of samples follows an Additive (Normal) distribution.
10
10
  *
11
11
  * @example
12
- * const rng = new Rng(1729);
12
+ * const rng = new Rng("demo-dist-multiplic");
13
13
  * const dist = new Multiplic(0, 1);
14
14
  * const sample = dist.sample(rng);
15
15
  */
@@ -11,7 +11,7 @@ const additive_1 = require("./additive");
11
11
  * The logarithm of samples follows an Additive (Normal) distribution.
12
12
  *
13
13
  * @example
14
- * const rng = new Rng(1729);
14
+ * const rng = new Rng("demo-dist-multiplic");
15
15
  * const dist = new Multiplic(0, 1);
16
16
  * const sample = dist.sample(rng);
17
17
  */
@@ -9,7 +9,7 @@ import { Distribution } from './distribution';
9
9
  * Follows a power-law distribution where large values are rare but possible.
10
10
  *
11
11
  * @example
12
- * const rng = new Rng(1729);
12
+ * const rng = new Rng("demo-dist-power");
13
13
  * const dist = new Power(1, 2); // min=1, shape=2
14
14
  * const sample = dist.sample(rng);
15
15
  */
@@ -11,7 +11,7 @@ const constants_1 = require("../constants");
11
11
  * Follows a power-law distribution where large values are rare but possible.
12
12
  *
13
13
  * @example
14
- * const rng = new Rng(1729);
14
+ * const rng = new Rng("demo-dist-power");
15
15
  * const dist = new Power(1, 2); // min=1, shape=2
16
16
  * const sample = dist.sample(rng);
17
17
  */
@@ -7,7 +7,7 @@ import { Distribution } from './distribution';
7
7
  * Uniform distribution on [min, max).
8
8
  *
9
9
  * @example
10
- * const rng = new Rng(1729);
10
+ * const rng = new Rng("demo-dist-uniform");
11
11
  * const dist = new Uniform(0, 10);
12
12
  * const sample = dist.sample(rng);
13
13
  */
@@ -8,7 +8,7 @@ exports.Uniform = void 0;
8
8
  * Uniform distribution on [min, max).
9
9
  *
10
10
  * @example
11
- * const rng = new Rng(1729);
11
+ * const rng = new Rng("demo-dist-uniform");
12
12
  * const dist = new Uniform(0, 10);
13
13
  * const sample = dist.sample(rng);
14
14
  */
@@ -1,6 +1,12 @@
1
1
  /**
2
2
  * Pragmastat estimators implementation
3
3
  */
4
+ /**
5
+ * Calculate the median of an array of numbers
6
+ * @param values Array of numbers
7
+ * @returns The median value
8
+ */
9
+ export declare function median(values: number[]): number;
4
10
  /**
5
11
  * Calculate the Center - median of all pairwise averages (x[i] + x[j])/2
6
12
  * Uses fast O(n log n) algorithm.
@@ -117,4 +123,15 @@ export declare function shiftBounds(x: number[], y: number[], misrate: number):
117
123
  * @throws AssumptionError if either sample is empty, contains NaN/Inf, or contains non-positive values
118
124
  */
119
125
  export declare function ratioBounds(x: number[], y: number[], misrate: number): Bounds;
126
+ /**
127
+ * Provides exact bounds on the Center (Hodges-Lehmann pseudomedian) with specified misclassification rate
128
+ *
129
+ * Uses SignedRankMargin to determine which pairwise averages form the bounds.
130
+ *
131
+ * @param x Sample array
132
+ * @param misrate Misclassification rate (probability that true center falls outside bounds)
133
+ * @returns An object containing the lower and upper bounds
134
+ * @throws AssumptionError if sample is empty or contains NaN/Inf
135
+ */
136
+ export declare function centerBounds(x: number[], misrate: number): Bounds;
120
137
  //# sourceMappingURL=estimators.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"estimators.d.ts","sourceRoot":"","sources":["../src/estimators.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAI1C;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAM1C;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAW7C;AAED;;;;;;GAMG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAMtD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAWtD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAkB1D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAqB1D;AAED;;GAEG;AACH,MAAM,WAAW,MAAM;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAqC7E;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAgB7E"}
1
+ {"version":3,"file":"estimators.d.ts","sourceRoot":"","sources":["../src/estimators.ts"],"names":[],"mappings":"AAAA;;GAEG;AAWH;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAY/C;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAI1C;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAM1C;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAW7C;AAED;;;;;;GAMG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAMtD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAWtD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAkB1D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAqB1D;AAED;;GAEG;AACH,MAAM,WAAW,MAAM;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CA8C7E;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAyB7E;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAmCjE"}
@@ -3,6 +3,7 @@
3
3
  * Pragmastat estimators implementation
4
4
  */
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.median = median;
6
7
  exports.center = center;
7
8
  exports.spread = spread;
8
9
  exports.relSpread = relSpread;
@@ -12,11 +13,32 @@ exports.avgSpread = avgSpread;
12
13
  exports.disparity = disparity;
13
14
  exports.shiftBounds = shiftBounds;
14
15
  exports.ratioBounds = ratioBounds;
16
+ exports.centerBounds = centerBounds;
15
17
  const fastCenter_1 = require("./fastCenter");
16
18
  const fastSpread_1 = require("./fastSpread");
17
19
  const fastShift_1 = require("./fastShift");
18
20
  const pairwiseMargin_1 = require("./pairwiseMargin");
21
+ const signedRankMargin_1 = require("./signedRankMargin");
22
+ const fastCenterQuantiles_1 = require("./fastCenterQuantiles");
23
+ const minMisrate_1 = require("./minMisrate");
19
24
  const assumptions_1 = require("./assumptions");
25
+ /**
26
+ * Calculate the median of an array of numbers
27
+ * @param values Array of numbers
28
+ * @returns The median value
29
+ */
30
+ function median(values) {
31
+ // Check validity (priority 0)
32
+ (0, assumptions_1.checkValidity)(values, 'x');
33
+ const sorted = [...values].sort((a, b) => a - b);
34
+ const mid = Math.floor(sorted.length / 2);
35
+ if (sorted.length % 2 === 0) {
36
+ return (sorted[mid - 1] + sorted[mid]) / 2;
37
+ }
38
+ else {
39
+ return sorted[mid];
40
+ }
41
+ }
20
42
  /**
21
43
  * Calculate the Center - median of all pairwise averages (x[i] + x[j])/2
22
44
  * Uses fast O(n log n) algorithm.
@@ -25,7 +47,7 @@ const assumptions_1 = require("./assumptions");
25
47
  */
26
48
  function center(x) {
27
49
  // Check validity (priority 0)
28
- (0, assumptions_1.checkValidity)(x, 'x', 'Center');
50
+ (0, assumptions_1.checkValidity)(x, 'x');
29
51
  return (0, fastCenter_1.fastCenter)(x);
30
52
  }
31
53
  /**
@@ -41,9 +63,9 @@ function center(x) {
41
63
  */
42
64
  function spread(x) {
43
65
  // Check validity (priority 0)
44
- (0, assumptions_1.checkValidity)(x, 'x', 'Spread');
66
+ (0, assumptions_1.checkValidity)(x, 'x');
45
67
  // Check sparity (priority 2)
46
- (0, assumptions_1.checkSparity)(x, 'x', 'Spread');
68
+ (0, assumptions_1.checkSparity)(x, 'x');
47
69
  return (0, fastSpread_1.fastSpread)(x);
48
70
  }
49
71
  /**
@@ -58,9 +80,9 @@ function spread(x) {
58
80
  */
59
81
  function relSpread(x) {
60
82
  // Check validity (priority 0)
61
- (0, assumptions_1.checkValidity)(x, 'x', 'RelSpread');
83
+ (0, assumptions_1.checkValidity)(x, 'x');
62
84
  // Check positivity (priority 1)
63
- (0, assumptions_1.checkPositivity)(x, 'x', 'RelSpread');
85
+ (0, assumptions_1.checkPositivity)(x, 'x');
64
86
  // Calculate center (we know x is valid, center should succeed)
65
87
  const c = (0, fastCenter_1.fastCenter)(x);
66
88
  // Calculate spread (using internal implementation since we already validated)
@@ -77,8 +99,8 @@ function relSpread(x) {
77
99
  */
78
100
  function shift(x, y) {
79
101
  // Check validity (priority 0)
80
- (0, assumptions_1.checkValidity)(x, 'x', 'Shift');
81
- (0, assumptions_1.checkValidity)(y, 'y', 'Shift');
102
+ (0, assumptions_1.checkValidity)(x, 'x');
103
+ (0, assumptions_1.checkValidity)(y, 'y');
82
104
  return (0, fastShift_1.fastShift)(x, y, [0.5], false)[0];
83
105
  }
84
106
  /**
@@ -97,13 +119,13 @@ function shift(x, y) {
97
119
  */
98
120
  function ratio(x, y) {
99
121
  // Check validity for x (priority 0, subject x)
100
- (0, assumptions_1.checkValidity)(x, 'x', 'Ratio');
122
+ (0, assumptions_1.checkValidity)(x, 'x');
101
123
  // Check validity for y (priority 0, subject y)
102
- (0, assumptions_1.checkValidity)(y, 'y', 'Ratio');
124
+ (0, assumptions_1.checkValidity)(y, 'y');
103
125
  // Check positivity for x (priority 1, subject x)
104
- (0, assumptions_1.checkPositivity)(x, 'x', 'Ratio');
126
+ (0, assumptions_1.checkPositivity)(x, 'x');
105
127
  // Check positivity for y (priority 1, subject y)
106
- (0, assumptions_1.checkPositivity)(y, 'y', 'Ratio');
128
+ (0, assumptions_1.checkPositivity)(y, 'y');
107
129
  return (0, fastShift_1.fastRatio)(x, y, [0.5], false)[0];
108
130
  }
109
131
  /**
@@ -120,13 +142,13 @@ function ratio(x, y) {
120
142
  */
121
143
  function avgSpread(x, y) {
122
144
  // Check validity for x (priority 0, subject x)
123
- (0, assumptions_1.checkValidity)(x, 'x', 'AvgSpread');
145
+ (0, assumptions_1.checkValidity)(x, 'x');
124
146
  // Check validity for y (priority 0, subject y)
125
- (0, assumptions_1.checkValidity)(y, 'y', 'AvgSpread');
147
+ (0, assumptions_1.checkValidity)(y, 'y');
126
148
  // Check sparity for x (priority 2, subject x)
127
- (0, assumptions_1.checkSparity)(x, 'x', 'AvgSpread');
149
+ (0, assumptions_1.checkSparity)(x, 'x');
128
150
  // Check sparity for y (priority 2, subject y)
129
- (0, assumptions_1.checkSparity)(y, 'y', 'AvgSpread');
151
+ (0, assumptions_1.checkSparity)(y, 'y');
130
152
  const nx = x.length;
131
153
  const ny = y.length;
132
154
  // Calculate spreads (using internal implementation since we already validated)
@@ -148,13 +170,13 @@ function avgSpread(x, y) {
148
170
  */
149
171
  function disparity(x, y) {
150
172
  // Check validity for x (priority 0, subject x)
151
- (0, assumptions_1.checkValidity)(x, 'x', 'Disparity');
173
+ (0, assumptions_1.checkValidity)(x, 'x');
152
174
  // Check validity for y (priority 0, subject y)
153
- (0, assumptions_1.checkValidity)(y, 'y', 'Disparity');
175
+ (0, assumptions_1.checkValidity)(y, 'y');
154
176
  // Check sparity for x (priority 2, subject x)
155
- (0, assumptions_1.checkSparity)(x, 'x', 'Disparity');
177
+ (0, assumptions_1.checkSparity)(x, 'x');
156
178
  // Check sparity for y (priority 2, subject y)
157
- (0, assumptions_1.checkSparity)(y, 'y', 'Disparity');
179
+ (0, assumptions_1.checkSparity)(y, 'y');
158
180
  const nx = x.length;
159
181
  const ny = y.length;
160
182
  // Calculate shift (we know inputs are valid)
@@ -179,11 +201,18 @@ function disparity(x, y) {
179
201
  */
180
202
  function shiftBounds(x, y, misrate) {
181
203
  // Check validity for x
182
- (0, assumptions_1.checkValidity)(x, 'x', 'ShiftBounds');
204
+ (0, assumptions_1.checkValidity)(x, 'x');
183
205
  // Check validity for y
184
- (0, assumptions_1.checkValidity)(y, 'y', 'ShiftBounds');
206
+ (0, assumptions_1.checkValidity)(y, 'y');
185
207
  const n = x.length;
186
208
  const m = y.length;
209
+ if (isNaN(misrate) || misrate < 0 || misrate > 1) {
210
+ throw assumptions_1.AssumptionError.domain('misrate');
211
+ }
212
+ const minMisrate = (0, minMisrate_1.minAchievableMisrateTwoSample)(n, m);
213
+ if (misrate < minMisrate) {
214
+ throw assumptions_1.AssumptionError.domain('misrate');
215
+ }
187
216
  // Sort both arrays
188
217
  const xs = [...x].sort((a, b) => a - b);
189
218
  const ys = [...y].sort((a, b) => a - b);
@@ -224,11 +253,18 @@ function shiftBounds(x, y, misrate) {
224
253
  * @throws AssumptionError if either sample is empty, contains NaN/Inf, or contains non-positive values
225
254
  */
226
255
  function ratioBounds(x, y, misrate) {
227
- (0, assumptions_1.checkValidity)(x, 'x', 'RatioBounds');
228
- (0, assumptions_1.checkValidity)(y, 'y', 'RatioBounds');
256
+ (0, assumptions_1.checkValidity)(x, 'x');
257
+ (0, assumptions_1.checkValidity)(y, 'y');
258
+ if (isNaN(misrate) || misrate < 0 || misrate > 1) {
259
+ throw assumptions_1.AssumptionError.domain('misrate');
260
+ }
261
+ const minMisrate = (0, minMisrate_1.minAchievableMisrateTwoSample)(x.length, y.length);
262
+ if (misrate < minMisrate) {
263
+ throw assumptions_1.AssumptionError.domain('misrate');
264
+ }
229
265
  // Log-transform samples (includes positivity check)
230
- const logX = (0, assumptions_1.log)(x, 'x', 'RatioBounds');
231
- const logY = (0, assumptions_1.log)(y, 'y', 'RatioBounds');
266
+ const logX = (0, assumptions_1.log)(x, 'x');
267
+ const logY = (0, assumptions_1.log)(y, 'y');
232
268
  // Delegate to shiftBounds in log-space
233
269
  const logBounds = shiftBounds(logX, logY, misrate);
234
270
  // Exp-transform back to ratio-space
@@ -237,4 +273,41 @@ function ratioBounds(x, y, misrate) {
237
273
  upper: Math.exp(logBounds.upper),
238
274
  };
239
275
  }
276
+ /**
277
+ * Provides exact bounds on the Center (Hodges-Lehmann pseudomedian) with specified misclassification rate
278
+ *
279
+ * Uses SignedRankMargin to determine which pairwise averages form the bounds.
280
+ *
281
+ * @param x Sample array
282
+ * @param misrate Misclassification rate (probability that true center falls outside bounds)
283
+ * @returns An object containing the lower and upper bounds
284
+ * @throws AssumptionError if sample is empty or contains NaN/Inf
285
+ */
286
+ function centerBounds(x, misrate) {
287
+ (0, assumptions_1.checkValidity)(x, 'x');
288
+ if (isNaN(misrate) || misrate < 0 || misrate > 1) {
289
+ throw assumptions_1.AssumptionError.domain('misrate');
290
+ }
291
+ const n = x.length;
292
+ if (n < 2) {
293
+ throw assumptions_1.AssumptionError.domain('x');
294
+ }
295
+ // Validate misrate
296
+ const minMisrate = (0, minMisrate_1.minAchievableMisrateOneSample)(n);
297
+ if (misrate < minMisrate) {
298
+ throw assumptions_1.AssumptionError.domain('misrate');
299
+ }
300
+ // Total number of pairwise averages (including self-pairs)
301
+ const totalPairs = (n * (n + 1)) / 2;
302
+ // Get signed-rank margin
303
+ const margin = (0, signedRankMargin_1.signedRankMargin)(n, misrate);
304
+ const halfMargin = Math.min(Math.floor(margin / 2), Math.floor((totalPairs - 1) / 2));
305
+ // k_left and k_right are 1-based ranks
306
+ const kLeft = halfMargin + 1;
307
+ const kRight = totalPairs - halfMargin;
308
+ // Sort the input
309
+ const sorted = [...x].sort((a, b) => a - b);
310
+ const [lo, hi] = (0, fastCenterQuantiles_1.fastCenterQuantileBounds)(sorted, kLeft, kRight);
311
+ return { lower: lo, upper: hi };
312
+ }
240
313
  //# sourceMappingURL=estimators.js.map