@nirs4all/methods 1.0.18 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -49,8 +49,8 @@ isolated band (achieved ~1e-16).
49
49
  import * as n4m from "@nirs4all/methods";
50
50
 
51
51
  await n4m.loadModule();
52
- console.log(n4m.version()); // "1.0.15+abi.2.5.0"
53
- console.log(n4m.abiVersion()); // [2, 5, 0]
52
+ console.log(n4m.version()); // "1.0.21+abi.2.13.0"
53
+ console.log(n4m.abiVersion()); // [2, 13, 0]
54
54
 
55
55
  const rows = 40, cols = 6;
56
56
  const X = new Float64Array(rows * cols); // row-major
@@ -63,11 +63,46 @@ const preds = n4m.predictPls(model, { data: X, rows, cols });
63
63
 
64
64
  const split = n4m.computeSplitIndices("KennardStone", { data: X, rows, cols }, null);
65
65
  // `computeSplit()` remains available when a compact train/test mask is enough.
66
+
67
+ // One native route also covers all nine splitter kinds, including fold kinds.
68
+ const ordered = n4m.splitNative("SPXYFold", { data: X, rows, cols },
69
+ { data: y, rows, cols: 1 },
70
+ { nSplits: 3, foldIndex: 0 });
71
+ // ordered.trainIndices / ordered.testIndices are zero-based Int32Array values.
72
+
73
+ // Training-only X-to-X augmentation; no Y mixing or fitted-state export.
74
+ const noisyTrainX = n4m.augmentNative("GaussianNoise",
75
+ { data: X, rows, cols }, [0.03], 42);
66
76
  ```
67
77
 
68
78
  `Context` / `Config` / `MethodResult` are also exported for the lower-level
69
79
  path. There is no idiomatic (sklearn-style) layer — that is intentional.
70
80
 
81
+ Fitted preprocessing uses the native pipeline handle. Its N4MP bytes contain
82
+ the fitted state and original ordered operator plan, not an N4MM model:
83
+
84
+ ```typescript
85
+ const ctx = n4m.Context.create();
86
+ const recipe = [
87
+ { kind: n4m.PipelineOperatorKind.SNV, params: [] },
88
+ { kind: n4m.PipelineOperatorKind.MSC, params: [] },
89
+ ];
90
+ const pipeline = n4m.NativePreprocessingPipeline.fit(ctx, recipe, trainX);
91
+ const payload = pipeline.toBytes();
92
+ const restored = n4m.NativePreprocessingPipeline.fromBytes(ctx, payload, recipe);
93
+ const transformed = restored.transform(heldOutX);
94
+ console.log(restored.nFeatures, restored.steps); // plan read from native handle
95
+ restored.destroy();
96
+ pipeline.destroy();
97
+ ctx.destroy();
98
+ ```
99
+
100
+ `trainX` and `heldOutX` are row-major `{ data: Float64Array, rows, cols }`.
101
+ OSC/EPO additionally require a training `Y` matrix at `fit`. The optional
102
+ `fromBytes` recipe argument checks the imported native plan, including
103
+ positional parameters; applications should also bind the blob to their
104
+ feature schema. Native N4MP v1 supports operator kinds 0–14 only (15 kinds).
105
+
71
106
  ## Build options
72
107
 
73
108
  The CMake `emscripten` preset sets:
@@ -0,0 +1,139 @@
1
+ import type { Matrix } from "./types.js";
2
+ /** Regressor role: Data[n, p] + Target[n, q] -> Prediction[n, q]. */
3
+ export interface Regressor {
4
+ predict(X: Matrix): Matrix;
5
+ }
6
+ /**
7
+ * Classifier role: Data[n, p] + Labels[n] -> class ids and scores. The core
8
+ * works on integer class ids; callers map their own label names.
9
+ */
10
+ export interface Classifier {
11
+ /** Class id of each row. */
12
+ predictLabels(X: Matrix): number[];
13
+ /** Method-defined class scores, one column per class in classes() order. */
14
+ decisionFunction(X: Matrix): Matrix;
15
+ /** Fitted class ids, ascending. */
16
+ classes(): number[];
17
+ }
18
+ /** Classifier that defines class probabilities. */
19
+ export interface ProbabilisticClassifier extends Classifier {
20
+ /** Class probabilities, one column per class in classes() order. */
21
+ predictProba(X: Matrix): Matrix;
22
+ }
23
+ /**
24
+ * Sample-filter role: Data[n, p] (+ Target) -> keep mask[n], train only.
25
+ * Filters on the target read `y` at fit and in getMask; the others ignore it.
26
+ */
27
+ export interface SampleFilter {
28
+ /** Keep mask of the rows of X (true keeps the row). */
29
+ getMask(X: Matrix, y?: Float64Array | ArrayLike<number>): boolean[];
30
+ }
31
+ /** Transformer role: Data[n, p] (+ Target) -> Data[n, k]. */
32
+ export interface Transformer {
33
+ transform(X: Matrix): Matrix;
34
+ }
35
+ /** Selector role: Data[n, p] (+ Target) -> the k selected input columns. */
36
+ export interface Selector {
37
+ /** Selected columns in ascending input order. */
38
+ transform(X: Matrix): Matrix;
39
+ /** Selected input columns (0-based) in native selection order. */
40
+ selectedIndices(): number[];
41
+ }
42
+ /** Native parameter types, as published by the manifest. */
43
+ export type ParamType = "int" | "double" | "bool" | "enum" | "int_array" | "double_array";
44
+ export type ParamValue = number | boolean | string | number[];
45
+ /** Optional fit inputs; the native core refuses those a method does not use. */
46
+ export interface FitInputs {
47
+ sampleWeight?: Float64Array | number[];
48
+ groups?: number[];
49
+ featureGroups?: number[];
50
+ blocks?: number[];
51
+ axis?: Float64Array | number[];
52
+ XTarget?: Matrix;
53
+ foldIds?: number[];
54
+ }
55
+ /** Parameters of one catalog method (estimator or procedure). */
56
+ export declare abstract class NativeMethod {
57
+ /** Catalog method id, for example "models.pls.pls_regression". */
58
+ abstract readonly methodId: string;
59
+ /** Parameter name -> native type. */
60
+ abstract readonly paramTypes: Readonly<Record<string, ParamType>>;
61
+ /** Explicit parameter values (unset ones take the native default). */
62
+ params: Record<string, ParamValue | undefined>;
63
+ /** Registers a generated class so fromN4me() and methodClass() find it. */
64
+ static register(methodId: string, cls: new () => NativeMethod): void;
65
+ }
66
+ /** The native manifest: every method's roles, node kinds, fit inputs and typed parameters. */
67
+ export declare function manifest(): {
68
+ abi: string;
69
+ methods: Array<Record<string, unknown>>;
70
+ };
71
+ /** The generated class of a catalog method id. */
72
+ export declare function methodClass(methodId: string): new () => NativeMethod;
73
+ /** Base of every generated estimator: parameters, fit and N4ME state. */
74
+ export declare abstract class NativeEstimator extends NativeMethod {
75
+ /** True when the fit target is class labels (classifiers). */
76
+ protected readonly labelTarget: boolean;
77
+ private ptr;
78
+ get fitted(): boolean;
79
+ /**
80
+ * Fit on row-major X and the target: responses for a regressor (a vector
81
+ * or a row-major matrix), integer class ids for a classifier. Returns this.
82
+ */
83
+ fit(X: Matrix, y?: Matrix | Float64Array | ArrayLike<number>, inputs?: FitInputs): this;
84
+ /** Portable fitted state (N4ME bytes), readable by every n4m binding. */
85
+ toN4me(): Uint8Array;
86
+ /** Rebuilds a fitted estimator of the class registered for its method. */
87
+ static fromN4me(payload: Uint8Array): NativeEstimator;
88
+ /** Releases the native estimator. */
89
+ dispose(): void;
90
+ protected predictMatrix(X: Matrix): Matrix;
91
+ protected transformMatrix(X: Matrix): Matrix;
92
+ protected decisionMatrix(X: Matrix): Matrix;
93
+ protected probaMatrix(X: Matrix): Matrix;
94
+ protected labelArray(X: Matrix): number[];
95
+ protected maskArray(X: Matrix, y?: Float64Array | ArrayLike<number>): boolean[];
96
+ protected classArray(): number[];
97
+ protected selectedIndexArray(): number[];
98
+ /** Reads a (handle, out, capacity, out_count) integer list. */
99
+ private indexArray;
100
+ private matrixOp;
101
+ private handle;
102
+ private static methodIdOf;
103
+ }
104
+ /** Splitter role: Data[n, p] (+ Target, groups) -> folds of 0-based row indices. */
105
+ export interface Splitter {
106
+ split(X: Matrix, y?: Float64Array | ArrayLike<number>, groups?: number[]): Fold[];
107
+ }
108
+ /** Augmenter role: Data[n, p] -> augmented Data[n, p], train only. */
109
+ export interface Augmenter {
110
+ augment(X: Matrix, axis?: Float64Array | number[]): Matrix;
111
+ }
112
+ /** Augmenter that mixes rows (mixup): the targets are mixed with the same draw, row for row. */
113
+ export interface TargetMixingAugmenter {
114
+ augment(X: Matrix, y: Matrix | Float64Array | ArrayLike<number>, axis?: Float64Array | number[]): {
115
+ X: Matrix;
116
+ Y: Matrix;
117
+ };
118
+ }
119
+ /** Generic procedure (diagnostics, utilities): inputs -> named outputs. */
120
+ export interface Procedure {
121
+ run(X: Matrix, y?: Matrix | Float64Array | ArrayLike<number>, inputs?: FitInputs): Record<string, ProcedureOutput>;
122
+ }
123
+ export interface Fold {
124
+ train: number[];
125
+ test: number[];
126
+ }
127
+ /** A named output: a matrix, an integer vector or a scalar. */
128
+ export type ProcedureOutput = Matrix | number[] | number;
129
+ /** Base of the generated procedures: one native run, no fitted state. */
130
+ export declare abstract class NativeProcedure extends NativeMethod {
131
+ protected runRaw<T>(X: Matrix, y: Matrix | Float64Array | ArrayLike<number> | undefined, inputs: FitInputs, read: (result: number) => T): T;
132
+ protected splitFolds(X: Matrix, y?: Float64Array | ArrayLike<number>, groups?: number[]): Fold[];
133
+ protected augmentMatrix(X: Matrix, axis?: Float64Array | number[]): Matrix;
134
+ protected augmentWithTargets(X: Matrix, y: Matrix | Float64Array | ArrayLike<number>, axis?: Float64Array | number[]): {
135
+ X: Matrix;
136
+ Y: Matrix;
137
+ };
138
+ protected runOutputs(X: Matrix, y?: Matrix | Float64Array | ArrayLike<number>, inputs?: FitInputs): Record<string, ProcedureOutput>;
139
+ }