@iyulab/u-numflow 0.6.2 → 0.6.3

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 CHANGED
@@ -17,7 +17,7 @@ u-numflow provides foundational mathematical, statistical, and probabilistic bui
17
17
  |--------|-------------|
18
18
  | `stats` | Descriptive statistics (mean, variance, skewness, kurtosis) with Welford's online algorithm and Neumaier summation |
19
19
  | `distributions` | Probability distributions: Uniform, Triangular, PERT, Normal, LogNormal |
20
- | `special` | Special functions: normal CDF and tail-precise survival function (and their inverses), t/F/chi² CDF, regularized incomplete beta/gamma, erf |
20
+ | `special` | Special functions: normal CDF and tail-precise survival function (and their inverses), t/F/chi² CDF and quantiles, the noncentral t CDF (Lenth AS 243 — the distribution power is computed from), regularized incomplete beta/gamma, erf |
21
21
  | `transforms` | Data transformations: Box-Cox (λ via MLE golden-section search), inverse Box-Cox |
22
22
  | `fourier` | Discrete Fourier transform of any length (radix-2 for powers of two, Bluestein otherwise): `fft`, `ifft`, `rfft`, `Complex` |
23
23
  | `matrix` | Dense matrix operations: determinant, inverse, Cholesky decomposition, Jacobi eigenvalue decomposition |
