@compstats/core 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/CHANGELOG.md +71 -0
  2. package/README.md +117 -116
  3. package/dist/3d.js +1120 -122
  4. package/dist/3d.js.map +16 -9
  5. package/dist/core/arith.d.ts.map +1 -1
  6. package/dist/core/linalg/cov.d.ts +50 -0
  7. package/dist/core/linalg/cov.d.ts.map +1 -0
  8. package/dist/core/linalg/eigen.d.ts +53 -0
  9. package/dist/core/linalg/eigen.d.ts.map +1 -0
  10. package/dist/core/linalg/lm.d.ts +78 -0
  11. package/dist/core/linalg/lm.d.ts.map +1 -0
  12. package/dist/core/linalg/lu.d.ts +154 -0
  13. package/dist/core/linalg/lu.d.ts.map +1 -0
  14. package/dist/core/linalg/matrix.d.ts +131 -0
  15. package/dist/core/linalg/matrix.d.ts.map +1 -0
  16. package/dist/core/linalg/modelMatrix.d.ts +69 -0
  17. package/dist/core/linalg/modelMatrix.d.ts.map +1 -0
  18. package/dist/core/linalg/namedVector.d.ts +37 -0
  19. package/dist/core/linalg/namedVector.d.ts.map +1 -0
  20. package/dist/core/linalg/ops.d.ts +120 -0
  21. package/dist/core/linalg/ops.d.ts.map +1 -0
  22. package/dist/core/linalg/prcomp.d.ts +66 -0
  23. package/dist/core/linalg/prcomp.d.ts.map +1 -0
  24. package/dist/core/linalg/qr.d.ts +134 -0
  25. package/dist/core/linalg/qr.d.ts.map +1 -0
  26. package/dist/core/linalg/vector.d.ts +68 -0
  27. package/dist/core/linalg/vector.d.ts.map +1 -0
  28. package/dist/core/moderation.d.ts +6 -3
  29. package/dist/core/moderation.d.ts.map +1 -1
  30. package/dist/core/ols.d.ts +4 -7
  31. package/dist/core/ols.d.ts.map +1 -1
  32. package/dist/data/moderationData.d.ts +2 -2
  33. package/dist/data/pcaDegenerate.d.ts +1 -1
  34. package/dist/index.js +1455 -863
  35. package/dist/index.js.map +16 -10
  36. package/dist/linalg.d.ts +36 -0
  37. package/dist/linalg.d.ts.map +1 -0
  38. package/dist/linalg.js +1860 -0
  39. package/dist/linalg.js.map +24 -0
  40. package/dist/plot/moderation3d.d.ts +1 -1
  41. package/dist/plot/scatter3d.d.ts +1 -1
  42. package/package.json +7 -2
