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.
- package/README.md +33 -23
- package/dist/assumptions.d.ts +13 -10
- package/dist/assumptions.d.ts.map +1 -1
- package/dist/assumptions.js +22 -16
- package/dist/assumptions.js.map +1 -1
- package/dist/distributions/additive.d.ts +1 -1
- package/dist/distributions/additive.js +1 -1
- package/dist/distributions/exp.d.ts +1 -1
- package/dist/distributions/exp.js +1 -1
- package/dist/distributions/multiplic.d.ts +1 -1
- package/dist/distributions/multiplic.js +1 -1
- package/dist/distributions/power.d.ts +1 -1
- package/dist/distributions/power.js +1 -1
- package/dist/distributions/uniform.d.ts +1 -1
- package/dist/distributions/uniform.js +1 -1
- package/dist/estimators.d.ts +17 -0
- package/dist/estimators.d.ts.map +1 -1
- package/dist/estimators.js +98 -25
- package/dist/estimators.js.map +1 -1
- package/dist/fastCenterQuantiles.d.ts +15 -0
- package/dist/fastCenterQuantiles.d.ts.map +1 -0
- package/dist/fastCenterQuantiles.js +125 -0
- package/dist/fastCenterQuantiles.js.map +1 -0
- package/dist/fastShift.js +2 -2
- package/dist/fastShift.js.map +1 -1
- package/dist/gaussCdf.d.ts +16 -0
- package/dist/gaussCdf.d.ts.map +1 -0
- package/dist/gaussCdf.js +76 -0
- package/dist/gaussCdf.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/minMisrate.d.ts +23 -0
- package/dist/minMisrate.d.ts.map +1 -0
- package/dist/minMisrate.js +58 -0
- package/dist/minMisrate.js.map +1 -0
- package/dist/pairwiseMargin.d.ts +1 -1
- package/dist/pairwiseMargin.d.ts.map +1 -1
- package/dist/pairwiseMargin.js +14 -75
- package/dist/pairwiseMargin.js.map +1 -1
- package/dist/rng.d.ts +15 -8
- package/dist/rng.d.ts.map +1 -1
- package/dist/rng.js +29 -8
- package/dist/rng.js.map +1 -1
- package/dist/signedRankMargin.d.ts +17 -0
- package/dist/signedRankMargin.d.ts.map +1 -0
- package/dist/signedRankMargin.js +114 -0
- package/dist/signedRankMargin.js.map +1 -0
- package/package.json +5 -5
- package/dist/utils.d.ts +0 -10
- package/dist/utils.d.ts.map +0 -1
- package/dist/utils.js +0 -25
- 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
|
+
npm i pragmastat@7.0.0
|
|
7
7
|
```
|
|
8
8
|
|
|
9
|
-
Source code: https://github.com/AndreyAkinshin/pragmastat/tree/
|
|
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,
|
|
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(
|
|
25
|
-
console.log(rng.uniform()); // 0.
|
|
26
|
-
console.log(rng.uniform()); // 0.
|
|
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("
|
|
29
|
-
console.log(rng.
|
|
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(
|
|
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(
|
|
41
|
+
rng = new Rng("demo-dist-uniform");
|
|
40
42
|
let dist = new Uniform(0, 10);
|
|
41
|
-
console.log(dist.sample(rng)); //
|
|
43
|
+
console.log(dist.sample(rng)); // 6.54043657816832
|
|
42
44
|
|
|
43
|
-
rng = new Rng(
|
|
45
|
+
rng = new Rng("demo-dist-additive");
|
|
44
46
|
let addDist = new Additive(0, 1);
|
|
45
|
-
console.log(addDist.sample(rng)); //
|
|
47
|
+
console.log(addDist.sample(rng)); // 0.17410448679568188
|
|
46
48
|
|
|
47
|
-
rng = new Rng(
|
|
49
|
+
rng = new Rng("demo-dist-exp");
|
|
48
50
|
let expDist = new Exp(1);
|
|
49
|
-
console.log(expDist.sample(rng)); // 0.
|
|
51
|
+
console.log(expDist.sample(rng)); // 0.6589065267276553
|
|
50
52
|
|
|
51
|
-
rng = new Rng(
|
|
53
|
+
rng = new Rng("demo-dist-power");
|
|
52
54
|
let powDist = new Power(1, 2);
|
|
53
|
-
console.log(powDist.sample(rng)); // 1.
|
|
55
|
+
console.log(powDist.sample(rng)); // 1.023677535537084
|
|
54
56
|
|
|
55
|
-
rng = new Rng(
|
|
57
|
+
rng = new Rng("demo-dist-multiplic");
|
|
56
58
|
let mulDist = new Multiplic(0, 1);
|
|
57
|
-
console.log(mulDist.sample(rng)); //
|
|
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
|
-
// ---
|
|
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);
|
package/dist/assumptions.d.ts
CHANGED
|
@@ -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.
|
|
7
|
-
* 3.
|
|
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(
|
|
27
|
-
static positivity(
|
|
28
|
-
static sparity(
|
|
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
|
|
31
|
-
export declare function checkPositivity(values: number[], subject: Subject
|
|
32
|
-
export declare function checkSparity(values: number[], subject: Subject
|
|
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
|
|
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
|
|
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"}
|
package/dist/assumptions.js
CHANGED
|
@@ -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.
|
|
15
|
-
* 3.
|
|
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
|
-
|
|
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(
|
|
34
|
+
static validity(subject) {
|
|
32
35
|
return new AssumptionError({ id: exports.AssumptionId.VALIDITY, subject });
|
|
33
36
|
}
|
|
34
|
-
static positivity(
|
|
37
|
+
static positivity(subject) {
|
|
35
38
|
return new AssumptionError({ id: exports.AssumptionId.POSITIVITY, subject });
|
|
36
39
|
}
|
|
37
|
-
static sparity(
|
|
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
|
|
48
|
+
function checkValidity(values, subject) {
|
|
43
49
|
if (values.length === 0) {
|
|
44
|
-
throw AssumptionError.validity(
|
|
50
|
+
throw AssumptionError.validity(subject);
|
|
45
51
|
}
|
|
46
52
|
if (!values.every((v) => Number.isFinite(v))) {
|
|
47
|
-
throw AssumptionError.validity(
|
|
53
|
+
throw AssumptionError.validity(subject);
|
|
48
54
|
}
|
|
49
55
|
}
|
|
50
|
-
function checkPositivity(values, subject
|
|
56
|
+
function checkPositivity(values, subject) {
|
|
51
57
|
if (values.some((v) => v <= 0)) {
|
|
52
|
-
throw AssumptionError.positivity(
|
|
58
|
+
throw AssumptionError.positivity(subject);
|
|
53
59
|
}
|
|
54
60
|
}
|
|
55
|
-
function checkSparity(values, subject
|
|
61
|
+
function checkSparity(values, subject) {
|
|
56
62
|
if (values.length < 2) {
|
|
57
|
-
throw AssumptionError.sparity(
|
|
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(
|
|
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
|
|
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(
|
|
77
|
+
throw AssumptionError.positivity(subject);
|
|
72
78
|
}
|
|
73
79
|
result[i] = Math.log(values[i]);
|
|
74
80
|
}
|
package/dist/assumptions.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assumptions.js","sourceRoot":"","sources":["../src/assumptions.ts"],"names":[],"mappings":";;;
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
*/
|
package/dist/estimators.d.ts
CHANGED
|
@@ -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
|
package/dist/estimators.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"estimators.d.ts","sourceRoot":"","sources":["../src/estimators.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
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"}
|
package/dist/estimators.js
CHANGED
|
@@ -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'
|
|
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'
|
|
66
|
+
(0, assumptions_1.checkValidity)(x, 'x');
|
|
45
67
|
// Check sparity (priority 2)
|
|
46
|
-
(0, assumptions_1.checkSparity)(x, 'x'
|
|
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'
|
|
83
|
+
(0, assumptions_1.checkValidity)(x, 'x');
|
|
62
84
|
// Check positivity (priority 1)
|
|
63
|
-
(0, assumptions_1.checkPositivity)(x, 'x'
|
|
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'
|
|
81
|
-
(0, assumptions_1.checkValidity)(y, 'y'
|
|
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'
|
|
122
|
+
(0, assumptions_1.checkValidity)(x, 'x');
|
|
101
123
|
// Check validity for y (priority 0, subject y)
|
|
102
|
-
(0, assumptions_1.checkValidity)(y, 'y'
|
|
124
|
+
(0, assumptions_1.checkValidity)(y, 'y');
|
|
103
125
|
// Check positivity for x (priority 1, subject x)
|
|
104
|
-
(0, assumptions_1.checkPositivity)(x, 'x'
|
|
126
|
+
(0, assumptions_1.checkPositivity)(x, 'x');
|
|
105
127
|
// Check positivity for y (priority 1, subject y)
|
|
106
|
-
(0, assumptions_1.checkPositivity)(y, 'y'
|
|
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'
|
|
145
|
+
(0, assumptions_1.checkValidity)(x, 'x');
|
|
124
146
|
// Check validity for y (priority 0, subject y)
|
|
125
|
-
(0, assumptions_1.checkValidity)(y, 'y'
|
|
147
|
+
(0, assumptions_1.checkValidity)(y, 'y');
|
|
126
148
|
// Check sparity for x (priority 2, subject x)
|
|
127
|
-
(0, assumptions_1.checkSparity)(x, 'x'
|
|
149
|
+
(0, assumptions_1.checkSparity)(x, 'x');
|
|
128
150
|
// Check sparity for y (priority 2, subject y)
|
|
129
|
-
(0, assumptions_1.checkSparity)(y, 'y'
|
|
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'
|
|
173
|
+
(0, assumptions_1.checkValidity)(x, 'x');
|
|
152
174
|
// Check validity for y (priority 0, subject y)
|
|
153
|
-
(0, assumptions_1.checkValidity)(y, 'y'
|
|
175
|
+
(0, assumptions_1.checkValidity)(y, 'y');
|
|
154
176
|
// Check sparity for x (priority 2, subject x)
|
|
155
|
-
(0, assumptions_1.checkSparity)(x, 'x'
|
|
177
|
+
(0, assumptions_1.checkSparity)(x, 'x');
|
|
156
178
|
// Check sparity for y (priority 2, subject y)
|
|
157
|
-
(0, assumptions_1.checkSparity)(y, 'y'
|
|
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'
|
|
204
|
+
(0, assumptions_1.checkValidity)(x, 'x');
|
|
183
205
|
// Check validity for y
|
|
184
|
-
(0, assumptions_1.checkValidity)(y, 'y'
|
|
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'
|
|
228
|
-
(0, assumptions_1.checkValidity)(y, 'y'
|
|
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'
|
|
231
|
-
const logY = (0, assumptions_1.log)(y, 'y'
|
|
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
|