@@ -104,6 +104,25 @@ Exported functions: `mean`, `std_dev`, `variance`, `normal_cdf`, `normal_sf` (up
104
104
  `rfft(data) -> Float64Array` — the DFT of a real sequence of any length, interleaved as
105
105
  `[re0, im0, re1, im1, …]` (bins `k` and `n − k` are conjugates, so `0..=n/2` describes the spectrum).
106
106
 
107
+ Distribution functions for critical values and p-values — each returns a `number` and
108
+ **throws** (a message naming the argument) when an argument is outside the domain,
109
+ rather than returning `NaN`:
110
+
111
+ | Function | Returns |
112
+ |---|---|
113
+ | `inverse_normal_cdf(p)` | `z` with `P(Z ≤ z) = p` |
114
+ | `t_distribution_cdf(t, df)` / `t_distribution_quantile(p, df)` | Student's t; a two-sided critical value at level α is `t_distribution_quantile(1 − α/2, df)` |
115
+ | `f_distribution_cdf(x, df1, df2)` / `f_distribution_quantile(p, df1, df2)` | F |
116
+ | `chi_squared_cdf(x, k)` / `chi_squared_quantile(p, k)` | χ² |
117
+
118
+ `p` must lie strictly between 0 and 1 and every degrees-of-freedom argument must be a
119
+ finite number `> 0` (fractional values are allowed).
120
+
121
+ ```js
122
+ const { t_distribution_quantile } = require("@iyulab/u-numflow");
123
+ t_distribution_quantile(0.975, 10); // 2.2281…
124
+ ```
125
+
107
126
  ### TypeScript
108
127
 
109
128
  Every exported function declares its return type, and the declarations are
@@ -25,6 +25,43 @@ function box_cox(data, lambda) {
25
25
  }
26
26
  exports.box_cox = box_cox;
27
27
 
28
+ /**
29
+ * Chi-squared CDF: `P(X ≤ x)` for `X ~ χ²(k)` (`0` for `x ≤ 0`).
30
+ *
31
+ * # Errors
32
+ * Throws if `x` is NaN or `k` is not a finite number > 0.
33
+ * @param {number} x
34
+ * @param {number} k
35
+ * @returns {number}
36
+ */
37
+ function chi_squared_cdf(x, k) {
38
+ const ret = wasm.chi_squared_cdf(x, k);
39
+ if (ret[2]) {
40
+ throw takeFromExternrefTable0(ret[1]);
41
+ }
42
+ return ret[0];
43
+ }
44
+ exports.chi_squared_cdf = chi_squared_cdf;
45
+
46
+ /**
47
+ * Chi-squared quantile: the `x` with `P(X ≤ x) = p` for `X ~ χ²(k)`.
48
+ *
49
+ * # Errors
50
+ * Throws if `p` is not strictly between 0 and 1, or `k` is not a finite
51
+ * number > 0.
52
+ * @param {number} p
53
+ * @param {number} k
54
+ * @returns {number}
55
+ */
56
+ function chi_squared_quantile(p, k) {
57
+ const ret = wasm.chi_squared_quantile(p, k);
58
+ if (ret[2]) {
59
+ throw takeFromExternrefTable0(ret[1]);
60
+ }
61
+ return ret[0];
62
+ }
63
+ exports.chi_squared_quantile = chi_squared_quantile;
64
+
28
65
  /**
29
66
  * Estimate the optimal Box-Cox lambda via profile maximum likelihood.
30
67
  *
@@ -54,6 +91,62 @@ function estimate_lambda(data, lambda_min, lambda_max) {
54
91
  }
55
92
  exports.estimate_lambda = estimate_lambda;
56
93
 
94
+ /**
95
+ * F CDF: `P(X ≤ x)` for `X ~ F(df1, df2)` (`0` for `x ≤ 0`).
96
+ *
97
+ * # Errors
98
+ * Throws if `x` is NaN, or `df1`/`df2` is not a finite number > 0.
99
+ * @param {number} x
100
+ * @param {number} df1
101
+ * @param {number} df2
102
+ * @returns {number}
103
+ */
104
+ function f_distribution_cdf(x, df1, df2) {
105
+ const ret = wasm.f_distribution_cdf(x, df1, df2);
106
+ if (ret[2]) {
107
+ throw takeFromExternrefTable0(ret[1]);
108
+ }
109
+ return ret[0];
110
+ }
111
+ exports.f_distribution_cdf = f_distribution_cdf;
112
+
113
+ /**
114
+ * F quantile: the `x` with `P(X ≤ x) = p` for `X ~ F(df1, df2)`.
115
+ *
116
+ * # Errors
117
+ * Throws if `p` is not strictly between 0 and 1, or `df1`/`df2` is not a
118
+ * finite number > 0.
119
+ * @param {number} p
120
+ * @param {number} df1
121
+ * @param {number} df2
122
+ * @returns {number}
123
+ */
124
+ function f_distribution_quantile(p, df1, df2) {
125
+ const ret = wasm.f_distribution_quantile(p, df1, df2);
126
+ if (ret[2]) {
127
+ throw takeFromExternrefTable0(ret[1]);
128
+ }
129
+ return ret[0];
130
+ }
131
+ exports.f_distribution_quantile = f_distribution_quantile;
132
+
133
+ /**
134
+ * Standard normal quantile Φ⁻¹(p): the `z` with `P(Z ≤ z) = p`.
135
+ *
136
+ * # Errors
137
+ * Throws if `p` is not strictly between 0 and 1.
138
+ * @param {number} p
139
+ * @returns {number}
140
+ */
141
+ function inverse_normal_cdf(p) {
142
+ const ret = wasm.inverse_normal_cdf(p);
143
+ if (ret[2]) {
144
+ throw takeFromExternrefTable0(ret[1]);
145
+ }
146
+ return ret[0];
147
+ }
148
+ exports.inverse_normal_cdf = inverse_normal_cdf;
149
+
57
150
  /**
58
151
  * Arithmetic mean of `data` using Kahan compensated summation.
59
152
  *
@@ -134,6 +227,44 @@ function std_dev(data) {
134
227
  }
135
228
  exports.std_dev = std_dev;
136
229
 
230
+ /**
231
+ * Student's t CDF: `P(T ≤ t)` for `T ~ t(df)`. `df` may be fractional.
232
+ *
233
+ * # Errors
234
+ * Throws if `t` is NaN or `df` is not a finite number > 0.
235
+ * @param {number} t
236
+ * @param {number} df
237
+ * @returns {number}
238
+ */
239
+ function t_distribution_cdf(t, df) {
240
+ const ret = wasm.t_distribution_cdf(t, df);
241
+ if (ret[2]) {
242
+ throw takeFromExternrefTable0(ret[1]);
243
+ }
244
+ return ret[0];
245
+ }
246
+ exports.t_distribution_cdf = t_distribution_cdf;
247
+
248
+ /**
249
+ * Student's t quantile: the `t` with `P(T ≤ t) = p`. A two-sided critical
250
+ * value at level α is `t_distribution_quantile(1 − α/2, df)`.
251
+ *
252
+ * # Errors
253
+ * Throws if `p` is not strictly between 0 and 1, or `df` is not a finite
254
+ * number > 0.
255
+ * @param {number} p
256
+ * @param {number} df
257
+ * @returns {number}
258
+ */
259
+ function t_distribution_quantile(p, df) {
260
+ const ret = wasm.t_distribution_quantile(p, df);
261
+ if (ret[2]) {
262
+ throw takeFromExternrefTable0(ret[1]);
263
+ }
264
+ return ret[0];
265
+ }
266
+ exports.t_distribution_quantile = t_distribution_quantile;
267
+
137
268
  /**
138
269
  * Sample variance of `data` (Bessel-corrected, denominator n−1).
139
270
  *
@@ -20,6 +20,23 @@ export interface LambdaEstimateDto {
20
20
  */
21
21
  export function box_cox(data: Float64Array, lambda: number): Float64Array;
22
22
 
23
+ /**
24
+ * Chi-squared CDF: `P(X ≤ x)` for `X ~ χ²(k)` (`0` for `x ≤ 0`).
25
+ *
26
+ * # Errors
27
+ * Throws if `x` is NaN or `k` is not a finite number > 0.
28
+ */
29
+ export function chi_squared_cdf(x: number, k: number): number;
30
+
31
+ /**
32
+ * Chi-squared quantile: the `x` with `P(X ≤ x) = p` for `X ~ χ²(k)`.
33
+ *
34
+ * # Errors
35
+ * Throws if `p` is not strictly between 0 and 1, or `k` is not a finite
36
+ * number > 0.
37
+ */
38
+ export function chi_squared_quantile(p: number, k: number): number;
39
+
23
40
  /**
24
41
  * Estimate the optimal Box-Cox lambda via profile maximum likelihood.
25
42
  *
@@ -36,6 +53,31 @@ export function box_cox(data: Float64Array, lambda: number): Float64Array;
36
53
  */
37
54
  export function estimate_lambda(data: Float64Array, lambda_min: number, lambda_max: number): LambdaEstimateDto;
38
55
 
56
+ /**
57
+ * F CDF: `P(X ≤ x)` for `X ~ F(df1, df2)` (`0` for `x ≤ 0`).
58
+ *
59
+ * # Errors
60
+ * Throws if `x` is NaN, or `df1`/`df2` is not a finite number > 0.
61
+ */
62
+ export function f_distribution_cdf(x: number, df1: number, df2: number): number;
63
+
64
+ /**
65
+ * F quantile: the `x` with `P(X ≤ x) = p` for `X ~ F(df1, df2)`.
66
+ *
67
+ * # Errors
68
+ * Throws if `p` is not strictly between 0 and 1, or `df1`/`df2` is not a
69
+ * finite number > 0.
70
+ */
71
+ export function f_distribution_quantile(p: number, df1: number, df2: number): number;
72
+
73
+ /**
74
+ * Standard normal quantile Φ⁻¹(p): the `z` with `P(Z ≤ z) = p`.
75
+ *
76
+ * # Errors
77
+ * Throws if `p` is not strictly between 0 and 1.
78
+ */
79
+ export function inverse_normal_cdf(p: number): number;
80
+
39
81
  /**
40
82
  * Arithmetic mean of `data` using Kahan compensated summation.
41
83
  *
@@ -78,6 +120,24 @@ export function rfft(data: Float64Array): Float64Array;
78
120
  */
79
121
  export function std_dev(data: Float64Array): number;
80
122
 
123
+ /**
124
+ * Student's t CDF: `P(T ≤ t)` for `T ~ t(df)`. `df` may be fractional.
125
+ *
126
+ * # Errors
127
+ * Throws if `t` is NaN or `df` is not a finite number > 0.
128
+ */
129
+ export function t_distribution_cdf(t: number, df: number): number;
130
+
131
+ /**
132
+ * Student's t quantile: the `t` with `P(T ≤ t) = p`. A two-sided critical
133
+ * value at level α is `t_distribution_quantile(1 − α/2, df)`.
134
+ *
135
+ * # Errors
136
+ * Throws if `p` is not strictly between 0 and 1, or `df` is not a finite
137
+ * number > 0.
138
+ */
139
+ export function t_distribution_quantile(p: number, df: number): number;
140
+
81
141
  /**
82
142
  * Sample variance of `data` (Bessel-corrected, denominator n−1).
83
143
  *
Binary file
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "iyulab"
6
6
  ],
7
7
  "description": "Foundational mathematical primitives: statistics, probability distributions, random sampling, and collections.",
8
- "version": "0.6.2",
8
+ "version": "0.6.3",
9
9
  "license": "MIT",
10
10
  "repository": {
11
11
  "type": "git",
package/u_numflow.d.ts CHANGED
@@ -20,6 +20,23 @@ export interface LambdaEstimateDto {
20
20
  */
21
21
  export function box_cox(data: Float64Array, lambda: number): Float64Array;
22
22
 
23
+ /**
24
+ * Chi-squared CDF: `P(X ≤ x)` for `X ~ χ²(k)` (`0` for `x ≤ 0`).
25
+ *
26
+ * # Errors
27
+ * Throws if `x` is NaN or `k` is not a finite number > 0.
28
+ */
29
+ export function chi_squared_cdf(x: number, k: number): number;
30
+
31
+ /**
32
+ * Chi-squared quantile: the `x` with `P(X ≤ x) = p` for `X ~ χ²(k)`.
33
+ *
34
+ * # Errors
35
+ * Throws if `p` is not strictly between 0 and 1, or `k` is not a finite
36
+ * number > 0.
37
+ */
38
+ export function chi_squared_quantile(p: number, k: number): number;
39
+
23
40
  /**
24
41
  * Estimate the optimal Box-Cox lambda via profile maximum likelihood.
25
42
  *
@@ -36,6 +53,31 @@ export function box_cox(data: Float64Array, lambda: number): Float64Array;
36
53
  */
37
54
  export function estimate_lambda(data: Float64Array, lambda_min: number, lambda_max: number): LambdaEstimateDto;
38
55
 
56
+ /**
57
+ * F CDF: `P(X ≤ x)` for `X ~ F(df1, df2)` (`0` for `x ≤ 0`).
58
+ *
59
+ * # Errors
60
+ * Throws if `x` is NaN, or `df1`/`df2` is not a finite number > 0.
61
+ */
62
+ export function f_distribution_cdf(x: number, df1: number, df2: number): number;
63
+
64
+ /**
65
+ * F quantile: the `x` with `P(X ≤ x) = p` for `X ~ F(df1, df2)`.
66
+ *
67
+ * # Errors
68
+ * Throws if `p` is not strictly between 0 and 1, or `df1`/`df2` is not a
69
+ * finite number > 0.
70
+ */
71
+ export function f_distribution_quantile(p: number, df1: number, df2: number): number;
72
+
73
+ /**
74
+ * Standard normal quantile Φ⁻¹(p): the `z` with `P(Z ≤ z) = p`.
75
+ *
76
+ * # Errors
77
+ * Throws if `p` is not strictly between 0 and 1.
78
+ */
79
+ export function inverse_normal_cdf(p: number): number;
80
+
39
81
  /**
40
82
  * Arithmetic mean of `data` using Kahan compensated summation.
41
83
  *
@@ -78,6 +120,24 @@ export function rfft(data: Float64Array): Float64Array;
78
120
  */
79
121
  export function std_dev(data: Float64Array): number;
80
122
 
123
+ /**
124
+ * Student's t CDF: `P(T ≤ t)` for `T ~ t(df)`. `df` may be fractional.
125
+ *
126
+ * # Errors
127
+ * Throws if `t` is NaN or `df` is not a finite number > 0.
128
+ */
129
+ export function t_distribution_cdf(t: number, df: number): number;
130
+
131
+ /**
132
+ * Student's t quantile: the `t` with `P(T ≤ t) = p`. A two-sided critical
133
+ * value at level α is `t_distribution_quantile(1 − α/2, df)`.
134
+ *
135
+ * # Errors
136
+ * Throws if `p` is not strictly between 0 and 1, or `df` is not a finite
137
+ * number > 0.
138
+ */
139
+ export function t_distribution_quantile(p: number, df: number): number;
140
+
81
141
  /**
82
142
  * Sample variance of `data` (Bessel-corrected, denominator n−1).
83
143
  *
package/u_numflow.js CHANGED
@@ -5,5 +5,5 @@ import { __wbg_set_wasm } from "./u_numflow_bg.js";
5
5
  __wbg_set_wasm(wasm);
6
6
  wasm.__wbindgen_start();
7
7
  export {
8
- box_cox, estimate_lambda, mean, normal_cdf, normal_sf, rfft, std_dev, variance
8
+ box_cox, chi_squared_cdf, chi_squared_quantile, estimate_lambda, f_distribution_cdf, f_distribution_quantile, inverse_normal_cdf, mean, normal_cdf, normal_sf, rfft, std_dev, t_distribution_cdf, t_distribution_quantile, variance
9
9
  } from "./u_numflow_bg.js";
package/u_numflow_bg.js CHANGED
@@ -22,6 +22,41 @@ export function box_cox(data, lambda) {
22
22
  return v2;
23
23
  }
24
24
 
25
+ /**
26
+ * Chi-squared CDF: `P(X ≤ x)` for `X ~ χ²(k)` (`0` for `x ≤ 0`).
27
+ *
28
+ * # Errors
29
+ * Throws if `x` is NaN or `k` is not a finite number > 0.
30
+ * @param {number} x
31
+ * @param {number} k
32
+ * @returns {number}
33
+ */
34
+ export function chi_squared_cdf(x, k) {
35
+ const ret = wasm.chi_squared_cdf(x, k);
36
+ if (ret[2]) {
37
+ throw takeFromExternrefTable0(ret[1]);
38
+ }
39
+ return ret[0];
40
+ }
41
+
42
+ /**
43
+ * Chi-squared quantile: the `x` with `P(X ≤ x) = p` for `X ~ χ²(k)`.
44
+ *
45
+ * # Errors
46
+ * Throws if `p` is not strictly between 0 and 1, or `k` is not a finite
47
+ * number > 0.
48
+ * @param {number} p
49
+ * @param {number} k
50
+ * @returns {number}
51
+ */
52
+ export function chi_squared_quantile(p, k) {
53
+ const ret = wasm.chi_squared_quantile(p, k);
54
+ if (ret[2]) {
55
+ throw takeFromExternrefTable0(ret[1]);
56
+ }
57
+ return ret[0];
58
+ }
59
+
25
60
  /**
26
61
  * Estimate the optimal Box-Cox lambda via profile maximum likelihood.
27
62
  *
@@ -50,6 +85,59 @@ export function estimate_lambda(data, lambda_min, lambda_max) {
50
85
  return takeFromExternrefTable0(ret[0]);
51
86
  }
52
87
 
88
+ /**
89
+ * F CDF: `P(X ≤ x)` for `X ~ F(df1, df2)` (`0` for `x ≤ 0`).
90
+ *
91
+ * # Errors
92
+ * Throws if `x` is NaN, or `df1`/`df2` is not a finite number > 0.
93
+ * @param {number} x
94
+ * @param {number} df1
95
+ * @param {number} df2
96
+ * @returns {number}
97
+ */
98
+ export function f_distribution_cdf(x, df1, df2) {
99
+ const ret = wasm.f_distribution_cdf(x, df1, df2);
100
+ if (ret[2]) {
101
+ throw takeFromExternrefTable0(ret[1]);
102
+ }
103
+ return ret[0];
104
+ }
105
+
106
+ /**
107
+ * F quantile: the `x` with `P(X ≤ x) = p` for `X ~ F(df1, df2)`.
108
+ *
109
+ * # Errors
110
+ * Throws if `p` is not strictly between 0 and 1, or `df1`/`df2` is not a
111
+ * finite number > 0.
112
+ * @param {number} p
113
+ * @param {number} df1
114
+ * @param {number} df2
115
+ * @returns {number}
116
+ */
117
+ export function f_distribution_quantile(p, df1, df2) {
118
+ const ret = wasm.f_distribution_quantile(p, df1, df2);
119
+ if (ret[2]) {
120
+ throw takeFromExternrefTable0(ret[1]);
121
+ }
122
+ return ret[0];
123
+ }
124
+
125
+ /**
126
+ * Standard normal quantile Φ⁻¹(p): the `z` with `P(Z ≤ z) = p`.
127
+ *
128
+ * # Errors
129
+ * Throws if `p` is not strictly between 0 and 1.
130
+ * @param {number} p
131
+ * @returns {number}
132
+ */
133
+ export function inverse_normal_cdf(p) {
134
+ const ret = wasm.inverse_normal_cdf(p);
135
+ if (ret[2]) {
136
+ throw takeFromExternrefTable0(ret[1]);
137
+ }
138
+ return ret[0];
139
+ }
140
+
53
141
  /**
54
142
  * Arithmetic mean of `data` using Kahan compensated summation.
55
143
  *
@@ -125,6 +213,42 @@ export function std_dev(data) {
125
213
  return ret;
126
214
  }
127
215
 
216
+ /**
217
+ * Student's t CDF: `P(T ≤ t)` for `T ~ t(df)`. `df` may be fractional.
218
+ *
219
+ * # Errors
220
+ * Throws if `t` is NaN or `df` is not a finite number > 0.
221
+ * @param {number} t
222
+ * @param {number} df
223
+ * @returns {number}
224
+ */
225
+ export function t_distribution_cdf(t, df) {
226
+ const ret = wasm.t_distribution_cdf(t, df);
227
+ if (ret[2]) {
228
+ throw takeFromExternrefTable0(ret[1]);
229
+ }
230
+ return ret[0];
231
+ }
232
+
233
+ /**
234
+ * Student's t quantile: the `t` with `P(T ≤ t) = p`. A two-sided critical
235
+ * value at level α is `t_distribution_quantile(1 − α/2, df)`.
236
+ *
237
+ * # Errors
238
+ * Throws if `p` is not strictly between 0 and 1, or `df` is not a finite
239
+ * number > 0.
240
+ * @param {number} p
241
+ * @param {number} df
242
+ * @returns {number}
243
+ */
244
+ export function t_distribution_quantile(p, df) {
245
+ const ret = wasm.t_distribution_quantile(p, df);
246
+ if (ret[2]) {
247
+ throw takeFromExternrefTable0(ret[1]);
248
+ }
249
+ return ret[0];
250
+ }
251
+
128
252
  /**
129
253
  * Sample variance of `data` (Bessel-corrected, denominator n−1).
130
254
  *
package/u_numflow_bg.wasm CHANGED
Binary file