@c9up/atom 0.1.12 → 0.1.14
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 +57 -0
- package/dist/Decimal.d.ts +32 -0
- package/dist/Decimal.d.ts.map +1 -1
- package/dist/Decimal.js +50 -0
- package/dist/Decimal.js.map +1 -1
- package/dist/bulk.d.ts +193 -0
- package/dist/bulk.d.ts.map +1 -0
- package/dist/bulk.js +826 -0
- package/dist/bulk.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +33 -16
- package/dist/index.js.map +1 -1
- package/dist/native/generated.d.ts +23 -0
- package/dist/native/generated.d.ts.map +1 -1
- package/index.darwin-arm64.node +0 -0
- package/index.darwin-x64.node +0 -0
- package/index.linux-arm64-gnu.node +0 -0
- package/index.linux-x64-gnu.node +0 -0
- package/index.win32-x64-msvc.node +0 -0
- package/package.json +11 -9
- package/scripts/bench-bulk.mjs +98 -0
- package/scripts/clean-wasm-pack-meta.mjs +32 -0
- package/scripts/copy-napi.mjs +11 -3
- package/scripts/verify-wasm.mjs +49 -2
- package/src/Decimal.ts +58 -0
- package/src/bulk.ts +1054 -0
- package/src/index.ts +34 -16
- package/src/native/generated.ts +33 -0
- package/wasm/atom_engine_wasm.d.ts +86 -0
- package/wasm/atom_engine_wasm.js +583 -0
- package/wasm/atom_engine_wasm_bg.wasm +0 -0
- package/wasm/atom_engine_wasm_bg.wasm.d.ts +22 -0
package/src/index.ts
CHANGED
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
* pure TypeScript BigInt fallback for unsupported platforms.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
export type { BulkDivOptions, BulkStddevOptions } from "./bulk.js";
|
|
8
|
+
export { Bulk, BulkColumn, BulkScalar, bulk } from "./bulk.js";
|
|
7
9
|
export type { AtomContext, AtomContextOptions } from "./context.js";
|
|
8
10
|
export {
|
|
9
11
|
configureAtomContext,
|
|
@@ -34,6 +36,7 @@ export type {
|
|
|
34
36
|
export { Money, money } from "./Money.js";
|
|
35
37
|
export { isNativeAvailable } from "./native.js";
|
|
36
38
|
|
|
39
|
+
import { bulk as bulkFn } from "./bulk.js";
|
|
37
40
|
import { defaultPrecision, defaultRoundMode } from "./context.js";
|
|
38
41
|
import type { MedianOptions, StddevOptions } from "./Decimal.js";
|
|
39
42
|
import { Decimal, type DecimalInput } from "./Decimal.js";
|
|
@@ -82,21 +85,28 @@ function resolveValues(args: readonly unknown[]): Iterable<DecimalInput> {
|
|
|
82
85
|
return args.map(toDecimalValue);
|
|
83
86
|
}
|
|
84
87
|
|
|
88
|
+
/**
|
|
89
|
+
* Exact sum — through the engine's BATCH entry point, not a fold.
|
|
90
|
+
*
|
|
91
|
+
* The result is identical either way; the cost is not. Every `plus` from
|
|
92
|
+
* JavaScript serialises both operands, crosses into the native engine and
|
|
93
|
+
* comes back with a string, and that crossing is where the time goes — around
|
|
94
|
+
* a microsecond an operation, against nanoseconds for the arithmetic itself.
|
|
95
|
+
* `Decimal.sum` hands the whole list over once, so summing a column of a
|
|
96
|
+
* hundred thousand figures costs one crossing rather than a hundred thousand.
|
|
97
|
+
*
|
|
98
|
+
* Nothing changed for callers: this is what `Atom.sum` always meant.
|
|
99
|
+
*/
|
|
85
100
|
function sumImpl(values: Iterable<DecimalInput>): Decimal {
|
|
86
|
-
|
|
87
|
-
for (const value of values) {
|
|
88
|
-
total = total.plus(value);
|
|
89
|
-
}
|
|
90
|
-
return total;
|
|
101
|
+
return Decimal.sum(values);
|
|
91
102
|
}
|
|
92
103
|
|
|
93
104
|
function avgImpl(values: Iterable<DecimalInput>): Decimal {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}
|
|
105
|
+
// Materialised so the count and the batch see the same values: an iterable
|
|
106
|
+
// consumed by one is not there for the other.
|
|
107
|
+
const list = [...values];
|
|
108
|
+
const total = Decimal.sum(list);
|
|
109
|
+
const count = list.length;
|
|
100
110
|
if (count === 0) {
|
|
101
111
|
throw new Error("Atom.avg requires at least one value");
|
|
102
112
|
}
|
|
@@ -183,11 +193,10 @@ function stddevImpl(
|
|
|
183
193
|
throw new Error("Atom.stddev sample mode requires at least two values");
|
|
184
194
|
}
|
|
185
195
|
const mean = avgImpl(list);
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
}
|
|
196
|
+
// `Σ diff²` is a dot product of the deviations with themselves: one
|
|
197
|
+
// crossing, where the fold made two per value — a multiply and an add.
|
|
198
|
+
const deviations = list.map((value) => value.minus(mean));
|
|
199
|
+
const sumSquares = Decimal.dot(deviations, deviations);
|
|
191
200
|
const variance = sumSquares.div(String(divisor), {
|
|
192
201
|
precision: precision + 8,
|
|
193
202
|
});
|
|
@@ -278,6 +287,15 @@ function stddevFn(
|
|
|
278
287
|
export const Atom = {
|
|
279
288
|
/** Construct a `Decimal` from a string / number / bigint / Decimal. Alias for `Decimal.from`. */
|
|
280
289
|
decimal,
|
|
290
|
+
/**
|
|
291
|
+
* Plan a computation and run it in one crossing.
|
|
292
|
+
*
|
|
293
|
+
* For chains of dependent operations — a schedule, a rate solver, a
|
|
294
|
+
* statistic over a column — where the cost is the boundary rather than the
|
|
295
|
+
* arithmetic. Not for a lone sum: below about three operations per element a
|
|
296
|
+
* plain loop wins.
|
|
297
|
+
*/
|
|
298
|
+
bulk: bulkFn,
|
|
281
299
|
/** Exact sum of N values. Empty input → `Decimal('0')`. */
|
|
282
300
|
sum: sumFn,
|
|
283
301
|
/** Arithmetic mean of N values. Throws on empty input. */
|
package/src/native/generated.ts
CHANGED
|
@@ -4,6 +4,25 @@
|
|
|
4
4
|
// output. Editing this file by hand puts it back where it started: a
|
|
5
5
|
// description that can disagree with the code it describes.
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Run a bulk program over a resident column buffer.
|
|
9
|
+
*
|
|
10
|
+
* `values` holds every column laid end to end, `rows` values each, followed by
|
|
11
|
+
* the scalar literals the program refers to by absolute index. `program` is
|
|
12
|
+
* six-word bytecode. Returns the scalars the program emitted, in order.
|
|
13
|
+
*
|
|
14
|
+
* An overflow of the 128-bit working width is reported with a message opening
|
|
15
|
+
* `[ATOM_BULK_OVERFLOW]`, which is the caller's signal to re-run the same
|
|
16
|
+
* program on the BigInt executor rather than to give up: the fast path is
|
|
17
|
+
* allowed to be too narrow, never to be wrong.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
export declare function runBulk(
|
|
21
|
+
values: BigInt64Array,
|
|
22
|
+
rows: number,
|
|
23
|
+
program: Int32Array,
|
|
24
|
+
): Array<string>;
|
|
25
|
+
|
|
7
26
|
export declare function add(a: string, b: string): string;
|
|
8
27
|
|
|
9
28
|
export declare function sub(a: string, b: string): string;
|
|
@@ -18,4 +37,18 @@ export declare function pow(a: string, exp: number, precision: number): string;
|
|
|
18
37
|
|
|
19
38
|
export declare function sqrt(a: string, precision: number): string;
|
|
20
39
|
|
|
40
|
+
/**
|
|
41
|
+
* Batch addition — one crossing for the whole list.
|
|
42
|
+
*
|
|
43
|
+
* `Vec<String>` rather than a stream of calls, because the crossing IS the
|
|
44
|
+
* cost: parsing and formatting a decimal is cheap, and doing it once per
|
|
45
|
+
* pair from JavaScript is what makes a long fold expensive.
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
export declare function sum(values: Array<string>): string;
|
|
49
|
+
|
|
50
|
+
/** Batch `Σ aᵢ·bᵢ` — the shape of every valuation, in one crossing. */
|
|
51
|
+
|
|
52
|
+
export declare function dot(a: Array<string>, b: Array<string>): string;
|
|
53
|
+
|
|
21
54
|
export declare function cmp(a: string, b: string): number;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
|
|
4
|
+
export function add(a: string, b: string): string;
|
|
5
|
+
|
|
6
|
+
export function cmp(a: string, b: string): number;
|
|
7
|
+
|
|
8
|
+
export function div(a: string, b: string, precision: number): string;
|
|
9
|
+
|
|
10
|
+
export function dot(a: string[], b: string[]): string;
|
|
11
|
+
|
|
12
|
+
export function mul(a: string, b: string): string;
|
|
13
|
+
|
|
14
|
+
export function pow(a: string, exp: number, precision: number): string;
|
|
15
|
+
|
|
16
|
+
export function rem(a: string, b: string): string;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Run a bulk program over a resident column buffer.
|
|
20
|
+
*
|
|
21
|
+
* Held to the same shape as the N-API build so the two engines cannot quietly
|
|
22
|
+
* diverge — the browser has to export what Node does. `Vec<i64>` and `Vec<i32>`
|
|
23
|
+
* cross as `BigInt64Array` and `Int32Array`, which is what the compiler in
|
|
24
|
+
* TypeScript produces anyway.
|
|
25
|
+
*/
|
|
26
|
+
export function runBulk(values: BigInt64Array, rows: number, program: Int32Array): string[];
|
|
27
|
+
|
|
28
|
+
export function sqrt(a: string, precision: number): string;
|
|
29
|
+
|
|
30
|
+
export function sub(a: string, b: string): string;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* The batch pair, held to the same shape as the NAPI build so the two
|
|
34
|
+
* engines cannot quietly diverge — the browser has to export what Node does.
|
|
35
|
+
*
|
|
36
|
+
* `Vec<String>` crosses the wasm boundary as a JS array of strings, which is
|
|
37
|
+
* exactly what the facade holds anyway.
|
|
38
|
+
*/
|
|
39
|
+
export function sum(values: string[]): string;
|
|
40
|
+
|
|
41
|
+
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
|
42
|
+
|
|
43
|
+
export interface InitOutput {
|
|
44
|
+
readonly memory: WebAssembly.Memory;
|
|
45
|
+
readonly add: (a: number, b: number, c: number, d: number) => [number, number, number, number];
|
|
46
|
+
readonly cmp: (a: number, b: number, c: number, d: number) => [number, number, number];
|
|
47
|
+
readonly div: (a: number, b: number, c: number, d: number, e: number) => [number, number, number, number];
|
|
48
|
+
readonly dot: (a: number, b: number, c: number, d: number) => [number, number, number, number];
|
|
49
|
+
readonly mul: (a: number, b: number, c: number, d: number) => [number, number, number, number];
|
|
50
|
+
readonly pow: (a: number, b: number, c: number, d: number) => [number, number, number, number];
|
|
51
|
+
readonly rem: (a: number, b: number, c: number, d: number) => [number, number, number, number];
|
|
52
|
+
readonly runBulk: (a: number, b: number, c: number, d: number, e: number) => [number, number, number, number];
|
|
53
|
+
readonly sqrt: (a: number, b: number, c: number) => [number, number, number, number];
|
|
54
|
+
readonly sub: (a: number, b: number, c: number, d: number) => [number, number, number, number];
|
|
55
|
+
readonly sum: (a: number, b: number) => [number, number, number, number];
|
|
56
|
+
readonly __wbindgen_malloc: (a: number, b: number) => number;
|
|
57
|
+
readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
|
|
58
|
+
readonly __wbindgen_externrefs: WebAssembly.Table;
|
|
59
|
+
readonly __externref_table_dealloc: (a: number) => void;
|
|
60
|
+
readonly __wbindgen_free: (a: number, b: number, c: number) => void;
|
|
61
|
+
readonly __externref_table_alloc: () => number;
|
|
62
|
+
readonly __externref_drop_slice: (a: number, b: number) => void;
|
|
63
|
+
readonly __wbindgen_start: () => void;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export type SyncInitInput = BufferSource | WebAssembly.Module;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Instantiates the given `module`, which can either be bytes or
|
|
70
|
+
* a precompiled `WebAssembly.Module`.
|
|
71
|
+
*
|
|
72
|
+
* @param {{ module: SyncInitInput }} module - Passing `SyncInitInput` directly is deprecated.
|
|
73
|
+
*
|
|
74
|
+
* @returns {InitOutput}
|
|
75
|
+
*/
|
|
76
|
+
export function initSync(module: { module: SyncInitInput } | SyncInitInput): InitOutput;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* If `module_or_path` is {RequestInfo} or {URL}, makes a request and
|
|
80
|
+
* for everything else, calls `WebAssembly.instantiate` directly.
|
|
81
|
+
*
|
|
82
|
+
* @param {{ module_or_path: InitInput | Promise<InitInput> }} module_or_path - Passing `InitInput` directly is deprecated.
|
|
83
|
+
*
|
|
84
|
+
* @returns {Promise<InitOutput>}
|
|
85
|
+
*/
|
|
86
|
+
export default function __wbg_init (module_or_path?: { module_or_path: InitInput | Promise<InitInput> } | InitInput | Promise<InitInput>): Promise<InitOutput>;
|