@@ -1 +1 @@
1
- {"version":3,"file":"arith.d.ts","sourceRoot":"","sources":["../../src/core/arith.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,mDAAmD;AACnD,wBAAgB,GAAG,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAErD;AAED,iEAAiE;AACjE,wBAAgB,IAAI,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAEtD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAQlE;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,yDAAyD;AACzD,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAI9D;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAC7B,EAAE,EAAE,SAAS,CAAC,EAAE,EAChB,EAAE,EAAE,SAAS,CAAC,EAAE,EAChB,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,GACzB,CAAC,EAAE,CAIL;AAED;;;;;;GAMG;AACH,wBAAgB,EAAE,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAQpD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAGvE;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAKxE;AA0BD;;;;;;;;;;;;GAYG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAErE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,SAAS,CACvB,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,KAAK,EAAE,SAAS,MAAM,EAAE,GACvB,MAAM,EAAE,CAaV;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAExD"}
1
+ {"version":3,"file":"arith.d.ts","sourceRoot":"","sources":["../../src/core/arith.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,mDAAmD;AACnD,wBAAgB,GAAG,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAErD;AAED,iEAAiE;AACjE,wBAAgB,IAAI,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAEtD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAQlE;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,yDAAyD;AACzD,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAI9D;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAC7B,EAAE,EAAE,SAAS,CAAC,EAAE,EAChB,EAAE,EAAE,SAAS,CAAC,EAAE,EAChB,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,GACzB,CAAC,EAAE,CAIL;AAED;;;;;;GAMG;AACH,wBAAgB,EAAE,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAQpD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAGvE;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAUxE;AA0BD;;;;;;;;;;;;GAYG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAErE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,SAAS,CACvB,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,KAAK,EAAE,SAAS,MAAM,EAAE,GACvB,MAAM,EAAE,CAaV;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAExD"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * R's `var()`, `cov()` and `cor()`.
3
+ *
4
+ * R computes a covariance in two passes: the mean of each column, refined
5
+ * once by adding the mean of the residuals (its `cov.c` does this to shave
6
+ * the rounding off a long sum), then the sum of products of deviations over
7
+ * `n − 1`. A correlation is the covariance matrix scaled by the square roots
8
+ * of its diagonal, clamped to `[-1, 1]`, with an exact 1 on the diagonal.
9
+ * The port follows those steps. R accumulates in `long double` where the
10
+ * platform has one; the conformance fixtures come from arm64, where it does
11
+ * not, and the values are verified at a relative tolerance (plan Q1).
12
+ *
13
+ * A missing value gives NaN, as R's default `use = "everything"` gives NA.
14
+ * A constant column gives NaN for its correlations, where R warns "the
15
+ * standard deviation is zero" and gives NA.
16
+ */
17
+ import { type Matrix } from "./matrix";
18
+ import type { Vector } from "./vector";
19
+ /**
20
+ * R's `var(x)` of a vector: the sample variance with the `n − 1` divisor.
21
+ *
22
+ * @returns The variance, or NaN below two values or with a missing value.
23
+ */
24
+ export declare function variance(a: Vector): number;
25
+ /**
26
+ * R's `cov()`: the covariance of two vectors, or the covariance matrix of
27
+ * the columns of a matrix.
28
+ *
29
+ * @param x A vector, or a matrix whose columns are the variables.
30
+ * @param y The second vector when `x` is a vector.
31
+ * @returns The covariance, or the symmetric covariance matrix with the
32
+ * column names of `x` on both sides.
33
+ * @throws RangeError If two vectors differ in length.
34
+ */
35
+ export declare function cov(x: Vector, y: Vector): number;
36
+ export declare function cov(x: Matrix): Matrix;
37
+ /**
38
+ * R's `cor()`: the Pearson correlation of two vectors, or the correlation
39
+ * matrix of the columns of a matrix.
40
+ *
41
+ * @param x A vector, or a matrix whose columns are the variables.
42
+ * @param y The second vector when `x` is a vector.
43
+ * @returns The correlation, clamped to `[-1, 1]`, or the symmetric
44
+ * correlation matrix with an exact 1 on its diagonal. NaN where a
45
+ * variable has no spread.
46
+ * @throws RangeError If two vectors differ in length.
47
+ */
48
+ export declare function cor(x: Vector, y: Vector): number;
49
+ export declare function cor(x: Matrix): Matrix;
50
+ //# sourceMappingURL=cov.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cov.d.ts","sourceRoot":"","sources":["../../../src/core/linalg/cov.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,EAAuB,KAAK,MAAM,EAAE,MAAM,UAAU,CAAC;AAC5D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAwCvC;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAG1C;AAED;;;;;;;;;GASG;AACH,wBAAgB,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;AAClD,wBAAgB,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;AAYvC;;;;;;;;;;GAUG;AACH,wBAAgB,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;AAClD,wBAAgB,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * The eigendecomposition of a symmetric matrix, R's
3
+ * `eigen(x, symmetric = TRUE)`.
4
+ *
5
+ * R goes through LAPACK's `dsyevr`. The port uses cyclic Jacobi rotations,
6
+ * which for the matrices a teaching library sees — a covariance of a handful
7
+ * of variables — converge to machine precision in a few sweeps and are
8
+ * short enough to read. Eigenvalues come back descending, as R's do, and
9
+ * the eigenvectors are orthonormal columns. Verified against R in
10
+ * `eigen.test.ts`: the eigenvalues to a relative `1e-12`, the vectors up to
11
+ * sign (plan Q1).
12
+ *
13
+ * **Signs are this port's own.** LAPACK leaves the sign of each eigenvector
14
+ * to the arithmetic; the port makes the entry of largest magnitude positive
15
+ * (a tie goes to the first), which is the rule `pca.ts` already uses, so
16
+ * that the same input gives the same picture every time.
17
+ *
18
+ * Two departures from R, both stated: a matrix that is not symmetric is
19
+ * refused, where R silently reads its lower triangle; and the eigenvector
20
+ * matrix carries the row names of the input as its row names, where R's
21
+ * carries none — a loading without its variable is unreadable. The refusals
22
+ * R does make are followed in its order and its words: a non-square matrix,
23
+ * then a 0 x 0 one, then a missing or infinite entry (fixture 5e).
24
+ *
25
+ * Index loops throughout: a rotation addresses entries by position.
26
+ */
27
+ import { type Matrix } from "./matrix";
28
+ import type { Vector } from "./vector";
29
+ /** R's `eigen()` result for a symmetric matrix. */
30
+ export interface SymmetricEigen {
31
+ /** The eigenvalues, largest first. */
32
+ readonly values: Vector;
33
+ /**
34
+ * The eigenvectors as columns, in the order of the values, each of unit
35
+ * length with its largest entry positive. Row names are the input's.
36
+ */
37
+ readonly vectors: Matrix;
38
+ }
39
+ /**
40
+ * R's `isSymmetric()`: whether a square matrix equals its transpose to a
41
+ * relative tolerance, R's `all.equal()` default of `100 * eps`.
42
+ */
43
+ export declare function isSymmetric(m: Matrix, tolerance?: number): boolean;
44
+ /**
45
+ * Decompose a symmetric matrix, as R's `eigen(x, symmetric = TRUE)` does.
46
+ *
47
+ * @param m The symmetric matrix. The function does not modify it.
48
+ * @returns The eigenvalues, descending, and the eigenvectors as columns.
49
+ * @throws RangeError If the matrix is not square, is 0 x 0, holds a missing
50
+ * or infinite entry, or is not symmetric.
51
+ */
52
+ export declare function eigenSymmetric(m: Matrix): SymmetricEigen;
53
+ //# sourceMappingURL=eigen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eigen.d.ts","sourceRoot":"","sources":["../../../src/core/linalg/eigen.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAQ,KAAK,MAAM,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAEvC,mDAAmD;AACnD,MAAM,WAAW,cAAc;IAC7B,sCAAsC;IACtC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,SAAuB,GAAG,OAAO,CAehF;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,GAAG,cAAc,CA0CxD"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * R's `lm()` over a data frame, with what `summary.lm()` reads off the fit.
3
+ *
4
+ * `lm()` is `model.matrix()` followed by `lm.fit()`, and `lm.fit()` is
5
+ * `dqrls`: the `qr()` of `qr.ts` — LINPACK's `dqrdc2` with its limited
6
+ * column pivoting — followed by `dqrsl`'s coefficients and residuals, with
7
+ * the fitted values as `y` minus the residuals. The port runs that same
8
+ * arithmetic, so the coefficients, fitted values and residuals pin bit for
9
+ * bit against R. The summary statistics — R², adjusted R², σ, the standard
10
+ * errors and the t and p values — follow `summary.lm()`'s formulas but not
11
+ * its rounding step for step (`chol2inv` and `pt`), and are verified at a
12
+ * stated tolerance. See `lm.test.ts`.
13
+ *
14
+ * Coefficients come back as a `NamedVector` in R's order, `null` where R
15
+ * reports `NA` for an aliased column. Fitted values and residuals are padded
16
+ * with NaN to the input length where a row was dropped for a missing value,
17
+ * R's `na.exclude`, which is the convention every fit in this package uses.
18
+ */
19
+ import type { DataFrame } from "../frame";
20
+ import { type ModelSpec } from "./modelMatrix";
21
+ import { type NamedVector } from "./namedVector";
22
+ import type { Vector } from "./vector";
23
+ /** The model, with the outcome required, and the rank tolerance. */
24
+ export interface LmOptions extends ModelSpec {
25
+ /** The column to fit. */
26
+ readonly outcome: string;
27
+ /** How far a column's norm may collapse before it is aliased. R's `lm.fit()` default. */
28
+ readonly tolerance?: number;
29
+ }
30
+ /** R's `summary(fit)$fstatistic`. */
31
+ export interface FStatistic {
32
+ readonly value: number;
33
+ readonly numdf: number;
34
+ readonly dendf: number;
35
+ }
36
+ /** A fitted linear model and its summary. */
37
+ export interface LmFit {
38
+ /** `coef(fit)`: one entry per design column, null where R reports `NA`. */
39
+ readonly coefficients: NamedVector;
40
+ /** `coef(summary(fit))[, "Std. Error"]`, null for an aliased term. */
41
+ readonly standardErrors: NamedVector;
42
+ /** `coef(summary(fit))[, "t value"]`, null for an aliased term. */
43
+ readonly tValues: NamedVector;
44
+ /** `coef(summary(fit))[, "Pr(>|t|)"]`, null for an aliased term. */
45
+ readonly pValues: NamedVector;
46
+ /** The fitted outcome of each data row, in input order; NaN for a row dropped. */
47
+ readonly fitted: Vector;
48
+ /** The outcome minus the fit, in input order; NaN for a row dropped. */
49
+ readonly residuals: Vector;
50
+ /** The number of columns the fit could identify. */
51
+ readonly rank: number;
52
+ /** `fit$df.residual`: rows fitted minus rank. */
53
+ readonly dfResidual: number;
54
+ /** `summary(fit)$r.squared`. */
55
+ readonly rSquared: number;
56
+ /** `summary(fit)$adj.r.squared`. */
57
+ readonly adjRSquared: number;
58
+ /** `summary(fit)$sigma`: the residual standard error. */
59
+ readonly sigma: number;
60
+ /** `summary(fit)$fstatistic`, or null when the model has no term beyond the intercept. */
61
+ readonly fStatistic: FStatistic | null;
62
+ /** The data rows the fit used, in input order. */
63
+ readonly rows: readonly number[];
64
+ /** R's `term.labels`. */
65
+ readonly termLabels: readonly string[];
66
+ }
67
+ /**
68
+ * Fit a linear model, as R's `lm()` does.
69
+ *
70
+ * @param data The frame holding every column the model names.
71
+ * @param options The outcome, the terms, the intercept flag, and the rank
72
+ * tolerance.
73
+ * @returns The fit and its summary.
74
+ * @throws RangeError If a named column is absent or not numeric, if the
75
+ * frame is ragged, or if no row is complete — R's "0 (non-NA) cases".
76
+ */
77
+ export declare function lm(data: DataFrame, options: LmOptions): LmFit;
78
+ //# sourceMappingURL=lm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lm.d.ts","sourceRoot":"","sources":["../../../src/core/linalg/lm.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE1C,OAAO,EAAe,KAAK,SAAS,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAE9D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAEvC,oEAAoE;AACpE,MAAM,WAAW,SAAU,SAAQ,SAAS;IAC1C,yBAAyB;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,yFAAyF;IACzF,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,qCAAqC;AACrC,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,6CAA6C;AAC7C,MAAM,WAAW,KAAK;IACpB,2EAA2E;IAC3E,QAAQ,CAAC,YAAY,EAAE,WAAW,CAAC;IACnC,sEAAsE;IACtE,QAAQ,CAAC,cAAc,EAAE,WAAW,CAAC;IACrC,mEAAmE;IACnE,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,oEAAoE;IACpE,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,kFAAkF;IAClF,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,wEAAwE;IACxE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,oDAAoD;IACpD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,iDAAiD;IACjD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,gCAAgC;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,oCAAoC;IACpC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,yDAAyD;IACzD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,0FAA0F;IAC1F,QAAQ,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IACvC,kDAAkD;IAClD,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,yBAAyB;IACzB,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC;AAED;;;;;;;;;GASG;AACH,wBAAgB,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,GAAG,KAAK,CAyD7D"}
@@ -0,0 +1,154 @@
1
+ /**
2
+ * The LU factorization with partial pivoting, and what R reads off it:
3
+ * `solve()`, `det()`, `determinant()`, `rcond()` and `norm()`.
4
+ *
5
+ * R's `solve(a, b)` is LAPACK `dgesv` — `dgetrf` to factor, `dgetrs` to
6
+ * substitute — followed by `dgecon`'s condition estimate and an error when
7
+ * that estimate falls below `tol`. `det()` factors the same way and then
8
+ * exponentiates a sum of logarithms of the diagonal, which is why the
9
+ * determinant of an integer matrix comes back as `30.000000000000004`. This
10
+ * module follows those routines step for step, with the arithmetic of the
11
+ * reference BLAS build the fixtures come from (each product rounded once
12
+ * into its sum — see `fusedMultiplyAdd`), so that the factorization, the
13
+ * solves and the determinant pin bit for bit. Verified in `lu.test.ts`.
14
+ * The 2 × 2 special case in `../matrix.ts` is the same algorithm and the
15
+ * two agree exactly on every fixture of the interactive demo.
16
+ *
17
+ * Three departures from R, each stated where it applies: `rcond` is the
18
+ * exact one-norm ratio rather than `dgecon`'s estimate; a vector right-hand
19
+ * side comes back as a plain array rather than R's named vector; and a
20
+ * negative or NaN tolerance is refused where R would skip the check.
21
+ *
22
+ * Index loops throughout: a factorization addresses single entries by
23
+ * position, and this one follows `dgetf2` and `dtrsm` as written.
24
+ */
25
+ import { type Matrix } from "./matrix";
26
+ import type { Vector } from "./vector";
27
+ /** R's `solve()` result on a square matrix, factored. */
28
+ export interface LuDecomposition {
29
+ /**
30
+ * The compact factorization, LAPACK's: `U` on and above the diagonal, the
31
+ * multipliers of the unit lower triangle `L` below it, rows already
32
+ * interchanged.
33
+ */
34
+ readonly lu: Matrix;
35
+ /**
36
+ * The row interchanges, LAPACK's `ipiv` **zero-based**: at step `i` row
37
+ * `i` was swapped with row `pivots[i]`. Apply them in order to recover
38
+ * `P` such that `P A = L U`. Plural, and not `pivot` as in
39
+ * `QrDecomposition`, because this is a list of interchanges rather than
40
+ * a column order.
41
+ */
42
+ readonly pivots: readonly number[];
43
+ /**
44
+ * The zero-based index of the first exactly zero pivot — LAPACK's `info`,
45
+ * less one — or null if the factorization completed. R reports it as
46
+ * `U[i,i] = 0`, one-based.
47
+ */
48
+ readonly zeroPivot: number | null;
49
+ }
50
+ /**
51
+ * Factor a square matrix, as LAPACK's `dgetrf` does.
52
+ *
53
+ * @param a The matrix. The function does not modify it.
54
+ * @returns The compact factorization, the row interchanges, and the first
55
+ * zero pivot if any. A zero pivot does not stop the factorization, as it
56
+ * does not in LAPACK.
57
+ * @throws RangeError If the matrix is not square.
58
+ * @throws TypeError If `a` is not a matrix.
59
+ */
60
+ export declare function lu(a: Matrix): LuDecomposition;
61
+ export interface SolveOptions {
62
+ /**
63
+ * The reciprocal condition number below which the system is refused as
64
+ * computationally singular. R's default is `.Machine$double.eps`; zero
65
+ * skips the check, as it does in R. R also skips it for a negative or
66
+ * NA `tol`; the port refuses those with a `RangeError` — a deliberate
67
+ * narrowing, as `matrix()` narrows R's recycling.
68
+ */
69
+ readonly tolerance?: number;
70
+ }
71
+ /** The singularity tolerance of R's `solve()`: one machine epsilon. */
72
+ export declare const DEFAULT_SOLVE_TOLERANCE: number;
73
+ /**
74
+ * R's `solve(a)`, `solve(a, b)` and `solve(a, B)`: the inverse, the solution
75
+ * of `a x = b` for a vector, or the solution of `a X = B` for a matrix.
76
+ *
77
+ * @param a The square coefficient matrix.
78
+ * @param b The right-hand side, or the options when only the inverse is
79
+ * wanted. A vector gives a plain array (R names it by the column names of
80
+ * `a`; the port carries no names on a bare array — plan Q11). A matrix
81
+ * gives a matrix whose row names are the column names of `a` and whose
82
+ * column names are those of `b`; the inverse has the column names of `a`
83
+ * as rows and the row names of `a` as columns, as R's does.
84
+ * @param options The singularity tolerance.
85
+ * @returns The solution.
86
+ * @throws RangeError If `a` is not square or has no rows, `b` does not
87
+ * conform or has no columns, the factorization meets an exactly zero
88
+ * pivot, or the reciprocal condition number is below the tolerance —
89
+ * each in R's own words. As in R, a non-finite entry in `a` leaves the
90
+ * condition unchecked: R's `dgecon` reports a bad norm and `solve()`
91
+ * goes on.
92
+ * @throws TypeError If `a` or `b` is neither a matrix nor an array.
93
+ */
94
+ export declare function solve(a: Matrix, options?: SolveOptions): Matrix;
95
+ export declare function solve(a: Matrix, b: Vector, options?: SolveOptions): number[];
96
+ export declare function solve(a: Matrix, b: Matrix, options?: SolveOptions): Matrix;
97
+ /**
98
+ * R's `det()`: the determinant, through the factorization and a sum of
99
+ * logarithms, as R computes it. A 0 × 0 matrix has determinant 1, as in R.
100
+ *
101
+ * @throws RangeError If the matrix is not square.
102
+ * @throws TypeError If `a` is not a matrix.
103
+ */
104
+ export declare function det(a: Matrix): number;
105
+ /**
106
+ * R's `determinant()`: the logarithm of the absolute determinant and its
107
+ * sign. An exactly singular matrix reports `-Infinity` and sign 1, so that
108
+ * `det()` is a positive zero, as R's is.
109
+ *
110
+ * @throws RangeError If the matrix is not square.
111
+ * @throws TypeError If `a` is not a matrix.
112
+ */
113
+ export declare function determinant(a: Matrix): {
114
+ readonly modulus: number;
115
+ readonly sign: 1 | -1;
116
+ };
117
+ /**
118
+ * The reciprocal condition number in the one-norm, R's `rcond(x)`:
119
+ * `1 / (norm(x) * norm(solve(x)))` for a square matrix, 0 when it is
120
+ * exactly singular, and Infinity for a 0 × 0 matrix. A matrix that is not
121
+ * square goes through the triangular factor of its QR, as R's does
122
+ * (`rcond(qr.R(qr(x)))`, transposed first when wide).
123
+ *
124
+ * R's `rcond()` and `solve()` read an estimate of this number from LAPACK's
125
+ * `dgecon` rather than computing it, and the port computes it exactly. On
126
+ * the fixtures the two agree to the last bit for most matrices (3a, 3c, 3d,
127
+ * 3e, 3i) and differ by one unit in the last place on two (3b, 3h);
128
+ * `solve()`'s error message matches R's to the six digits it prints on
129
+ * every singular case pinned. The estimate bounds the norm of the inverse
130
+ * from below, so R's number is never smaller than the port's.
131
+ *
132
+ * @throws RangeError If an entry is not finite — R's "error code -5 from
133
+ * Lapack routine 'dgecon()'", because `dgecon` refuses a norm it cannot
134
+ * read.
135
+ * @throws TypeError If `a` is not a matrix.
136
+ */
137
+ export declare function rcond(a: Matrix): number;
138
+ /**
139
+ * R's `norm()` types. `"O"` is R's default; the letters are accepted in
140
+ * either case, as R's `lsame` accepts them. R's `"2"`, the spectral norm,
141
+ * needs a singular value decomposition, which this plan leaves out.
142
+ */
143
+ export type MatrixNormType = "O" | "1" | "I" | "F" | "E" | "M" | "o" | "i" | "f" | "e" | "m";
144
+ /**
145
+ * R's `norm(x, type)`: the one-norm (`"O"` or `"1"`, the largest absolute
146
+ * column sum), the infinity norm (`"I"`, the largest absolute row sum), the
147
+ * Frobenius norm (`"F"` or `"E"`), or the largest absolute entry (`"M"`).
148
+ * Named `matrixNorm` because `norm` in this entry is the vector length.
149
+ *
150
+ * @throws RangeError If the type is none of those, in R's words.
151
+ * @throws TypeError If `a` is not a matrix.
152
+ */
153
+ export declare function matrixNorm(a: Matrix, type?: MatrixNormType): number;
154
+ //# sourceMappingURL=lu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lu.d.ts","sourceRoot":"","sources":["../../../src/core/linalg/lu.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAGH,OAAO,EAAuB,KAAK,MAAM,EAAE,MAAM,UAAU,CAAC;AAG5D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAUvC,yDAAyD;AACzD,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB;;;;;;OAMG;IACH,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC;;;;OAIG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAED;;;;;;;;;GASG;AACH,wBAAgB,EAAE,CAAC,CAAC,EAAE,MAAM,GAAG,eAAe,CAoD7C;AAWD,MAAM,WAAW,YAAY;IAC3B;;;;;;OAMG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,uEAAuE;AACvE,eAAO,MAAM,uBAAuB,QAAiB,CAAC;AAEtD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,MAAM,CAAC;AACjE,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,MAAM,EAAE,CAAC;AAC9E,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,MAAM,CAAC;AA2I5E;;;;;;GAMG;AACH,wBAAgB,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAGrC;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAA;CAAE,CAoB1F;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAoBvC;AAED;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAE7F;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,GAAE,cAAoB,GAAG,MAAM,CAmCxE"}
@@ -0,0 +1,131 @@
1
+ /**
2
+ * A matrix, held the way R holds one.
3
+ *
4
+ * R stores a matrix as one vector in column-major order with a `dim`
5
+ * attribute and optional `dimnames`. This module keeps that shape as a plain
6
+ * object: a `Float64Array` of the entries column by column, the two extents,
7
+ * and the names. Plain data, not a class — a matrix serializes, clones and
8
+ * crosses a worker boundary as it is, and every operation on it is a function
9
+ * in R's vocabulary (`t`, `matmul`, `crossprod`, `cbind`, …) in `ops.ts`.
10
+ *
11
+ * Column-major is load-bearing. It is what R, LAPACK and every conformance
12
+ * fixture assume, so `matrix(c(x1, y1, x2, y2), nrow = 2)` translates with
13
+ * no reordering, and a factorization ported from LINPACK reads the same
14
+ * memory in the same order.
15
+ *
16
+ * Indices are zero-based throughout, as the language's are. R's `A[1, 1]` is
17
+ * `at(a, 0, 0)` here.
18
+ *
19
+ * R recycles the data to fill the matrix: a scalar silently, a sub-multiple
20
+ * of the extent silently too (`matrix(1:3, 3, 2)` repeats the column), and
21
+ * any other length with a warning. This module recycles a scalar only —
22
+ * `matrix([0], {nrow: 3, ncol: 3})` is R's `matrix(0, 3, 3)` — and refuses
23
+ * every other mismatch, warned or not. A silently recycled column lets a
24
+ * typo fit the wrong model; a caller who wants the repeat writes
25
+ * `cbind(v, v)`.
26
+ */
27
+ import { type DataFrame } from "../frame";
28
+ import type { Vector } from "./vector";
29
+ /** Row names and column names, either of which R may leave `NULL`. */
30
+ export type Dimnames = readonly [
31
+ readonly string[] | null,
32
+ readonly string[] | null
33
+ ];
34
+ /** A matrix in R's layout: column-major data with its two extents. */
35
+ export interface Matrix {
36
+ readonly nrow: number;
37
+ readonly ncol: number;
38
+ /**
39
+ * The entries, column by column: entry `(i, j)` is `data[j * nrow + i]`.
40
+ * Treat it as read-only. A `Float64Array` has no read-only type, so the
41
+ * rule is stated rather than enforced.
42
+ */
43
+ readonly data: Float64Array;
44
+ /** R's `dimnames`, or null when the matrix has none. */
45
+ readonly dimnames: Dimnames | null;
46
+ }
47
+ /** The named arguments of R's `matrix()`. */
48
+ export interface MatrixOptions {
49
+ /** The number of rows. At least one of `nrow` and `ncol` is required. */
50
+ readonly nrow?: number;
51
+ /** The number of columns. */
52
+ readonly ncol?: number;
53
+ /** Fill row by row instead of column by column. False by default. */
54
+ readonly byrow?: boolean;
55
+ /** Row names and column names. */
56
+ readonly dimnames?: Dimnames;
57
+ }
58
+ /**
59
+ * Build a matrix from its entries, as R's `matrix()` does.
60
+ *
61
+ * @param values The entries, in column-major order unless `byrow` is set,
62
+ * or a single value to fill the whole matrix with. The function copies
63
+ * them; a hole in a sparse array reads as NaN.
64
+ * @param options `nrow` or `ncol` (or both, in which case they must agree
65
+ * with the length), `byrow`, and `dimnames`. An extent may be zero, as
66
+ * R's may.
67
+ * @returns The matrix.
68
+ * @throws RangeError If neither extent is given, an extent is not a
69
+ * non-negative integer, the length is not a multiple of the extent given
70
+ * (R warns and recycles; the port refuses), both extents are given and do
71
+ * not multiply to the length (R recycles a sub-multiple silently; the port
72
+ * refuses), or a dimnames entry has the wrong length.
73
+ */
74
+ export declare function matrix(values: Vector, options: MatrixOptions): Matrix;
75
+ /**
76
+ * Assemble a matrix from data already in column-major order, checking the
77
+ * dimnames against the extents and copying the name arrays so that no two
78
+ * matrices share one. The data is taken as is, not copied.
79
+ *
80
+ * @internal Not part of the entry point. The other linalg modules build
81
+ * their results through it.
82
+ */
83
+ export declare function make(nrow: number, ncol: number, data: Float64Array, dimnames: Dimnames | null): Matrix;
84
+ /**
85
+ * Build a matrix from its rows.
86
+ *
87
+ * @param rows One array per row, each one value per column. Copied.
88
+ * @returns The matrix.
89
+ * @throws RangeError If there are no rows, a row is empty, or the rows have
90
+ * different lengths.
91
+ */
92
+ export declare function fromRows(rows: readonly Vector[]): Matrix;
93
+ /**
94
+ * Build a matrix from its columns. This is R's `cbind()` over vectors and
95
+ * the natural constructor from a column-keyed data frame.
96
+ *
97
+ * @param columns One array per column, each one value per row. Copied.
98
+ * @returns The matrix.
99
+ * @throws RangeError If there are no columns, a column is empty, or the
100
+ * columns have different lengths.
101
+ */
102
+ export declare function fromColumns(columns: readonly Vector[]): Matrix;
103
+ /**
104
+ * Read one entry. R's `m[i + 1, j + 1]`.
105
+ *
106
+ * @throws RangeError If the index is outside the matrix.
107
+ */
108
+ export declare function at(m: Matrix, i: number, j: number): number;
109
+ /** Read one row as a plain array. R's `m[i + 1, ]`. */
110
+ export declare function row(m: Matrix, i: number): number[];
111
+ /** Read one column as a plain array. R's `m[, j + 1]`. */
112
+ export declare function column(m: Matrix, j: number): number[];
113
+ /** The matrix as an array of rows. */
114
+ export declare function toRows(m: Matrix): number[][];
115
+ /** The matrix as an array of columns. */
116
+ export declare function toColumns(m: Matrix): number[][];
117
+ /**
118
+ * R's `as.matrix()` of a data frame: the numeric columns side by side, with
119
+ * the column names carried. The natural way into `cov`, `prcomp` and
120
+ * `matmul` from a column-keyed frame.
121
+ *
122
+ * @param data The frame.
123
+ * @param columns The columns to take, in order. By default every numeric
124
+ * column, in frame order — R's `Filter(is.numeric, data)`.
125
+ * @returns The matrix, `frameRows(data)` by `columns.length`, with the
126
+ * column names as its column names.
127
+ * @throws RangeError If a named column is absent or not numeric (through
128
+ * `requireNumericColumn`), or if the frame is ragged.
129
+ */
130
+ export declare function fromFrame(data: DataFrame, columns?: readonly string[]): Matrix;
131
+ //# sourceMappingURL=matrix.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matrix.d.ts","sourceRoot":"","sources":["../../../src/core/linalg/matrix.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAIL,KAAK,SAAS,EACf,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAEvC,sEAAsE;AACtE,MAAM,MAAM,QAAQ,GAAG,SAAS;IAC9B,SAAS,MAAM,EAAE,GAAG,IAAI;IACxB,SAAS,MAAM,EAAE,GAAG,IAAI;CACzB,CAAC;AAEF,sEAAsE;AACtE,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,wDAAwD;IACxD,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;CACpC;AAED,6CAA6C;AAC7C,MAAM,WAAW,aAAa;IAC5B,yEAAyE;IACzE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,6BAA6B;IAC7B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,qEAAqE;IACrE,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,kCAAkC;IAClC,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC;CAC9B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,MAAM,CACpB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,aAAa,GACrB,MAAM,CAqBR;AAwDD;;;;;;;GAOG;AACH,wBAAgB,IAAI,CAClB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,YAAY,EAClB,QAAQ,EAAE,QAAQ,GAAG,IAAI,GACxB,MAAM,CAwBR;AAED;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAsBxD;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,SAAS,MAAM,EAAE,GACzB,MAAM,CAqBR;AAED;;;;GAIG;AACH,wBAAgB,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAQ1D;AAED,uDAAuD;AACvD,wBAAgB,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAKlD;AAED,0DAA0D;AAC1D,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAKrD;AAED,sCAAsC;AACtC,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,CAE5C;AAED,yCAAyC;AACzC,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,CAE/C;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAQ9E"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * R's `model.matrix()`: a data frame and a list of terms → the design
3
+ * matrix, with the column names `lm()` gives its coefficients.
4
+ *
5
+ * R builds this from a formula. The port has no formulas (CLAUDE.md: the
6
+ * canonical form is explicit column names in an options object), so a
7
+ * model is a list of terms — a column name for a main effect, an array of
8
+ * column names for an interaction — and the intercept is a flag. R's
9
+ * `y ~ x * z + w` is `{ outcome: "y", terms: ["x", "z", "w", ["x", "z"]] }`.
10
+ *
11
+ * The columns come out in R's order, whatever order the terms were written
12
+ * in: the intercept, then the terms by degree — every main effect before
13
+ * every two-way interaction before every three-way — and within a degree in
14
+ * the order given. A term written twice enters once. The `assign` vector is
15
+ * R's: the index of the term each column came from, 0 for the intercept.
16
+ *
17
+ * Rows with a missing (non-finite) value in the outcome or in any column a
18
+ * term names are dropped, R's `model.frame()` under `na.omit`; the indices
19
+ * of the rows kept are returned, so a fit can pad its results back to the
20
+ * input order (the `na.exclude` convention every fit in this package uses).
21
+ * Only numeric columns can enter; R's factors and contrasts are out of
22
+ * scope.
23
+ */
24
+ import { type DataFrame } from "../frame";
25
+ import { type Matrix } from "./matrix";
26
+ /**
27
+ * One term of a model: a column name for a main effect, or the column names
28
+ * of an interaction, R's `a:b`.
29
+ */
30
+ export type Term = string | readonly string[];
31
+ /** Which columns make the model. */
32
+ export interface ModelSpec {
33
+ /**
34
+ * The outcome column. It enters no design column, but a row missing it is
35
+ * dropped, as `model.frame()` drops it. Optional here; `lm()` requires it.
36
+ */
37
+ readonly outcome?: string;
38
+ /** The terms, in any order. R's order is restored. */
39
+ readonly terms: readonly Term[];
40
+ /** Whether to lead with a column of ones. True by default, R's `+ 1`. */
41
+ readonly intercept?: boolean;
42
+ }
43
+ /** A design matrix and where its rows came from. */
44
+ export interface ModelMatrix {
45
+ /**
46
+ * The design, one row per complete data row, with the coefficient names
47
+ * as column names: `(Intercept)`, the main effects, the interactions as
48
+ * `a:b`.
49
+ */
50
+ readonly matrix: Matrix;
51
+ /** The data rows the design holds, in input order. */
52
+ readonly rows: readonly number[];
53
+ /** R's `assign`: the term each column came from, 0 for the intercept. */
54
+ readonly assign: readonly number[];
55
+ /** R's `term.labels`: the terms in the order the columns follow. */
56
+ readonly termLabels: readonly string[];
57
+ }
58
+ /**
59
+ * Build the design matrix of a model, as R's `model.matrix()` does.
60
+ *
61
+ * @param data The frame holding every column the model names.
62
+ * @param spec The outcome, the terms, and the intercept flag.
63
+ * @returns The design, the rows it kept, and R's `assign` and term labels.
64
+ * @throws RangeError If a named column is absent or not numeric (through
65
+ * `requireNumericColumn`, naming the option it arrived through), if the
66
+ * frame is ragged, or if an interaction term names no column.
67
+ */
68
+ export declare function modelMatrix(data: DataFrame, spec: ModelSpec): ModelMatrix;
69
+ //# sourceMappingURL=modelMatrix.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modelMatrix.d.ts","sourceRoot":"","sources":["../../../src/core/linalg/modelMatrix.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAmC,KAAK,SAAS,EAAE,MAAM,UAAU,CAAC;AAC3E,OAAO,EAAQ,KAAK,MAAM,EAAE,MAAM,UAAU,CAAC;AAE7C;;;GAGG;AACH,MAAM,MAAM,IAAI,GAAG,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;AAE9C,oCAAoC;AACpC,MAAM,WAAW,SAAS;IACxB;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,sDAAsD;IACtD,QAAQ,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,CAAC;IAChC,yEAAyE;IACzE,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,oDAAoD;AACpD,MAAM,WAAW,WAAW;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,sDAAsD;IACtD,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,yEAAyE;IACzE,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,oEAAoE;IACpE,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC;AAED;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,WAAW,CA0DzE"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * R's named vector: values with a name each, in order.
3
+ *
4
+ * A coefficient vector is the case that matters here — `coef(fit)` in R
5
+ * prints `(Intercept)`, `x`, `z`, `x:z` above its values, and `summary()`
6
+ * lines the standard errors up under the same names. The port holds the
7
+ * names alongside the values rather than in an object keyed by name,
8
+ * because a JavaScript object moves an integer-like key to the front: a
9
+ * column called `"1"` would jump ahead of `(Intercept)`. The pair of arrays
10
+ * keeps R's order, and pairs with `dimnames` on a `Matrix`, so the column
11
+ * names of a model matrix become the names of a fit with no reshaping
12
+ * (plan Q11).
13
+ *
14
+ * `null` is R's `NA`: a coefficient the fit could not identify.
15
+ */
16
+ /** Values with a name each, in order. */
17
+ export interface NamedVector {
18
+ readonly names: readonly string[];
19
+ /** One value per name; null where R reports `NA`. */
20
+ readonly values: readonly (number | null)[];
21
+ }
22
+ /**
23
+ * Pair names with values.
24
+ *
25
+ * @param names One name per value. Copied.
26
+ * @param values One value per name; null for R's `NA`. Copied.
27
+ * @throws RangeError If the two lengths differ.
28
+ */
29
+ export declare function namedVector(names: readonly string[], values: readonly (number | null)[]): NamedVector;
30
+ /**
31
+ * Read one value by name. R's `v[["name"]]`.
32
+ *
33
+ * @returns The value, null where the entry is R's `NA`, or undefined when
34
+ * no entry carries the name. With a repeated name, the first.
35
+ */
36
+ export declare function lookup(v: NamedVector, name: string): number | null | undefined;
37
+ //# sourceMappingURL=namedVector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"namedVector.d.ts","sourceRoot":"","sources":["../../../src/core/linalg/namedVector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,yCAAyC;AACzC,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,qDAAqD;IACrD,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;CAC7C;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,MAAM,EAAE,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,GACjC,WAAW,CAOb;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAG9E"}