pragmastat 3.1.10

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Andrey Akinshin
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,134 @@
1
+ # Pragmastat TypeScript Implementation
2
+
3
+ [![DOI](https://zenodo.org/badge/doi/10.5281/zenodo.17236778.svg)](https://doi.org/10.5281/zenodo.17236778)
4
+
5
+ This is the TypeScript implementation of Pragmastat, a pragmatic statistical toolkit designed for analyzing real-world data.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install pragmastat
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ ```typescript
16
+ import {
17
+ center,
18
+ spread,
19
+ relSpread,
20
+ shift,
21
+ ratio,
22
+ avgSpread,
23
+ disparity
24
+ } from 'pragmastat';
25
+
26
+ // One-sample estimators
27
+ const data = [1, 2, 3, 4, 5];
28
+ console.log('Center:', center(data));
29
+ console.log('Spread:', spread(data));
30
+ console.log('RelSpread:', relSpread(data));
31
+
32
+ // Two-sample estimators
33
+ const x = [1, 2, 3];
34
+ const y = [4, 5, 6];
35
+ console.log('Shift:', shift(x, y));
36
+ console.log('Ratio:', ratio(x, y));
37
+ console.log('AvgSpread:', avgSpread(x, y));
38
+ console.log('Disparity:', disparity(x, y));
39
+ ```
40
+
41
+ ## Estimators
42
+
43
+ ### One-Sample Estimators
44
+
45
+ - **center**: Hodges-Lehmann location estimator - robust measure of average
46
+ - **spread**: Shamos scale estimator - robust measure of dispersion
47
+ - **relSpread**: Relative dispersion measure - spread normalized by center
48
+
49
+ ### Two-Sample Estimators
50
+
51
+ - **shift**: Hodges-Lehmann shift estimator - robust measure of location difference
52
+ - **ratio**: Robust ratio estimator - median of all pairwise ratios
53
+ - **avgSpread**: Pooled spread estimator - combined measure of dispersion
54
+ - **disparity**: Effect size measure - normalized difference between samples
55
+
56
+ ## Development
57
+
58
+ ### Building
59
+
60
+ ```bash
61
+ # Build TypeScript to JavaScript
62
+ npm run build
63
+
64
+ # Or use the build script
65
+ ./build.sh build
66
+ ```
67
+
68
+ ### Testing
69
+
70
+ ```bash
71
+ # Run all tests
72
+ npm test
73
+
74
+ # Run tests with coverage
75
+ npm run test:coverage
76
+
77
+ # Run tests in watch mode
78
+ npm run test:watch
79
+ ```
80
+
81
+ ### Code Quality
82
+
83
+ ```bash
84
+ # Run ESLint
85
+ npm run lint
86
+
87
+ # Format code with Prettier
88
+ npm run format
89
+
90
+ # Check formatting
91
+ npm run format:check
92
+ ```
93
+
94
+ ### Build Script
95
+
96
+ The `build.sh` script provides convenient commands:
97
+
98
+ ```bash
99
+ ./build.sh test # Run all tests
100
+ ./build.sh build # Build TypeScript to JavaScript
101
+ ./build.sh check # Run linting and format checking
102
+ ./build.sh clean # Clean build artifacts
103
+ ./build.sh format # Format code with Prettier
104
+ ./build.sh install # Install npm dependencies
105
+ ./build.sh coverage # Run tests with coverage report
106
+ ./build.sh watch # Run tests in watch mode
107
+ ./build.sh all # Run all tasks
108
+ ```
109
+
110
+ ## Project Structure
111
+
112
+ ```
113
+ ts/
114
+ ├── src/ # Source code
115
+ │ ├── index.ts # Main entry point
116
+ │ ├── estimators.ts # Estimator implementations
117
+ │ └── utils.ts # Utility functions
118
+ ├── tests/ # Test files
119
+ │ ├── estimators.test.ts # Unit tests
120
+ │ ├── invariance.test.ts # Mathematical invariance tests
121
+ │ └── reference.test.ts # Reference tests against JSON data
122
+ ├── dist/ # Compiled JavaScript (generated)
123
+ ├── package.json # NPM package configuration
124
+ ├── tsconfig.json # TypeScript configuration
125
+ ├── jest.config.js # Jest test configuration
126
+ ├── .eslintrc.js # ESLint configuration
127
+ ├── .prettierrc # Prettier configuration
128
+ ├── build.sh # Build script
129
+ └── README.md # This file
130
+ ```
131
+
132
+ ## License
133
+
134
+ This project is licensed under the MIT License - see the LICENSE file for details.
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Pragmastat estimators implementation
3
+ */
4
+ /**
5
+ * Calculate the Center - median of all pairwise averages (x[i] + x[j])/2
6
+ * Uses fast O(n log n) algorithm.
7
+ * @param x Array of sample values
8
+ * @returns The center estimate
9
+ */
10
+ export declare function center(x: number[]): number;
11
+ /**
12
+ * Calculate the Spread - median of all pairwise absolute differences |x[i] - x[j]|
13
+ * Uses fast O(n log n) algorithm.
14
+ * @param x Array of sample values
15
+ * @returns The spread estimate
16
+ */
17
+ export declare function spread(x: number[]): number;
18
+ /**
19
+ * Calculate the RelSpread - ratio of Spread to absolute Center
20
+ * @param x Array of sample values
21
+ * @returns The relative spread estimate
22
+ */
23
+ export declare function relSpread(x: number[]): number;
24
+ /**
25
+ * Calculate the Shift - median of all pairwise differences (x[i] - y[j])
26
+ * @param x First sample
27
+ * @param y Second sample
28
+ * @returns The shift estimate
29
+ */
30
+ export declare function shift(x: number[], y: number[]): number;
31
+ /**
32
+ * Calculate the Ratio - median of all pairwise ratios (x[i] / y[j])
33
+ * @param x First sample
34
+ * @param y Second sample
35
+ * @returns The ratio estimate
36
+ */
37
+ export declare function ratio(x: number[], y: number[]): number;
38
+ /**
39
+ * Calculate the AvgSpread - weighted average of spreads: (n*Spread(x) + m*Spread(y))/(n+m)
40
+ * @param x First sample
41
+ * @param y Second sample
42
+ * @returns The combined spread estimate
43
+ */
44
+ export declare function avgSpread(x: number[], y: number[]): number;
45
+ /**
46
+ * Calculate the Disparity - Shift / AvgSpread
47
+ * @param x First sample
48
+ * @param y Second sample
49
+ * @returns The disparity estimate
50
+ */
51
+ export declare function disparity(x: number[], y: number[]): number;
52
+ //# sourceMappingURL=estimators.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"estimators.d.ts","sourceRoot":"","sources":["../src/estimators.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAE1C;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAE1C;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAa7C;AAED;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAgBtD;AAED;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAqBtD;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAa1D;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAa1D"}
@@ -0,0 +1,128 @@
1
+ "use strict";
2
+ /**
3
+ * Pragmastat estimators implementation
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.center = center;
7
+ exports.spread = spread;
8
+ exports.relSpread = relSpread;
9
+ exports.shift = shift;
10
+ exports.ratio = ratio;
11
+ exports.avgSpread = avgSpread;
12
+ exports.disparity = disparity;
13
+ const utils_1 = require("./utils");
14
+ const fastCenter_1 = require("./fastCenter");
15
+ const fastSpread_1 = require("./fastSpread");
16
+ /**
17
+ * Calculate the Center - median of all pairwise averages (x[i] + x[j])/2
18
+ * Uses fast O(n log n) algorithm.
19
+ * @param x Array of sample values
20
+ * @returns The center estimate
21
+ */
22
+ function center(x) {
23
+ return (0, fastCenter_1.fastCenter)(x);
24
+ }
25
+ /**
26
+ * Calculate the Spread - median of all pairwise absolute differences |x[i] - x[j]|
27
+ * Uses fast O(n log n) algorithm.
28
+ * @param x Array of sample values
29
+ * @returns The spread estimate
30
+ */
31
+ function spread(x) {
32
+ return (0, fastSpread_1.fastSpread)(x);
33
+ }
34
+ /**
35
+ * Calculate the RelSpread - ratio of Spread to absolute Center
36
+ * @param x Array of sample values
37
+ * @returns The relative spread estimate
38
+ */
39
+ function relSpread(x) {
40
+ if (x.length === 0) {
41
+ throw new Error('Input array cannot be empty');
42
+ }
43
+ const s = spread(x);
44
+ const c = center(x);
45
+ if (c === 0) {
46
+ throw new Error('RelSpread is undefined when Center equals zero');
47
+ }
48
+ return s / Math.abs(c);
49
+ }
50
+ /**
51
+ * Calculate the Shift - median of all pairwise differences (x[i] - y[j])
52
+ * @param x First sample
53
+ * @param y Second sample
54
+ * @returns The shift estimate
55
+ */
56
+ function shift(x, y) {
57
+ const nx = x.length;
58
+ const ny = y.length;
59
+ if (nx === 0 || ny === 0) {
60
+ throw new Error('Input arrays cannot be empty');
61
+ }
62
+ const pairwiseDifferences = [];
63
+ for (let i = 0; i < nx; i++) {
64
+ for (let j = 0; j < ny; j++) {
65
+ pairwiseDifferences.push(x[i] - y[j]);
66
+ }
67
+ }
68
+ return (0, utils_1.median)(pairwiseDifferences);
69
+ }
70
+ /**
71
+ * Calculate the Ratio - median of all pairwise ratios (x[i] / y[j])
72
+ * @param x First sample
73
+ * @param y Second sample
74
+ * @returns The ratio estimate
75
+ */
76
+ function ratio(x, y) {
77
+ const nx = x.length;
78
+ const ny = y.length;
79
+ if (nx === 0 || ny === 0) {
80
+ throw new Error('Input arrays cannot be empty');
81
+ }
82
+ // Check that all y values are strictly positive
83
+ if (y.some((val) => val <= 0)) {
84
+ throw new Error('All values in y must be strictly positive');
85
+ }
86
+ const pairwiseRatios = [];
87
+ for (let i = 0; i < nx; i++) {
88
+ for (let j = 0; j < ny; j++) {
89
+ pairwiseRatios.push(x[i] / y[j]);
90
+ }
91
+ }
92
+ return (0, utils_1.median)(pairwiseRatios);
93
+ }
94
+ /**
95
+ * Calculate the AvgSpread - weighted average of spreads: (n*Spread(x) + m*Spread(y))/(n+m)
96
+ * @param x First sample
97
+ * @param y Second sample
98
+ * @returns The combined spread estimate
99
+ */
100
+ function avgSpread(x, y) {
101
+ const nx = x.length;
102
+ const ny = y.length;
103
+ if (nx === 0 || ny === 0) {
104
+ throw new Error('Input arrays cannot be empty');
105
+ }
106
+ // Calculate weighted average of individual spreads
107
+ const spreadX = spread(x);
108
+ const spreadY = spread(y);
109
+ return (nx * spreadX + ny * spreadY) / (nx + ny);
110
+ }
111
+ /**
112
+ * Calculate the Disparity - Shift / AvgSpread
113
+ * @param x First sample
114
+ * @param y Second sample
115
+ * @returns The disparity estimate
116
+ */
117
+ function disparity(x, y) {
118
+ if (x.length === 0 || y.length === 0) {
119
+ throw new Error('Input arrays cannot be empty');
120
+ }
121
+ const shiftVal = shift(x, y);
122
+ const combinedSpread = avgSpread(x, y);
123
+ if (combinedSpread === 0) {
124
+ return Infinity;
125
+ }
126
+ return shiftVal / combinedSpread;
127
+ }
128
+ //# sourceMappingURL=estimators.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"estimators.js","sourceRoot":"","sources":["../src/estimators.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Fast O(n log n) implementation of the Center (Hodges-Lehmann) estimator.
3
+ * Based on Monahan's Algorithm 616 (1984).
4
+ *
5
+ * Internal implementation - not part of public API.
6
+ */
7
+ /**
8
+ * Compute the median of all pairwise averages (xi + xj)/2 efficiently.
9
+ *
10
+ * Time complexity: O(n log n) expected
11
+ * Space complexity: O(n)
12
+ *
13
+ * @param values Array of numeric values
14
+ * @returns The center estimate (Hodges-Lehmann estimator)
15
+ * @internal
16
+ */
17
+ export declare function fastCenter(values: number[]): number;
18
+ //# sourceMappingURL=fastCenter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fastCenter.d.ts","sourceRoot":"","sources":["../src/fastCenter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAmMnD"}
@@ -0,0 +1,183 @@
1
+ "use strict";
2
+ /**
3
+ * Fast O(n log n) implementation of the Center (Hodges-Lehmann) estimator.
4
+ * Based on Monahan's Algorithm 616 (1984).
5
+ *
6
+ * Internal implementation - not part of public API.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.fastCenter = fastCenter;
10
+ /**
11
+ * Compute the median of all pairwise averages (xi + xj)/2 efficiently.
12
+ *
13
+ * Time complexity: O(n log n) expected
14
+ * Space complexity: O(n)
15
+ *
16
+ * @param values Array of numeric values
17
+ * @returns The center estimate (Hodges-Lehmann estimator)
18
+ * @internal
19
+ */
20
+ function fastCenter(values) {
21
+ const n = values.length;
22
+ if (n === 0) {
23
+ throw new Error('Input array cannot be empty');
24
+ }
25
+ if (n === 1) {
26
+ return values[0];
27
+ }
28
+ if (n === 2) {
29
+ return (values[0] + values[1]) / 2;
30
+ }
31
+ // Sort the values
32
+ const sortedValues = [...values].sort((a, b) => a - b);
33
+ // Calculate target median rank(s) among all pairwise sums
34
+ const totalPairs = Math.floor((n * (n + 1)) / 2);
35
+ const medianRankLow = Math.floor((totalPairs + 1) / 2); // 1-based rank
36
+ const medianRankHigh = Math.floor((totalPairs + 2) / 2);
37
+ // Initialize search bounds for each row (1-based indexing)
38
+ const leftBounds = Array.from({ length: n }, (_, i) => i + 1);
39
+ const rightBounds = Array(n).fill(n);
40
+ // Start with a good pivot: sum of middle elements
41
+ let pivot = sortedValues[Math.floor((n - 1) / 2)] + sortedValues[Math.floor(n / 2)];
42
+ let activeSetSize = totalPairs;
43
+ let previousCount = 0;
44
+ while (true) {
45
+ // === PARTITION STEP ===
46
+ let countBelowPivot = 0;
47
+ let currentColumn = n;
48
+ const partitionCounts = [];
49
+ for (let row = 1; row <= n; row++) {
50
+ // Move left from current column until we find sums < pivot
51
+ while (currentColumn >= row &&
52
+ sortedValues[row - 1] + sortedValues[currentColumn - 1] >= pivot) {
53
+ currentColumn--;
54
+ }
55
+ // Count elements in this row that are < pivot
56
+ const elementsBelow = currentColumn >= row ? currentColumn - row + 1 : 0;
57
+ partitionCounts.push(elementsBelow);
58
+ countBelowPivot += elementsBelow;
59
+ }
60
+ // === CONVERGENCE CHECK ===
61
+ if (countBelowPivot === previousCount) {
62
+ let minActiveSum = Infinity;
63
+ let maxActiveSum = -Infinity;
64
+ for (let i = 0; i < n; i++) {
65
+ if (leftBounds[i] > rightBounds[i]) {
66
+ continue;
67
+ }
68
+ const rowValue = sortedValues[i];
69
+ const smallestInRow = sortedValues[leftBounds[i] - 1] + rowValue;
70
+ const largestInRow = sortedValues[rightBounds[i] - 1] + rowValue;
71
+ minActiveSum = Math.min(minActiveSum, smallestInRow);
72
+ maxActiveSum = Math.max(maxActiveSum, largestInRow);
73
+ }
74
+ pivot = (minActiveSum + maxActiveSum) / 2;
75
+ if (pivot <= minActiveSum || pivot > maxActiveSum) {
76
+ pivot = maxActiveSum;
77
+ }
78
+ if (minActiveSum === maxActiveSum || activeSetSize <= 2) {
79
+ return pivot / 2;
80
+ }
81
+ continue;
82
+ }
83
+ // === TARGET CHECK ===
84
+ const atTargetRank = countBelowPivot === medianRankLow || countBelowPivot === medianRankHigh - 1;
85
+ if (atTargetRank) {
86
+ let largestBelowPivot = -Infinity;
87
+ let smallestAtOrAbovePivot = Infinity;
88
+ for (let i = 0; i < n; i++) {
89
+ const countInRow = partitionCounts[i];
90
+ const rowValue = sortedValues[i];
91
+ const totalInRow = n - i;
92
+ // Find largest sum in this row that's < pivot
93
+ if (countInRow > 0) {
94
+ const lastBelowIndex = i + countInRow;
95
+ const lastBelowValue = rowValue + sortedValues[lastBelowIndex - 1];
96
+ largestBelowPivot = Math.max(largestBelowPivot, lastBelowValue);
97
+ }
98
+ // Find smallest sum in this row that's >= pivot
99
+ if (countInRow < totalInRow) {
100
+ const firstAtOrAboveIndex = i + countInRow + 1;
101
+ const firstAtOrAboveValue = rowValue + sortedValues[firstAtOrAboveIndex - 1];
102
+ smallestAtOrAbovePivot = Math.min(smallestAtOrAbovePivot, firstAtOrAboveValue);
103
+ }
104
+ }
105
+ // Calculate final result
106
+ if (medianRankLow < medianRankHigh) {
107
+ // Even total: average the two middle values
108
+ return (smallestAtOrAbovePivot + largestBelowPivot) / 4;
109
+ }
110
+ else {
111
+ // Odd total: return the single middle value
112
+ const needLargest = countBelowPivot === medianRankLow;
113
+ return (needLargest ? largestBelowPivot : smallestAtOrAbovePivot) / 2;
114
+ }
115
+ }
116
+ // === UPDATE BOUNDS ===
117
+ if (countBelowPivot < medianRankLow) {
118
+ // Too few values below pivot - search higher
119
+ for (let i = 0; i < n; i++) {
120
+ leftBounds[i] = i + partitionCounts[i] + 1;
121
+ }
122
+ }
123
+ else {
124
+ // Too many values below pivot - search lower
125
+ for (let i = 0; i < n; i++) {
126
+ rightBounds[i] = i + partitionCounts[i];
127
+ }
128
+ }
129
+ // === PREPARE NEXT ITERATION ===
130
+ previousCount = countBelowPivot;
131
+ // Recalculate active set size
132
+ activeSetSize = 0;
133
+ for (let i = 0; i < n; i++) {
134
+ const rowSize = rightBounds[i] - leftBounds[i] + 1;
135
+ if (rowSize > 0) {
136
+ activeSetSize += rowSize;
137
+ }
138
+ }
139
+ // Choose next pivot
140
+ if (activeSetSize > 2) {
141
+ // Use randomized row median strategy
142
+ const targetIndex = Math.floor(Math.random() * activeSetSize);
143
+ let cumulativeSize = 0;
144
+ let selectedRow = 0;
145
+ for (let i = 0; i < n; i++) {
146
+ const rowSize = rightBounds[i] - leftBounds[i] + 1;
147
+ if (rowSize > 0) {
148
+ if (targetIndex < cumulativeSize + rowSize) {
149
+ selectedRow = i;
150
+ break;
151
+ }
152
+ cumulativeSize += rowSize;
153
+ }
154
+ }
155
+ // Use median element of the selected row as pivot
156
+ const medianColumnInRow = Math.floor((leftBounds[selectedRow] + rightBounds[selectedRow]) / 2);
157
+ pivot = sortedValues[selectedRow] + sortedValues[medianColumnInRow - 1];
158
+ }
159
+ else {
160
+ // Few elements remain - use midrange strategy
161
+ let minRemainingSum = Infinity;
162
+ let maxRemainingSum = -Infinity;
163
+ for (let i = 0; i < n; i++) {
164
+ if (leftBounds[i] > rightBounds[i]) {
165
+ continue;
166
+ }
167
+ const rowValue = sortedValues[i];
168
+ const minInRow = sortedValues[leftBounds[i] - 1] + rowValue;
169
+ const maxInRow = sortedValues[rightBounds[i] - 1] + rowValue;
170
+ minRemainingSum = Math.min(minRemainingSum, minInRow);
171
+ maxRemainingSum = Math.max(maxRemainingSum, maxInRow);
172
+ }
173
+ pivot = (minRemainingSum + maxRemainingSum) / 2;
174
+ if (pivot <= minRemainingSum || pivot > maxRemainingSum) {
175
+ pivot = maxRemainingSum;
176
+ }
177
+ if (minRemainingSum === maxRemainingSum) {
178
+ return pivot / 2;
179
+ }
180
+ }
181
+ }
182
+ }
183
+ //# sourceMappingURL=fastCenter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fastCenter.js","sourceRoot":"","sources":["../src/fastCenter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Fast O(n log n) implementation of the Spread (Shamos) estimator.
3
+ * Based on Monahan's selection algorithm adapted for pairwise differences.
4
+ *
5
+ * Internal implementation - not part of public API.
6
+ */
7
+ /**
8
+ * Compute the median of all pairwise absolute differences |xi - xj| efficiently.
9
+ *
10
+ * Time complexity: O(n log n) expected
11
+ * Space complexity: O(n)
12
+ *
13
+ * @param values Array of numeric values
14
+ * @returns The spread estimate (Shamos estimator)
15
+ * @internal
16
+ */
17
+ export declare function fastSpread(values: number[]): number;
18
+ //# sourceMappingURL=fastSpread.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fastSpread.d.ts","sourceRoot":"","sources":["../src/fastSpread.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CA2MnD"}
@@ -0,0 +1,201 @@
1
+ "use strict";
2
+ /**
3
+ * Fast O(n log n) implementation of the Spread (Shamos) estimator.
4
+ * Based on Monahan's selection algorithm adapted for pairwise differences.
5
+ *
6
+ * Internal implementation - not part of public API.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.fastSpread = fastSpread;
10
+ /**
11
+ * Compute the median of all pairwise absolute differences |xi - xj| efficiently.
12
+ *
13
+ * Time complexity: O(n log n) expected
14
+ * Space complexity: O(n)
15
+ *
16
+ * @param values Array of numeric values
17
+ * @returns The spread estimate (Shamos estimator)
18
+ * @internal
19
+ */
20
+ function fastSpread(values) {
21
+ const n = values.length;
22
+ if (n === 0) {
23
+ throw new Error('Input array cannot be empty');
24
+ }
25
+ if (n === 1) {
26
+ return 0;
27
+ }
28
+ if (n === 2) {
29
+ return Math.abs(values[1] - values[0]);
30
+ }
31
+ // Sort the values
32
+ const a = [...values].sort((a, b) => a - b);
33
+ // Total number of pairwise differences with i < j
34
+ const N = Math.floor((n * (n - 1)) / 2);
35
+ const kLow = Math.floor((N + 1) / 2); // 1-based rank of lower middle
36
+ const kHigh = Math.floor((N + 2) / 2); // 1-based rank of upper middle
37
+ // Per-row active bounds over columns j (0-based indices)
38
+ // Row i allows j in [i+1, n-1] initially
39
+ const L = Array.from({ length: n }, (_, i) => Math.min(i + 1, n));
40
+ const R = Array(n).fill(n - 1);
41
+ for (let i = 0; i < n; i++) {
42
+ if (L[i] > R[i]) {
43
+ L[i] = 1;
44
+ R[i] = 0; // mark empty
45
+ }
46
+ }
47
+ const rowCounts = Array(n).fill(0);
48
+ // Initial pivot: a central gap
49
+ let pivot = a[Math.floor(n / 2)] - a[Math.floor((n - 1) / 2)];
50
+ let prevCountBelow = -1;
51
+ while (true) {
52
+ // === PARTITION: count how many differences are < pivot ===
53
+ let countBelow = 0;
54
+ let largestBelow = -Infinity;
55
+ let smallestAtOrAbove = Infinity;
56
+ let j = 1; // global two-pointer (non-decreasing across rows)
57
+ for (let i = 0; i < n - 1; i++) {
58
+ if (j < i + 1) {
59
+ j = i + 1;
60
+ }
61
+ while (j < n && a[j] - a[i] < pivot) {
62
+ j++;
63
+ }
64
+ const cntRow = Math.max(0, j - (i + 1));
65
+ rowCounts[i] = cntRow;
66
+ countBelow += cntRow;
67
+ // boundary elements for this row
68
+ if (cntRow > 0) {
69
+ const candBelow = a[j - 1] - a[i];
70
+ largestBelow = Math.max(largestBelow, candBelow);
71
+ }
72
+ if (j < n) {
73
+ const candAtOrAbove = a[j] - a[i];
74
+ smallestAtOrAbove = Math.min(smallestAtOrAbove, candAtOrAbove);
75
+ }
76
+ }
77
+ // === TARGET CHECK ===
78
+ const atTarget = countBelow === kLow || countBelow === kHigh - 1;
79
+ if (atTarget) {
80
+ if (kLow < kHigh) {
81
+ // Even N: average the two central order stats
82
+ return 0.5 * (largestBelow + smallestAtOrAbove);
83
+ }
84
+ else {
85
+ // Odd N: pick the single middle
86
+ const needLargest = countBelow === kLow;
87
+ return needLargest ? largestBelow : smallestAtOrAbove;
88
+ }
89
+ }
90
+ // === STALL HANDLING ===
91
+ if (countBelow === prevCountBelow) {
92
+ let minActive = Infinity;
93
+ let maxActive = -Infinity;
94
+ let active = 0;
95
+ for (let i = 0; i < n - 1; i++) {
96
+ const Li = L[i];
97
+ const Ri = R[i];
98
+ if (Li > Ri) {
99
+ continue;
100
+ }
101
+ const rowMin = a[Li] - a[i];
102
+ const rowMax = a[Ri] - a[i];
103
+ minActive = Math.min(minActive, rowMin);
104
+ maxActive = Math.max(maxActive, rowMax);
105
+ active += Ri - Li + 1;
106
+ }
107
+ if (active <= 0) {
108
+ if (kLow < kHigh) {
109
+ return 0.5 * (largestBelow + smallestAtOrAbove);
110
+ }
111
+ return countBelow >= kLow ? largestBelow : smallestAtOrAbove;
112
+ }
113
+ if (maxActive <= minActive) {
114
+ return minActive;
115
+ }
116
+ const mid = 0.5 * (minActive + maxActive);
117
+ pivot = mid > minActive && mid <= maxActive ? mid : maxActive;
118
+ prevCountBelow = countBelow;
119
+ continue;
120
+ }
121
+ // === SHRINK ACTIVE WINDOW ===
122
+ if (countBelow < kLow) {
123
+ // Need larger differences: discard all strictly below pivot
124
+ for (let i = 0; i < n - 1; i++) {
125
+ const newL = i + 1 + rowCounts[i];
126
+ if (newL > L[i]) {
127
+ L[i] = newL;
128
+ }
129
+ if (L[i] > R[i]) {
130
+ L[i] = 1;
131
+ R[i] = 0;
132
+ }
133
+ }
134
+ }
135
+ else {
136
+ // Too many below: keep only those strictly below pivot
137
+ for (let i = 0; i < n - 1; i++) {
138
+ const newR = i + rowCounts[i];
139
+ if (newR < R[i]) {
140
+ R[i] = newR;
141
+ }
142
+ if (R[i] < i + 1) {
143
+ L[i] = 1;
144
+ R[i] = 0;
145
+ }
146
+ }
147
+ }
148
+ prevCountBelow = countBelow;
149
+ // === CHOOSE NEXT PIVOT FROM ACTIVE SET ===
150
+ let activeSize = 0;
151
+ for (let i = 0; i < n - 1; i++) {
152
+ if (L[i] <= R[i]) {
153
+ activeSize += R[i] - L[i] + 1;
154
+ }
155
+ }
156
+ if (activeSize <= 2) {
157
+ // Few candidates left: return midrange of remaining
158
+ let minRem = Infinity;
159
+ let maxRem = -Infinity;
160
+ for (let i = 0; i < n - 1; i++) {
161
+ if (L[i] > R[i]) {
162
+ continue;
163
+ }
164
+ const lo = a[L[i]] - a[i];
165
+ const hi = a[R[i]] - a[i];
166
+ minRem = Math.min(minRem, lo);
167
+ maxRem = Math.max(maxRem, hi);
168
+ }
169
+ if (activeSize <= 0) {
170
+ if (kLow < kHigh) {
171
+ return 0.5 * (largestBelow + smallestAtOrAbove);
172
+ }
173
+ return countBelow >= kLow ? largestBelow : smallestAtOrAbove;
174
+ }
175
+ if (kLow < kHigh) {
176
+ return 0.5 * (minRem + maxRem);
177
+ }
178
+ return Math.abs(kLow - 1 - countBelow) <= Math.abs(countBelow - kLow) ? minRem : maxRem;
179
+ }
180
+ else {
181
+ // Weighted random row selection
182
+ const t = Math.floor(Math.random() * activeSize);
183
+ let acc = 0;
184
+ let row = 0;
185
+ for (row = 0; row < n - 1; row++) {
186
+ if (L[row] > R[row]) {
187
+ continue;
188
+ }
189
+ const size = R[row] - L[row] + 1;
190
+ if (t < acc + size) {
191
+ break;
192
+ }
193
+ acc += size;
194
+ }
195
+ // Median column of the selected row
196
+ const col = Math.floor((L[row] + R[row]) / 2);
197
+ pivot = a[col] - a[row];
198
+ }
199
+ }
200
+ }
201
+ //# sourceMappingURL=fastSpread.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fastSpread.js","sourceRoot":"","sources":["../src/fastSpread.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;AAYH,gCA2MC;AArND;;;;;;;;;GASG;AACH,SAAgB,UAAU,CAAC,MAAgB;IACzC,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;IACxB,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IACjD,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACZ,OAAO,CAAC,CAAC;IACX,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACZ,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IACzC,CAAC;IAED,kBAAkB;IAClB,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAE5C,kDAAkD;IAClD,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACxC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,+BAA+B;IACrE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,+BAA+B;IAEtE,yDAAyD;IACzD,yCAAyC;IACzC,MAAM,CAAC,GAAa,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC5E,MAAM,CAAC,GAAa,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAEzC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAChB,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YACT,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,aAAa;QACzB,CAAC;IACH,CAAC;IAED,MAAM,SAAS,GAAa,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAE7C,+BAA+B;IAC/B,IAAI,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC9D,IAAI,cAAc,GAAG,CAAC,CAAC,CAAC;IAExB,OAAO,IAAI,EAAE,CAAC;QACZ,4DAA4D;QAC5D,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,IAAI,YAAY,GAAG,CAAC,QAAQ,CAAC;QAC7B,IAAI,iBAAiB,GAAG,QAAQ,CAAC;QAEjC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,kDAAkD;QAC7D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC/B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBACd,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACZ,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,EAAE,CAAC;gBACpC,CAAC,EAAE,CAAC;YACN,CAAC;YAED,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACxC,SAAS,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;YACtB,UAAU,IAAI,MAAM,CAAC;YAErB,iCAAiC;YACjC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;gBACf,MAAM,SAAS,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBAClC,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;YACnD,CAAC;YAED,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;gBACV,MAAM,aAAa,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBAClC,iBAAiB,GAAG,IAAI,CAAC,GAAG,CAAC,iBAAiB,EAAE,aAAa,CAAC,CAAC;YACjE,CAAC;QACH,CAAC;QAED,uBAAuB;QACvB,MAAM,QAAQ,GAAG,UAAU,KAAK,IAAI,IAAI,UAAU,KAAK,KAAK,GAAG,CAAC,CAAC;QAEjE,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,IAAI,GAAG,KAAK,EAAE,CAAC;gBACjB,8CAA8C;gBAC9C,OAAO,GAAG,GAAG,CAAC,YAAY,GAAG,iBAAiB,CAAC,CAAC;YAClD,CAAC;iBAAM,CAAC;gBACN,gCAAgC;gBAChC,MAAM,WAAW,GAAG,UAAU,KAAK,IAAI,CAAC;gBACxC,OAAO,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,iBAAiB,CAAC;YACxD,CAAC;QACH,CAAC;QAED,yBAAyB;QACzB,IAAI,UAAU,KAAK,cAAc,EAAE,CAAC;YAClC,IAAI,SAAS,GAAG,QAAQ,CAAC;YACzB,IAAI,SAAS,GAAG,CAAC,QAAQ,CAAC;YAC1B,IAAI,MAAM,GAAG,CAAC,CAAC;YAEf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC/B,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBAChB,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBAChB,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC;oBACZ,SAAS;gBACX,CAAC;gBAED,MAAM,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC5B,MAAM,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC5B,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;gBACxC,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;gBACxC,MAAM,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;YACxB,CAAC;YAED,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;gBAChB,IAAI,IAAI,GAAG,KAAK,EAAE,CAAC;oBACjB,OAAO,GAAG,GAAG,CAAC,YAAY,GAAG,iBAAiB,CAAC,CAAC;gBAClD,CAAC;gBACD,OAAO,UAAU,IAAI,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,iBAAiB,CAAC;YAC/D,CAAC;YAED,IAAI,SAAS,IAAI,SAAS,EAAE,CAAC;gBAC3B,OAAO,SAAS,CAAC;YACnB,CAAC;YAED,MAAM,GAAG,GAAG,GAAG,GAAG,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;YAC1C,KAAK,GAAG,GAAG,GAAG,SAAS,IAAI,GAAG,IAAI,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;YAC9D,cAAc,GAAG,UAAU,CAAC;YAC5B,SAAS;QACX,CAAC;QAED,+BAA+B;QAC/B,IAAI,UAAU,GAAG,IAAI,EAAE,CAAC;YACtB,4DAA4D;YAC5D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC/B,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;gBAClC,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;oBAChB,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;gBACd,CAAC;gBACD,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;oBAChB,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;oBACT,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;gBACX,CAAC;YACH,CAAC;QACH,CAAC;aAAM,CAAC;YACN,uDAAuD;YACvD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC/B,MAAM,IAAI,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;gBAC9B,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;oBAChB,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;gBACd,CAAC;gBACD,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;oBACjB,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;oBACT,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;gBACX,CAAC;YACH,CAAC;QACH,CAAC;QAED,cAAc,GAAG,UAAU,CAAC;QAE5B,4CAA4C;QAC5C,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC/B,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBACjB,UAAU,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YAChC,CAAC;QACH,CAAC;QAED,IAAI,UAAU,IAAI,CAAC,EAAE,CAAC;YACpB,oDAAoD;YACpD,IAAI,MAAM,GAAG,QAAQ,CAAC;YACtB,IAAI,MAAM,GAAG,CAAC,QAAQ,CAAC;YACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC/B,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;oBAChB,SAAS;gBACX,CAAC;gBACD,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC1B,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC1B,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;gBAC9B,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YAChC,CAAC;YAED,IAAI,UAAU,IAAI,CAAC,EAAE,CAAC;gBACpB,IAAI,IAAI,GAAG,KAAK,EAAE,CAAC;oBACjB,OAAO,GAAG,GAAG,CAAC,YAAY,GAAG,iBAAiB,CAAC,CAAC;gBAClD,CAAC;gBACD,OAAO,UAAU,IAAI,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,iBAAiB,CAAC;YAC/D,CAAC;YAED,IAAI,IAAI,GAAG,KAAK,EAAE,CAAC;gBACjB,OAAO,GAAG,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;YACjC,CAAC;YACD,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,GAAG,UAAU,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;QAC1F,CAAC;aAAM,CAAC;YACN,gCAAgC;YAChC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,UAAU,CAAC,CAAC;YACjD,IAAI,GAAG,GAAG,CAAC,CAAC;YACZ,IAAI,GAAG,GAAG,CAAC,CAAC;YACZ,KAAK,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC;gBACjC,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;oBACpB,SAAS;gBACX,CAAC;gBACD,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBACjC,IAAI,CAAC,GAAG,GAAG,GAAG,IAAI,EAAE,CAAC;oBACnB,MAAM;gBACR,CAAC;gBACD,GAAG,IAAI,IAAI,CAAC;YACd,CAAC;YAED,oCAAoC;YACpC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAC9C,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Pragmastat: Unified Statistical Toolkit
3
+ *
4
+ * A collection of robust statistical estimators for real-world data analysis.
5
+ */
6
+ export { center, spread, relSpread, shift, ratio, avgSpread, disparity } from './estimators';
7
+ export { median } from './utils';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE7F,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ /**
3
+ * Pragmastat: Unified Statistical Toolkit
4
+ *
5
+ * A collection of robust statistical estimators for real-world data analysis.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.median = exports.disparity = exports.avgSpread = exports.ratio = exports.shift = exports.relSpread = exports.spread = exports.center = void 0;
9
+ var estimators_1 = require("./estimators");
10
+ Object.defineProperty(exports, "center", { enumerable: true, get: function () { return estimators_1.center; } });
11
+ Object.defineProperty(exports, "spread", { enumerable: true, get: function () { return estimators_1.spread; } });
12
+ Object.defineProperty(exports, "relSpread", { enumerable: true, get: function () { return estimators_1.relSpread; } });
13
+ Object.defineProperty(exports, "shift", { enumerable: true, get: function () { return estimators_1.shift; } });
14
+ Object.defineProperty(exports, "ratio", { enumerable: true, get: function () { return estimators_1.ratio; } });
15
+ Object.defineProperty(exports, "avgSpread", { enumerable: true, get: function () { return estimators_1.avgSpread; } });
16
+ Object.defineProperty(exports, "disparity", { enumerable: true, get: function () { return estimators_1.disparity; } });
17
+ var utils_1 = require("./utils");
18
+ Object.defineProperty(exports, "median", { enumerable: true, get: function () { return utils_1.median; } });
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAEH,2CAA6F;AAApF,oGAAA,MAAM,OAAA;AAAE,oGAAA,MAAM,OAAA;AAAE,uGAAA,SAAS,OAAA;AAAE,mGAAA,KAAK,OAAA;AAAE,mGAAA,KAAK,OAAA;AAAE,uGAAA,SAAS,OAAA;AAAE,uGAAA,SAAS,OAAA;AAEtE,iCAAiC;AAAxB,+FAAA,MAAM,OAAA"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Utility functions for statistical calculations
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;
10
+ /**
11
+ * Generate all pairwise combinations of indices
12
+ * @param n Number of elements
13
+ * @param includeDiagonal Whether to include pairs (i, i)
14
+ * @returns Array of index pairs [i, j]
15
+ */
16
+ export declare function getPairs(n: number, includeDiagonal?: boolean): [number, number][];
17
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAa/C;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,eAAe,GAAE,OAAc,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAWvF"}
package/dist/utils.js ADDED
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ /**
3
+ * Utility functions for statistical calculations
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.median = median;
7
+ exports.getPairs = getPairs;
8
+ /**
9
+ * Calculate the median of an array of numbers
10
+ * @param values Array of numbers
11
+ * @returns The median value
12
+ */
13
+ function median(values) {
14
+ if (values.length === 0) {
15
+ return 0;
16
+ }
17
+ const sorted = [...values].sort((a, b) => a - b);
18
+ const mid = Math.floor(sorted.length / 2);
19
+ if (sorted.length % 2 === 0) {
20
+ return (sorted[mid - 1] + sorted[mid]) / 2;
21
+ }
22
+ else {
23
+ return sorted[mid];
24
+ }
25
+ }
26
+ /**
27
+ * Generate all pairwise combinations of indices
28
+ * @param n Number of elements
29
+ * @param includeDiagonal Whether to include pairs (i, i)
30
+ * @returns Array of index pairs [i, j]
31
+ */
32
+ function getPairs(n, includeDiagonal = true) {
33
+ const pairs = [];
34
+ for (let i = 0; i < n; i++) {
35
+ const startJ = includeDiagonal ? i : i + 1;
36
+ for (let j = startJ; j < n; j++) {
37
+ pairs.push([i, j]);
38
+ }
39
+ }
40
+ return pairs;
41
+ }
42
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";AAAA;;GAEG;;AAOH,wBAaC;AAQD,4BAWC;AArCD;;;;GAIG;AACH,SAAgB,MAAM,CAAC,MAAgB;IACrC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACjD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAE1C,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;IAC7C,CAAC;SAAM,CAAC;QACN,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAgB,QAAQ,CAAC,CAAS,EAAE,kBAA2B,IAAI;IACjE,MAAM,KAAK,GAAuB,EAAE,CAAC;IAErC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAC3C,KAAK,IAAI,CAAC,GAAG,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAChC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "pragmastat",
3
+ "version": "3.1.10",
4
+ "description": "Pragmastat: Pragmatic Statistical Toolkit",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "test": "jest",
10
+ "test:watch": "jest --watch",
11
+ "test:coverage": "jest --coverage",
12
+ "lint": "eslint src tests --ext .ts",
13
+ "format": "prettier --write \"src/**/*.ts\" \"tests/**/*.ts\"",
14
+ "format:check": "prettier --check \"src/**/*.ts\" \"tests/**/*.ts\"",
15
+ "clean": "rm -rf dist coverage",
16
+ "prepublishOnly": "npm run clean && npm run build && npm run test"
17
+ },
18
+ "keywords": [
19
+ "statistics",
20
+ "robust",
21
+ "estimators",
22
+ "median",
23
+ "hodges-lehmann"
24
+ ],
25
+ "author": "Andrey Akinshin",
26
+ "license": "MIT",
27
+ "devDependencies": {
28
+ "@types/jest": "^29.5.0",
29
+ "@types/node": "^20.0.0",
30
+ "@typescript-eslint/eslint-plugin": "^6.0.0",
31
+ "@typescript-eslint/parser": "^6.0.0",
32
+ "eslint": "^8.0.0",
33
+ "jest": "^29.5.0",
34
+ "prettier": "^3.0.0",
35
+ "ts-jest": "^29.1.0",
36
+ "typescript": "^5.0.0"
37
+ },
38
+ "files": [
39
+ "dist",
40
+ "LICENSE",
41
+ "README.md"
42
+ ],
43
+ "repository": {
44
+ "type": "git",
45
+ "url": "https://github.com/AndreyAkinshin/pragmastat.git"
46
+ },
47
+ "homepage": "https://pragmastat.dev",
48
+ "doi": "10.5281/zenodo.17236778"
49
+ }