dsh-meta-analysis 0.1.1 → 0.1.2
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/CHANGELOG.md +24 -0
- package/README-zh.md +28 -3
- package/README.md +28 -3
- package/lib/math.d.ts +5 -4
- package/lib/math.d.ts.map +1 -1
- package/lib/math.js +53 -17
- package/lib/math.js.map +1 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/package.json +3 -2
- package/src/math.ts +53 -16
- package/src/version.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,30 @@ All notable changes to this project are documented here. The format follows
|
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project
|
|
5
5
|
adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Deterministic 20-case synthetic meta-analysis benchmark: `bench/run-meta.mjs`,
|
|
12
|
+
the `bench:meta` script, and committed `bench/results-meta.json` /
|
|
13
|
+
`bench/results-meta.md`. The expected values are an independent closed-form
|
|
14
|
+
implementation in the dsh-research-bench generator, not plugin output.
|
|
15
|
+
- A double-precision normal-quantile test.
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- `normalQuantile` now uses Wichura's AS 241 (PPND16) instead of Acklam's
|
|
20
|
+
rational approximation: Φ⁻¹(0.975) is accurate to ~1e-16 instead of
|
|
21
|
+
~1.6e-9. The benchmark's CI-derived SEs had amplified the old error into
|
|
22
|
+
I² deviations of 1.12e-9 on two cases; the maximum is now 2.2e-16.
|
|
23
|
+
|
|
24
|
+
## [0.1.2] - 2026-11-08
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
|
|
28
|
+
- `normalQuantile` now uses Wichura AS 241 (PPND16) instead of the Acklam approximation; the 95% critical value matches 1.959963984540054 to double precision, which the new 20-case benchmark checks to 1e-9 (I²) and 1e-6 (Q, τ²).
|
|
29
|
+
- Added the deterministic 20-case meta-analysis benchmark (`pnpm run bench:meta`) and documented the measured maximum absolute errors.
|
|
30
|
+
|
|
7
31
|
## [0.1.1] - 2026-11-08
|
|
8
32
|
|
|
9
33
|
### Changed
|
package/README-zh.md
CHANGED
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
| SMD | `(m₁−m₂)/s_pooled`, SE `√(1/n₁+1/n₂+d²/(2(n₁+n₂)))` |
|
|
42
42
|
| Egger | 以 `θᵢ/SEᵢ` 对 `1/SEᵢ` 做 OLS 的截距,t 检验 df = k−2 |
|
|
43
43
|
|
|
44
|
-
正态尾部 p 使用 A&S 7.1.26 近似(约 1e-7);χ² 与 t 使用正则化不完全 gamma/beta 连分数(约 1e-10
|
|
44
|
+
正态尾部 p 使用 A&S 7.1.26 近似(约 1e-7);Φ⁻¹ 使用 Wichura AS 241 / PPND16(约 1e-16);χ² 与 t 使用正则化不完全 gamma/beta 连分数(约 1e-10)。三者都在 `src/math.ts` 中实现,且无依赖。
|
|
45
45
|
|
|
46
46
|
## 工具
|
|
47
47
|
|
|
@@ -85,9 +85,34 @@ dsh --profile <name> --dump-config | grep dsh-meta-analysis
|
|
|
85
85
|
|
|
86
86
|
## 评测
|
|
87
87
|
|
|
88
|
-
**
|
|
88
|
+
**23 个单元测试**:特殊函数对照已知临界值(χ²(8,2)=0.9817、t(2.306,8)≈0.05、z(1.96)≈0.05、Φ⁻¹(0.975) 精确到 12 位小数)、换算(logOR+SE、d⇄r、d⇄OR、SMD、不可能输入)、合并(手工计算的固定/随机效应估计,三项研究得到 Q=8、I²=0.75、τ²=0.03)、合并与各研究 CI 按所请求置信水平计算、由 CI 推导 SE 及拒绝 SE/CI 不一致、非法模型/置信水平/研究输入、Egger 在 k=10 时的门控、异质性警告、工具 schema、格式错误报告拒绝、端到端报告、插件契约、包契约、启用/禁用挂载契约。
|
|
89
89
|
|
|
90
|
-
|
|
90
|
+
### 合成元分析基准
|
|
91
|
+
|
|
92
|
+
**20 组确定性合成基准**(数据集 `meta` v0.1.0,已冻结)位于同工作区的兄弟仓库 `dsh-research-bench` 的 `data/meta` 下,不随本包分发。每组给出研究输入(效应 + SE,或对称 CI)以及 fixed/random 合并、Q、df、pQ、I²、τ² 和 Egger 是否运行的闭式期望值。
|
|
93
|
+
|
|
94
|
+
覆盖:5 组同质(I²=0,τ²=0)、5 组中等异质、4 组高异质(Q>df,τ²>0)、2 组零效应、2 组负效应、2 组小 k;k=2(4 组)、k=5(5 组)、k=10(6 组)、k=12(5 组);10 组等 SE、10 组不等 SE;SE、CI 与混合输入。Egger 在 11 组 k≥10(含 k=10 边界)上运行,在 9 组 k<10 上不运行。
|
|
95
|
+
|
|
96
|
+
适配器逐组调用 `pool(studies, { model: 'both' })`,与生成器独立实现的闭式真值比较(不 import 插件,也不从插件输出反推期望值)。**20/20 全部通过**;绝对误差:
|
|
97
|
+
|
|
98
|
+
| 量 | 最大绝对误差 | 平均绝对误差 | 阈值 |
|
|
99
|
+
|---|---:|---:|---:|
|
|
100
|
+
| fixed/random 效应 | 1.11e-16 | 8.33e-18 | 1e-6 |
|
|
101
|
+
| fixed/random SE | 2.78e-17 | 1.74e-18 | 1e-6 |
|
|
102
|
+
| fixed/random CI | 2.22e-16 | 3.96e-17 | 1e-6 |
|
|
103
|
+
| Q | 8.53e-14 | 7.58e-15 | 1e-6 |
|
|
104
|
+
| τ² | 8.33e-17 | 6.72e-18 | 1e-6 |
|
|
105
|
+
| I² | 2.22e-16 | 1.94e-17 | 1e-9 |
|
|
106
|
+
| pQ | 1.67e-15 | 1.96e-16 | 1e-9 |
|
|
107
|
+
|
|
108
|
+
基准暴露了一个真实的精度上限:旧的 Acklam Φ⁻¹ 在 95% 处偏差 1.6e-9,经 CI 推导的 SE 放大后,两组 case 的 I² 偏差达到 1.12e-9;`normalQuantile` 改用 AS 241 后,Q 的最大误差为 8.5e-14。
|
|
109
|
+
|
|
110
|
+
```sh
|
|
111
|
+
pnpm run build
|
|
112
|
+
pnpm run bench:meta # 读取 ../dsh-research-bench/data/meta(可用 BENCH_DIR 覆盖)
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
输出 `bench/results-meta.json` 与 `bench/results-meta.md`(不含时间戳;重复运行字节一致)。
|
|
91
116
|
|
|
92
117
|
## 已知限制(v0.1)
|
|
93
118
|
|
package/README.md
CHANGED
|
@@ -41,7 +41,7 @@ English · [简体中文](README-zh.md)
|
|
|
41
41
|
| SMD | `(m₁−m₂)/s_pooled`, SE `√(1/n₁+1/n₂+d²/(2(n₁+n₂)))` |
|
|
42
42
|
| Egger | OLS intercept of `θᵢ/SEᵢ` on `1/SEᵢ`, t with df = k−2 |
|
|
43
43
|
|
|
44
|
-
Normal-tail p uses an A&S 7.1.26 approximation (~1e-7); χ² and t use regularized incomplete gamma/beta continued fractions (~1e-10).
|
|
44
|
+
Normal-tail p uses an A&S 7.1.26 approximation (~1e-7); Φ⁻¹ uses Wichura's AS 241 / PPND16 (~1e-16); χ² and t use regularized incomplete gamma/beta continued fractions (~1e-10). All are implemented in `src/math.ts` with no dependencies.
|
|
45
45
|
|
|
46
46
|
## Tools
|
|
47
47
|
|
|
@@ -85,9 +85,34 @@ dsh --profile <name> --dump-config | grep dsh-meta-analysis
|
|
|
85
85
|
|
|
86
86
|
## Evaluation
|
|
87
87
|
|
|
88
|
-
**
|
|
88
|
+
**23 unit tests**: special functions against known critical values (χ²(8,2)=0.9817, t(2.306,8)≈0.05, z(1.96)≈0.05, Φ⁻¹(0.975) to 12 decimal places), conversions (logOR+SE, d⇄r, d⇄OR, SMD, impossible inputs), pooling (hand-calculated fixed/random estimates, Q=8, I²=0.75, τ²=0.03 from three studies), the requested confidence level for pooled and study CIs, CI-derived SE and SE/CI disagreement rejection, invalid models/levels/studies, Egger gating at k=10, heterogeneity warnings, tool schemas, malformed-report rejection, end-to-end report, plugin contract, package contract and the enabled/disabled mount contract.
|
|
89
89
|
|
|
90
|
-
|
|
90
|
+
### Synthetic meta-analysis benchmark
|
|
91
|
+
|
|
92
|
+
A separate **20-case, deterministic synthetic benchmark** (dataset `meta` v0.1.0, frozen) lives in the sibling `dsh-research-bench` repository under `data/meta`; it is not vendored into this package. Each case supplies studies (effect + SE, or a symmetric CI) and closed-form expected values for fixed/random pooling, Q, df, pQ, I², τ² and Egger presence.
|
|
93
|
+
|
|
94
|
+
Coverage: 5 homogeneous cases (I²=0, τ²=0), 5 medium- and 4 high-heterogeneity cases (Q>df, τ²>0), 2 zero-effect, 2 negative-effect and 2 small-k cases; k = 2 (4 cases), 5 (5), 10 (6) and 12 (5); 10 equal-SE and 10 unequal-SE designs; SE-only, CI-only and mixed inputs. Egger runs on the 11 cases with k ≥ 10 (including the k=10 boundary) and on none of the 9 below it.
|
|
95
|
+
|
|
96
|
+
The adapter calls `pool(studies, { model: 'both' })` and compares against the generator's independent implementation (no plugin import, no expected value derived from plugin output). **20/20 cases pass**; absolute errors:
|
|
97
|
+
|
|
98
|
+
| Quantity | Max abs error | Mean abs error | Tolerance |
|
|
99
|
+
|---|---:|---:|---:|
|
|
100
|
+
| fixed/random effect | 1.11e-16 | 8.33e-18 | 1e-6 |
|
|
101
|
+
| fixed/random SE | 2.78e-17 | 1.74e-18 | 1e-6 |
|
|
102
|
+
| fixed/random CI | 2.22e-16 | 3.96e-17 | 1e-6 |
|
|
103
|
+
| Q | 8.53e-14 | 7.58e-15 | 1e-6 |
|
|
104
|
+
| τ² | 8.33e-17 | 6.72e-18 | 1e-6 |
|
|
105
|
+
| I² | 2.22e-16 | 1.94e-17 | 1e-9 |
|
|
106
|
+
| pQ | 1.67e-15 | 1.96e-16 | 1e-9 |
|
|
107
|
+
|
|
108
|
+
The benchmark surfaced one real precision limit: the old Acklam Φ⁻¹ was 1.6e-9 off at 95%, and CI-derived SEs amplified it into I² deviations of 1.12e-9 on two cases. `normalQuantile` now uses AS 241; the largest Q error is 8.5e-14.
|
|
109
|
+
|
|
110
|
+
```sh
|
|
111
|
+
pnpm run build
|
|
112
|
+
pnpm run bench:meta # reads ../dsh-research-bench/data/meta (BENCH_DIR overrides)
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
It writes `bench/results-meta.json` and `bench/results-meta.md` (no timestamps; re-running is byte-identical).
|
|
91
116
|
|
|
92
117
|
## Known limitations (v0.1)
|
|
93
118
|
|
package/lib/math.d.ts
CHANGED
|
@@ -3,9 +3,10 @@
|
|
|
3
3
|
* log-gamma, regularized lower incomplete gamma (χ² CDF), regularized
|
|
4
4
|
* incomplete beta (t CDF) and a two-sided normal tail.
|
|
5
5
|
*
|
|
6
|
-
* Accuracy target is ~1e-10 for the gamma/beta continued fractions
|
|
7
|
-
* for the normal tail approximation
|
|
8
|
-
*
|
|
6
|
+
* Accuracy target is ~1e-10 for the gamma/beta continued fractions, ~1e-7
|
|
7
|
+
* for the normal tail approximation and ~1e-16 for the normal quantile
|
|
8
|
+
* (Wichura's AS 241); that is enough for pooling output, and the README says
|
|
9
|
+
* which approximation is used.
|
|
9
10
|
*
|
|
10
11
|
* @module dsh-meta-analysis/math
|
|
11
12
|
*/
|
|
@@ -21,6 +22,6 @@ export declare function betaIncomplete(x: number, a: number, b: number): number;
|
|
|
21
22
|
export declare function tTwoSidedP(statistic: number, df: number): number;
|
|
22
23
|
/** Two-sided p-value for a z statistic (normal tail, A&S 7.1.26). */
|
|
23
24
|
export declare function zTwoSidedP(z: number): number;
|
|
24
|
-
/** Quantile of the standard normal (
|
|
25
|
+
/** Quantile of the standard normal (Wichura's AS 241 / PPND16, ~1e-16). */
|
|
25
26
|
export declare function normalQuantile(p: number): number;
|
|
26
27
|
//# sourceMappingURL=math.d.ts.map
|
package/lib/math.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"math.d.ts","sourceRoot":"","sources":["../src/math.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"math.d.ts","sourceRoot":"","sources":["../src/math.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAQH,wDAAwD;AACxD,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAU7C;AAED,iDAAiD;AACjD,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CA+BnD;AAED,2CAA2C;AAC3C,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAIlE;AAqCD,4CAA4C;AAC5C,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAMtE;AAED,wEAAwE;AACxE,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAIhE;AAED,qEAAqE;AACrE,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAK5C;AAmCD,2EAA2E;AAC3E,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAmBhD"}
|
package/lib/math.js
CHANGED
|
@@ -3,9 +3,10 @@
|
|
|
3
3
|
* log-gamma, regularized lower incomplete gamma (χ² CDF), regularized
|
|
4
4
|
* incomplete beta (t CDF) and a two-sided normal tail.
|
|
5
5
|
*
|
|
6
|
-
* Accuracy target is ~1e-10 for the gamma/beta continued fractions
|
|
7
|
-
* for the normal tail approximation
|
|
8
|
-
*
|
|
6
|
+
* Accuracy target is ~1e-10 for the gamma/beta continued fractions, ~1e-7
|
|
7
|
+
* for the normal tail approximation and ~1e-16 for the normal quantile
|
|
8
|
+
* (Wichura's AS 241); that is enough for pooling output, and the README says
|
|
9
|
+
* which approximation is used.
|
|
9
10
|
*
|
|
10
11
|
* @module dsh-meta-analysis/math
|
|
11
12
|
*/
|
|
@@ -138,25 +139,60 @@ export function zTwoSidedP(z) {
|
|
|
138
139
|
const erf = 1 - ((((1.061405429 * t - 1.453152027) * t + 1.421413741) * t - 0.284496736) * t + 0.254829592) * t * Math.exp(-x * x);
|
|
139
140
|
return Math.max(0, Math.min(1, 1 - erf));
|
|
140
141
|
}
|
|
141
|
-
/**
|
|
142
|
+
/** AS 241 (PPND16) coefficients, lowest degree first. */
|
|
143
|
+
const AS241_A = [
|
|
144
|
+
3.387132872796366608, 1.3314166789178437745e2, 1.9715909503065514427e3, 1.3731693765509461125e4,
|
|
145
|
+
4.5921953931549871457e4, 6.7265770927008700853e4, 3.3430575583588128105e4, 2.5090809287301226727e3,
|
|
146
|
+
];
|
|
147
|
+
const AS241_B = [
|
|
148
|
+
1, 4.2313330701600911252e1, 6.871870074920579083e2, 5.3941960214247511077e3,
|
|
149
|
+
2.1213794301586595867e4, 3.930789580009271061e4, 2.8729085735721942674e4, 5.226495278852854561e3,
|
|
150
|
+
];
|
|
151
|
+
const AS241_C = [
|
|
152
|
+
1.42343711074968357734, 4.6303378461565452959, 5.7694972214606914055, 3.64784832476320460504,
|
|
153
|
+
1.27045825245236838258, 2.4178072517745061177e-1, 2.27238449892691845833e-2, 7.7454501427834140764e-4,
|
|
154
|
+
];
|
|
155
|
+
const AS241_D = [
|
|
156
|
+
1, 2.05319162663775882187, 1.6763848301838038494, 6.8976733498510000455e-1,
|
|
157
|
+
1.4810397642748007459e-1, 1.51986665636164571966e-2, 5.475938084995344946e-4, 1.05075007164441684324e-9,
|
|
158
|
+
];
|
|
159
|
+
const AS241_E = [
|
|
160
|
+
6.6579046435011037772, 5.4637849111641143699, 1.7848265399172913358, 2.9656057182850489123e-1,
|
|
161
|
+
2.6532189526576123093e-2, 1.2426609473880784386e-3, 2.71155556874348757815e-5, 2.01033439929228813265e-7,
|
|
162
|
+
];
|
|
163
|
+
const AS241_F = [
|
|
164
|
+
1, 5.9983220655588793769e-1, 1.3692988092273580531e-1, 1.48753612908506148525e-2,
|
|
165
|
+
7.868691311456132591e-4, 1.8463183175100546818e-5, 1.4215117583164458887e-7, 2.04426310338993978564e-15,
|
|
166
|
+
];
|
|
167
|
+
/** Horner evaluation with the coefficients ordered from lowest to highest degree. */
|
|
168
|
+
function horner(coefficients, value) {
|
|
169
|
+
let result = coefficients[coefficients.length - 1];
|
|
170
|
+
for (let index = coefficients.length - 2; index >= 0; index -= 1)
|
|
171
|
+
result = result * value + coefficients[index];
|
|
172
|
+
return result;
|
|
173
|
+
}
|
|
174
|
+
/** Quantile of the standard normal (Wichura's AS 241 / PPND16, ~1e-16). */
|
|
142
175
|
export function normalQuantile(p) {
|
|
143
176
|
if (p <= 0)
|
|
144
177
|
return Number.NEGATIVE_INFINITY;
|
|
145
178
|
if (p >= 1)
|
|
146
179
|
return Number.POSITIVE_INFINITY;
|
|
147
|
-
const a = [-3.969683028665376e1, 2.209460984245205e2, -2.759285104469687e2, 1.38357751867269e2, -3.066479806614716e1, 2.506628277459239];
|
|
148
|
-
const b = [-5.447609879822406e1, 1.615858368580409e2, -1.556989798598866e2, 6.680131188771972e1, -1.328068155288572e1];
|
|
149
|
-
const c = [-7.784894002430293e-3, -3.223964580411365e-1, -2.400758277161838, -2.549732539343734, 4.374664141464968, 2.938163982698783];
|
|
150
|
-
const d = [7.784695709041462e-3, 3.224671290700398e-1, 2.445134137142996, 3.754408661907416];
|
|
151
|
-
const low = 0.02425;
|
|
152
|
-
if (p < low) {
|
|
153
|
-
const q = Math.sqrt(-2 * Math.log(p));
|
|
154
|
-
return (((((c[0] * q + c[1]) * q + c[2]) * q + c[3]) * q + c[4]) * q + c[5]) / ((((d[0] * q + d[1]) * q + d[2]) * q + d[3]) * q + 1);
|
|
155
|
-
}
|
|
156
|
-
if (p > 1 - low)
|
|
157
|
-
return -normalQuantile(1 - p);
|
|
158
180
|
const q = p - 0.5;
|
|
159
|
-
|
|
160
|
-
|
|
181
|
+
if (Math.abs(q) <= 0.425) {
|
|
182
|
+
const r = 0.180625 - q * q;
|
|
183
|
+
return (q * horner(AS241_A, r)) / horner(AS241_B, r);
|
|
184
|
+
}
|
|
185
|
+
const tail = q < 0 ? p : 1 - p;
|
|
186
|
+
const r = Math.sqrt(-Math.log(tail));
|
|
187
|
+
let value;
|
|
188
|
+
if (r <= 5) {
|
|
189
|
+
const shifted = r - 1.6;
|
|
190
|
+
value = horner(AS241_C, shifted) / horner(AS241_D, shifted);
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
const shifted = r - 5;
|
|
194
|
+
value = horner(AS241_E, shifted) / horner(AS241_F, shifted);
|
|
195
|
+
}
|
|
196
|
+
return q < 0 ? -value : value;
|
|
161
197
|
}
|
|
162
198
|
//# sourceMappingURL=math.js.map
|
package/lib/math.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"math.js","sourceRoot":"","sources":["../src/math.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"math.js","sourceRoot":"","sources":["../src/math.ts"],"names":[],"mappings":"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"}
|
package/lib/version.d.ts
CHANGED
package/lib/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-meta-analysis",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Meta-analysis arithmetic for DeepSeek Harness: effect-size conversions (OR/RR/d/r/SMD, SE from CI) with named formulas, fixed-effect and DerSimonian-Laird random-effects pooling, Q/df/p, I2, tau2, forest-plot data, Markdown/SARIF reports and a light Egger test for k >= 10. Local, dependency-free, reproducible from the inputs.",
|
|
5
5
|
"author": "PerryLink contributors",
|
|
6
6
|
"repository": {
|
|
@@ -77,7 +77,8 @@
|
|
|
77
77
|
"typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.test.json",
|
|
78
78
|
"test": "vitest run",
|
|
79
79
|
"test:watch": "vitest",
|
|
80
|
-
"verify:package": "node scripts/verify-package.mjs"
|
|
80
|
+
"verify:package": "node scripts/verify-package.mjs",
|
|
81
|
+
"bench:meta": "node bench/run-meta.mjs"
|
|
81
82
|
},
|
|
82
83
|
"license": "Apache-2.0"
|
|
83
84
|
}
|
package/src/math.ts
CHANGED
|
@@ -3,9 +3,10 @@
|
|
|
3
3
|
* log-gamma, regularized lower incomplete gamma (χ² CDF), regularized
|
|
4
4
|
* incomplete beta (t CDF) and a two-sided normal tail.
|
|
5
5
|
*
|
|
6
|
-
* Accuracy target is ~1e-10 for the gamma/beta continued fractions
|
|
7
|
-
* for the normal tail approximation
|
|
8
|
-
*
|
|
6
|
+
* Accuracy target is ~1e-10 for the gamma/beta continued fractions, ~1e-7
|
|
7
|
+
* for the normal tail approximation and ~1e-16 for the normal quantile
|
|
8
|
+
* (Wichura's AS 241); that is enough for pooling output, and the README says
|
|
9
|
+
* which approximation is used.
|
|
9
10
|
*
|
|
10
11
|
* @module dsh-meta-analysis/math
|
|
11
12
|
*/
|
|
@@ -129,21 +130,57 @@ export function zTwoSidedP(z: number): number {
|
|
|
129
130
|
return Math.max(0, Math.min(1, 1 - erf))
|
|
130
131
|
}
|
|
131
132
|
|
|
132
|
-
/**
|
|
133
|
+
/** AS 241 (PPND16) coefficients, lowest degree first. */
|
|
134
|
+
const AS241_A = [
|
|
135
|
+
3.387132872796366608, 1.3314166789178437745e2, 1.9715909503065514427e3, 1.3731693765509461125e4,
|
|
136
|
+
4.5921953931549871457e4, 6.7265770927008700853e4, 3.3430575583588128105e4, 2.5090809287301226727e3,
|
|
137
|
+
]
|
|
138
|
+
const AS241_B = [
|
|
139
|
+
1, 4.2313330701600911252e1, 6.871870074920579083e2, 5.3941960214247511077e3,
|
|
140
|
+
2.1213794301586595867e4, 3.930789580009271061e4, 2.8729085735721942674e4, 5.226495278852854561e3,
|
|
141
|
+
]
|
|
142
|
+
const AS241_C = [
|
|
143
|
+
1.42343711074968357734, 4.6303378461565452959, 5.7694972214606914055, 3.64784832476320460504,
|
|
144
|
+
1.27045825245236838258, 2.4178072517745061177e-1, 2.27238449892691845833e-2, 7.7454501427834140764e-4,
|
|
145
|
+
]
|
|
146
|
+
const AS241_D = [
|
|
147
|
+
1, 2.05319162663775882187, 1.6763848301838038494, 6.8976733498510000455e-1,
|
|
148
|
+
1.4810397642748007459e-1, 1.51986665636164571966e-2, 5.475938084995344946e-4, 1.05075007164441684324e-9,
|
|
149
|
+
]
|
|
150
|
+
const AS241_E = [
|
|
151
|
+
6.6579046435011037772, 5.4637849111641143699, 1.7848265399172913358, 2.9656057182850489123e-1,
|
|
152
|
+
2.6532189526576123093e-2, 1.2426609473880784386e-3, 2.71155556874348757815e-5, 2.01033439929228813265e-7,
|
|
153
|
+
]
|
|
154
|
+
const AS241_F = [
|
|
155
|
+
1, 5.9983220655588793769e-1, 1.3692988092273580531e-1, 1.48753612908506148525e-2,
|
|
156
|
+
7.868691311456132591e-4, 1.8463183175100546818e-5, 1.4215117583164458887e-7, 2.04426310338993978564e-15,
|
|
157
|
+
]
|
|
158
|
+
|
|
159
|
+
/** Horner evaluation with the coefficients ordered from lowest to highest degree. */
|
|
160
|
+
function horner(coefficients: readonly number[], value: number): number {
|
|
161
|
+
let result = coefficients[coefficients.length - 1]!
|
|
162
|
+
for (let index = coefficients.length - 2; index >= 0; index -= 1) result = result * value + coefficients[index]!
|
|
163
|
+
return result
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/** Quantile of the standard normal (Wichura's AS 241 / PPND16, ~1e-16). */
|
|
133
167
|
export function normalQuantile(p: number): number {
|
|
134
168
|
if (p <= 0) return Number.NEGATIVE_INFINITY
|
|
135
169
|
if (p >= 1) return Number.POSITIVE_INFINITY
|
|
136
|
-
const a = [-3.969683028665376e1, 2.209460984245205e2, -2.759285104469687e2, 1.38357751867269e2, -3.066479806614716e1, 2.506628277459239]
|
|
137
|
-
const b = [-5.447609879822406e1, 1.615858368580409e2, -1.556989798598866e2, 6.680131188771972e1, -1.328068155288572e1]
|
|
138
|
-
const c = [-7.784894002430293e-3, -3.223964580411365e-1, -2.400758277161838, -2.549732539343734, 4.374664141464968, 2.938163982698783]
|
|
139
|
-
const d = [7.784695709041462e-3, 3.224671290700398e-1, 2.445134137142996, 3.754408661907416]
|
|
140
|
-
const low = 0.02425
|
|
141
|
-
if (p < low) {
|
|
142
|
-
const q = Math.sqrt(-2 * Math.log(p))
|
|
143
|
-
return (((((c[0]! * q + c[1]!) * q + c[2]!) * q + c[3]!) * q + c[4]!) * q + c[5]!) / ((((d[0]! * q + d[1]!) * q + d[2]!) * q + d[3]!) * q + 1)
|
|
144
|
-
}
|
|
145
|
-
if (p > 1 - low) return -normalQuantile(1 - p)
|
|
146
170
|
const q = p - 0.5
|
|
147
|
-
|
|
148
|
-
|
|
171
|
+
if (Math.abs(q) <= 0.425) {
|
|
172
|
+
const r = 0.180625 - q * q
|
|
173
|
+
return (q * horner(AS241_A, r)) / horner(AS241_B, r)
|
|
174
|
+
}
|
|
175
|
+
const tail = q < 0 ? p : 1 - p
|
|
176
|
+
const r = Math.sqrt(-Math.log(tail))
|
|
177
|
+
let value: number
|
|
178
|
+
if (r <= 5) {
|
|
179
|
+
const shifted = r - 1.6
|
|
180
|
+
value = horner(AS241_C, shifted) / horner(AS241_D, shifted)
|
|
181
|
+
} else {
|
|
182
|
+
const shifted = r - 5
|
|
183
|
+
value = horner(AS241_E, shifted) / horner(AS241_F, shifted)
|
|
184
|
+
}
|
|
185
|
+
return q < 0 ? -value : value
|
|
149
186
|
}
|
package/src/version.ts
CHANGED