@use-gpu/math 0.0.0-stage → 0.21.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/LICENSE.md +28 -0
- package/README.md +24 -2
- package/cjs/ease.cjs +285 -0
- package/cjs/ease.d.cts +25 -0
- package/cjs/ease.js.map +1 -0
- package/cjs/index.cjs +25 -0
- package/cjs/index.d.cts +6 -0
- package/cjs/index.js.map +1 -0
- package/cjs/linalg.cjs +101 -0
- package/cjs/linalg.d.cts +4 -0
- package/cjs/linalg.js.map +1 -0
- package/cjs/math.cjs +52 -0
- package/cjs/math.js.map +1 -0
- package/cjs/matrix.cjs +247 -0
- package/cjs/matrix.d.cts +18 -0
- package/cjs/matrix.js.map +1 -0
- package/cjs/number.cjs +52 -0
- package/cjs/number.d.cts +13 -0
- package/cjs/number.js.map +1 -0
- package/cjs/polynomial.cjs +174 -0
- package/cjs/polynomial.d.cts +5 -0
- package/cjs/polynomial.js.map +1 -0
- package/cjs/vector.cjs +108 -0
- package/cjs/vector.d.cts +32 -0
- package/cjs/vector.js.map +1 -0
- package/mjs/ease.d.mts +25 -0
- package/mjs/ease.js.map +1 -0
- package/mjs/ease.mjs +247 -0
- package/mjs/index.d.mts +6 -0
- package/mjs/index.js.map +1 -0
- package/mjs/index.mjs +8 -0
- package/mjs/linalg.d.mts +4 -0
- package/mjs/linalg.js.map +1 -0
- package/mjs/linalg.mjs +81 -0
- package/mjs/matrix.d.mts +18 -0
- package/mjs/matrix.js.map +1 -0
- package/mjs/matrix.mjs +237 -0
- package/mjs/number.d.mts +13 -0
- package/mjs/number.js.map +1 -0
- package/mjs/number.mjs +16 -0
- package/mjs/polynomial.d.mts +5 -0
- package/mjs/polynomial.js.map +1 -0
- package/mjs/polynomial.mjs +152 -0
- package/mjs/vector.d.mts +32 -0
- package/mjs/vector.js.map +1 -0
- package/mjs/vector.mjs +98 -0
- package/package.json +19 -3
package/mjs/matrix.mjs
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import { sqr } from './number.mjs';
|
|
2
|
+
const { sqrt } = Math;
|
|
3
|
+
// Get matrix dimensions
|
|
4
|
+
const dims = (m)=>[
|
|
5
|
+
m.length,
|
|
6
|
+
m[0].length
|
|
7
|
+
];
|
|
8
|
+
const size = ([a, b])=>`${a}x${b}`;
|
|
9
|
+
// Fill an NxM matrix using a given expression
|
|
10
|
+
const fill = (n, m, f = ()=>0)=>{
|
|
11
|
+
const out = [];
|
|
12
|
+
for(let j = 0; j < n; ++j){
|
|
13
|
+
const row = [];
|
|
14
|
+
for(let i = 0; i < m; ++i){
|
|
15
|
+
row[i] = f(i, j);
|
|
16
|
+
}
|
|
17
|
+
out.push(row);
|
|
18
|
+
}
|
|
19
|
+
return out;
|
|
20
|
+
};
|
|
21
|
+
// Identity matrix
|
|
22
|
+
const identity = (n)=>fill(n, n, (i, j)=>+(i == j));
|
|
23
|
+
// Add two matrices
|
|
24
|
+
const add = (a, b)=>{
|
|
25
|
+
const [na, ma] = dims(a);
|
|
26
|
+
const [nb, mb] = dims(b);
|
|
27
|
+
if (ma !== mb || na !== nb) {
|
|
28
|
+
console.error("Incompatible matrices", a, b, size(dims(a)), size(dims(b)));
|
|
29
|
+
throw new Error("Matrix error");
|
|
30
|
+
}
|
|
31
|
+
return fill(na, ma, (i, j)=>a[j][i] + b[j][i]);
|
|
32
|
+
};
|
|
33
|
+
// Subtract two matrices
|
|
34
|
+
const sub = (a, b)=>{
|
|
35
|
+
const [na, ma] = dims(a);
|
|
36
|
+
const [nb, mb] = dims(b);
|
|
37
|
+
if (ma !== mb || na !== nb) {
|
|
38
|
+
console.error("Incompatible matrices", a, b, size(dims(a)), size(dims(b)));
|
|
39
|
+
throw new Error("Matrix error");
|
|
40
|
+
}
|
|
41
|
+
return fill(na, ma, (i, j)=>a[j][i] - b[j][i]);
|
|
42
|
+
};
|
|
43
|
+
// Scale matrix by a scalar
|
|
44
|
+
const muls = (a, s)=>{
|
|
45
|
+
const [na, ma] = dims(a);
|
|
46
|
+
return fill(na, ma, (i, j)=>a[j][i] * s);
|
|
47
|
+
};
|
|
48
|
+
// Multiply two matrices
|
|
49
|
+
const mul = (a, b)=>{
|
|
50
|
+
const [na, ma] = dims(a);
|
|
51
|
+
const [nb, mb] = dims(b);
|
|
52
|
+
if (ma !== nb) {
|
|
53
|
+
console.error("Incompatible matrices", a, b, size(dims(a)), size(dims(b)));
|
|
54
|
+
throw new Error("Matrix error");
|
|
55
|
+
}
|
|
56
|
+
return fill(na, mb, (i, j)=>{
|
|
57
|
+
let v = 0;
|
|
58
|
+
for(let k = 0; k < ma; ++k)v += a[j][k] * b[k][i];
|
|
59
|
+
return v;
|
|
60
|
+
});
|
|
61
|
+
};
|
|
62
|
+
// Multiply two matrices while transposing the second
|
|
63
|
+
const tmul = (a, b)=>{
|
|
64
|
+
const [na, ma] = dims(a);
|
|
65
|
+
const [nb, mb] = dims(b);
|
|
66
|
+
if (ma !== mb) {
|
|
67
|
+
console.error("Incompatible matrices", a, b, size(dims(a)), size(dims(b)));
|
|
68
|
+
throw new Error("Matrix error");
|
|
69
|
+
}
|
|
70
|
+
return fill(na, nb, (i, j)=>{
|
|
71
|
+
let v = 0;
|
|
72
|
+
for(let k = 0; k < ma; ++k)v += a[j][k] * b[i][k];
|
|
73
|
+
return v;
|
|
74
|
+
});
|
|
75
|
+
};
|
|
76
|
+
// Transpose a matrix
|
|
77
|
+
const transpose = (x)=>{
|
|
78
|
+
const [n, m] = dims(x);
|
|
79
|
+
return fill(m, n, (i, j)=>x[i][j]);
|
|
80
|
+
};
|
|
81
|
+
// Concatenate two matrices horizontally
|
|
82
|
+
const concat = (a, b)=>{
|
|
83
|
+
const [na] = dims(a);
|
|
84
|
+
const nb = b.length;
|
|
85
|
+
if (na !== nb) {
|
|
86
|
+
console.error("Incompatible matrices", a, b, size(dims(a)), nb);
|
|
87
|
+
throw "Matrix error";
|
|
88
|
+
}
|
|
89
|
+
return a.map((_, i)=>a[i].concat(b[i]));
|
|
90
|
+
};
|
|
91
|
+
// Extract a submatrix from index (a,b) to (c,d) exclusive
|
|
92
|
+
const slice = (M, a, b, c, d)=>{
|
|
93
|
+
const [n, m] = dims(M);
|
|
94
|
+
a = Math.min(a, m);
|
|
95
|
+
b = Math.min(b, n);
|
|
96
|
+
if (c === undefined) c = m;
|
|
97
|
+
if (d === undefined) d = n;
|
|
98
|
+
c = Math.max(a, Math.min(m, c < 0 ? m + c : c));
|
|
99
|
+
d = Math.max(b, Math.min(n, d < 0 ? n + d : d));
|
|
100
|
+
return fill(d - b, c - a, (i, j)=>M[j][i]);
|
|
101
|
+
};
|
|
102
|
+
// Get matrix rank
|
|
103
|
+
const rank = (A)=>{
|
|
104
|
+
const G = jordanNormal(A);
|
|
105
|
+
return diagonalRank(G);
|
|
106
|
+
};
|
|
107
|
+
// Calculate frobenius norm squared
|
|
108
|
+
const norm2 = (x)=>{
|
|
109
|
+
const [n, m] = dims(x);
|
|
110
|
+
let v = 0;
|
|
111
|
+
for(let j = 0; j < m; ++j){
|
|
112
|
+
for(let i = 0; i < n; ++i){
|
|
113
|
+
v += sqr(x[j][i]);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return v;
|
|
117
|
+
};
|
|
118
|
+
// Calculate frobenius norm
|
|
119
|
+
const norm = (x)=>sqrt(norm2(x));
|
|
120
|
+
// Swap a later row to make (i,j) non-zero
|
|
121
|
+
const swapZero = (x, i, j)=>{
|
|
122
|
+
const [n] = dims(x);
|
|
123
|
+
for(let k = j + 1; k < n; ++k){
|
|
124
|
+
if (x[k][i] !== 0) {
|
|
125
|
+
[x[k], x[j]] = [
|
|
126
|
+
x[j],
|
|
127
|
+
x[k]
|
|
128
|
+
];
|
|
129
|
+
return true;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return false;
|
|
133
|
+
};
|
|
134
|
+
// In-place vector ops to spare the GC
|
|
135
|
+
// Scale a row by a constant
|
|
136
|
+
const scaleRow = (a, s)=>{
|
|
137
|
+
const { length } = a;
|
|
138
|
+
for(let i = 0; i < length; ++i)a[i] *= s;
|
|
139
|
+
};
|
|
140
|
+
// Multiply and add one row to another
|
|
141
|
+
const madRow = (a, b, s)=>{
|
|
142
|
+
const { length } = a;
|
|
143
|
+
for(let i = 0; i < length; ++i)a[i] += b[i] * s;
|
|
144
|
+
};
|
|
145
|
+
// Get determinant
|
|
146
|
+
const determinant = (x)=>{
|
|
147
|
+
const [n, m] = dims(x);
|
|
148
|
+
let offset = 0;
|
|
149
|
+
x = structuredClone(x);
|
|
150
|
+
let det = 1;
|
|
151
|
+
for(let i = 0; i < Math.min(n, m); ++i){
|
|
152
|
+
// Find next pivot element
|
|
153
|
+
const pivot = x[i][i + offset];
|
|
154
|
+
if (pivot == 0) {
|
|
155
|
+
// Unsuitable, find other row to swap with
|
|
156
|
+
if (!swapZero(x, i + offset, i)) {
|
|
157
|
+
// All zeros, move one column over until out of bounds
|
|
158
|
+
if (offset++ >= m - n) {
|
|
159
|
+
return 0;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
// Repeat iteration
|
|
163
|
+
i--;
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
// Scale pivot row
|
|
167
|
+
scaleRow(x[i], 1 / pivot);
|
|
168
|
+
det *= pivot;
|
|
169
|
+
// Subtract from other rows
|
|
170
|
+
for(let j = 0; j < n; ++j)if (i !== j) {
|
|
171
|
+
const pivot = x[j][i + offset];
|
|
172
|
+
madRow(x[j], x[i], -pivot);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return det;
|
|
176
|
+
};
|
|
177
|
+
// Convert matrix into jordan normal form if possible
|
|
178
|
+
const jordanNormal = (x)=>{
|
|
179
|
+
const [n, m] = dims(x);
|
|
180
|
+
let offset = 0;
|
|
181
|
+
// Don't modify argument
|
|
182
|
+
x = structuredClone(x);
|
|
183
|
+
for(let i = 0; i < Math.min(n, m); ++i){
|
|
184
|
+
// Find next pivot element
|
|
185
|
+
const pivot = x[i][i + offset];
|
|
186
|
+
if (pivot == 0) {
|
|
187
|
+
// Unsuitable, find other row to swap with
|
|
188
|
+
if (!swapZero(x, i + offset, i)) {
|
|
189
|
+
// All zeros, move one column over until out of bounds
|
|
190
|
+
if (offset++ >= m - n) {
|
|
191
|
+
return x;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
// Repeat iteration
|
|
195
|
+
i--;
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
// Scale pivot row
|
|
199
|
+
scaleRow(x[i], 1 / pivot);
|
|
200
|
+
// Subtract from other rows
|
|
201
|
+
for(let j = 0; j < n; ++j)if (i !== j) {
|
|
202
|
+
const pivot = x[j][i + offset];
|
|
203
|
+
madRow(x[j], x[i], -pivot);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return x;
|
|
207
|
+
};
|
|
208
|
+
// Verify if matrix has uninterrupted non-zero diagonal
|
|
209
|
+
const diagonalRank = (x)=>{
|
|
210
|
+
const [n, m] = dims(x);
|
|
211
|
+
const l = Math.min(n, m);
|
|
212
|
+
let i = 0;
|
|
213
|
+
for(; i < l; ++i){
|
|
214
|
+
if (x[i][i] == 0) break;
|
|
215
|
+
}
|
|
216
|
+
return i;
|
|
217
|
+
};
|
|
218
|
+
export const Matrix = {
|
|
219
|
+
dims,
|
|
220
|
+
fill,
|
|
221
|
+
identity,
|
|
222
|
+
add,
|
|
223
|
+
sub,
|
|
224
|
+
mul,
|
|
225
|
+
muls,
|
|
226
|
+
tmul,
|
|
227
|
+
transpose,
|
|
228
|
+
concat,
|
|
229
|
+
slice,
|
|
230
|
+
rank,
|
|
231
|
+
norm,
|
|
232
|
+
norm2,
|
|
233
|
+
determinant,
|
|
234
|
+
jordanNormal
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
//# sourceMappingURL=matrix.js.map
|
package/mjs/number.d.mts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type XY = [number, number];
|
|
2
|
+
export type XYZ = [number, number, number];
|
|
3
|
+
export type XYZW = [number, number, number, number];
|
|
4
|
+
export type TypedArray = Int8Array | Uint8Array | Int16Array | Uint16Array | Int32Array | Uint32Array | Uint8ClampedArray | Float32Array | Float64Array;
|
|
5
|
+
export type VectorLike = TypedArray | number[];
|
|
6
|
+
export declare const π: number;
|
|
7
|
+
export declare const τ: number;
|
|
8
|
+
export declare const clamp: (x: number, a: number, b: number) => number;
|
|
9
|
+
export declare const cub: (x: number) => number;
|
|
10
|
+
export declare const sqr: (x: number) => number;
|
|
11
|
+
export declare const lerp: (a: number, b: number, t: number) => number;
|
|
12
|
+
export declare const clerp: (a: number, b: number, t: number) => number;
|
|
13
|
+
export declare const seq: (n: number, start?: number, step?: number) => number[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../packages/math/src/number.ts"],"sourcesContent":["export type XY = [number, number];\nexport type XYZ = [number, number, number];\nexport type XYZW = [number, number, number, number];\n\nexport type TypedArray =\n Int8Array |\n Uint8Array |\n Int16Array |\n Uint16Array |\n Int32Array |\n Uint32Array |\n Uint8ClampedArray |\n //Float16Array |\n Float32Array |\n Float64Array;\n\nexport type VectorLike = TypedArray | number[];\n\nconst { max, min } = Math;\n\nexport const π = Math.PI;\nexport const τ = 2*π;\n\nexport const clamp = (x: number, a: number, b: number) => max(a, min(b, x));\n\nexport const cub = (x: number) => x * x * x;\nexport const sqr = (x: number) => x * x;\n\nexport const lerp = (a: number, b: number, t: number) => a * (1 - t) + b * t;\nexport const clerp = (a: number, b: number, t: number) => {\n const d = (((b - a + π) / τ) % 1) * τ - π;\n return lerp(a, a + d, t);\n};\n\nexport const seq = (n: number, start: number = 0, step: number = 1) => Array.from({length: n}).map((_, i) => start + i * step);\n"],"names":["max","min","Math","π","PI","τ","clamp","x","a","b","cub","sqr","lerp","t","clerp","d","seq","n","start","step","Array","from","length","map","_","i"],"mappings":"AAkBA,MAAM,EAAEA,GAAG,EAAEC,GAAG,EAAE,GAAGC;AAErB,OAAO,MAAMC,IAAID,KAAKE,EAAE,CAAC;AACzB,OAAO,MAAMC,IAAI,IAAEF,EAAE;AAErB,OAAO,MAAMG,QAAQ,CAACC,GAAWC,GAAWC,IAAcT,IAAIQ,GAAGP,IAAIQ,GAAGF,IAAI;AAE5E,OAAO,MAAMG,MAAM,CAACH,IAAcA,IAAIA,IAAIA,EAAE;AAC5C,OAAO,MAAMI,MAAM,CAACJ,IAAcA,IAAIA,EAAE;AAExC,OAAO,MAAMK,OAAO,CAACJ,GAAWC,GAAWI,IAAcL,IAAK,CAAA,IAAIK,CAAAA,IAAKJ,IAAII,EAAE;AAC7E,OAAO,MAAMC,QAAQ,CAACN,GAAWC,GAAWI;IAC1C,MAAME,IAAI,AAAGN,CAAAA,IAAID,IAAIL,CAAA,IAAKE,IAAK,IAAKA,IAAIF;IACxC,OAAOS,KAAKJ,GAAGA,IAAIO,GAAGF;AACxB,EAAE;AAEF,OAAO,MAAMG,MAAM,CAACC,GAAWC,QAAgB,CAAC,EAAEC,OAAe,CAAC,GAAKC,MAAMC,IAAI,CAAC;QAACC,QAAQL;IAAC,GAAGM,GAAG,CAAC,CAACC,GAAGC,IAAMP,QAAQO,IAAIN,MAAM"}
|
package/mjs/number.mjs
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const { max, min } = Math;
|
|
2
|
+
export const π = Math.PI;
|
|
3
|
+
export const τ = 2 * π;
|
|
4
|
+
export const clamp = (x, a, b)=>max(a, min(b, x));
|
|
5
|
+
export const cub = (x)=>x * x * x;
|
|
6
|
+
export const sqr = (x)=>x * x;
|
|
7
|
+
export const lerp = (a, b, t)=>a * (1 - t) + b * t;
|
|
8
|
+
export const clerp = (a, b, t)=>{
|
|
9
|
+
const d = (b - a + π) / τ % 1 * τ - π;
|
|
10
|
+
return lerp(a, a + d, t);
|
|
11
|
+
};
|
|
12
|
+
export const seq = (n, start = 0, step = 1)=>Array.from({
|
|
13
|
+
length: n
|
|
14
|
+
}).map((_, i)=>start + i * step);
|
|
15
|
+
|
|
16
|
+
//# sourceMappingURL=number.js.map
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const solveQuadratic: (a: number, b: number, c: number) => number[];
|
|
2
|
+
export declare const solveCubic: (a: number, b: number, c: number, d: number) => number[];
|
|
3
|
+
export declare const solveDepressedCubic: (p: number, q: number) => number[];
|
|
4
|
+
export declare const solveQuartic: (a: number, b: number, c: number, d: number, e: number) => number[];
|
|
5
|
+
export declare const solveDepressedQuartic: (a: number, b: number, c: number) => number[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../packages/math/src/polynomial.ts"],"sourcesContent":["import { π, sqr, cub } from './number';\n\nconst { acos, cbrt, cos, sign, sqrt } = Math;\n\n// Solve a quadratic a*x^2 + b*x + c = 0\nexport const solveQuadratic = (a: number, b: number, c: number): number[] => {\n const d = b*b - 4*a*c;\n if (d < 0) return [];\n if (d === 0) return [-b / (2*a)];\n\n const x1 = (-b - sqrt(d)) / (2*a);\n const x2 = (-b + sqrt(d)) / (2*a);\n return [x1, x2];\n}\n\n// Solve a cubic a*x^3 + b*x^2 + c*x + d = 0\nexport const solveCubic = (a: number, b: number, c: number, d: number): number[] => {\n const o = -b / (3 * a);\n const p = (3 * a * c - b * b) / (3 * a * a);\n const q = (2 * b * b * b - 9 * a * b * c + 27 * a * a * d) / (27 * a * a * a);\n \n return solveDepressedCubic(p, q).map(x => x + o);\n};\n\n// Solve a depressed cubic t^3 + p*t + q = 0\nexport const solveDepressedCubic = (p: number, q: number): number[] => {\n const p_3 = p / 3;\n const q_2 = q / 2;\n\n const p3_27 = cub(p_3);\n const ds = p3_27 + sqr(q_2);\n\n if (ds === 0) {\n // Multiple root\n if (p) {\n // Double root\n const r1 = q / p_3;\n const r2 = -q_2 / p_3;\n return [r1, r2];\n }\n // Triple root\n else {\n return [0];\n }\n }\n else if (ds > 0) {\n // Single real root\n // Vieta's substitution. Pick matching sign for better precision.\n const w = -q_2 - sqrt(ds) * sign(q);\n const cw = cbrt(w);\n return [cw - p_3 / cw];\n }\n else {\n // Three distinct real roots\n // Imaginary sqrt(ds)\n const dp = sqrt(-p3_27);\n const theta = acos(-q_2 / dp) / 3;\n const cw = cbrt(dp);\n const r = cw - p_3 / cw;\n\n const rs = [];\n for (let i = 0; i < 3; ++i) {\n const cc = cos(theta - i * (2/3) * π);\n const v = cc * r;\n rs.push(v);\n }\n\n return rs;\n }\n};\n\n// Solve a quartic a*x^4 + b*x^3 + c*x^2 + d*x + e = 0\nexport const solveQuartic = (a: number, b: number, c: number, d: number, e: number): number[] => {\n const o = -b / (4 * a);\n const aa = -3 * sqr(b) / (8 * sqr(a)) + c / a;\n const bb = cub(b) / (8 * cub(a)) - b * c / (2 * sqr(a)) + d / a;\n const cc = -3 * sqr(sqr(b)) / (256 * sqr(sqr(a))) + c * sqr(b) / (16 * cub(a)) - b * d / (4 * sqr(a)) + e / a;\n\n if (bb === 0) {\n // Biquadratic case\n const q = solveQuadratic(1, aa, cc);\n if (!q.length) return q;\n\n const solutions = [];\n const [q1, q2] = q;\n if (q1 > 0) {\n solutions.push(sqrt(q1) + o);\n solutions.push(-sqrt(q1) + o);\n }\n if (q2 > 0) {\n solutions.push(sqrt(q2) + o);\n solutions.push(-sqrt(q2) + o);\n }\n if (q1 === 0) {\n solutions.push(o);\n }\n if (q2 === 0) {\n solutions.push(o);\n }\n return solutions;\n }\n\n // Quartic case\n return solveDepressedQuartic(aa, bb, cc).map(x => x + o);\n};\n\n// Solve a depressed quartic t^4 + a*t^2 + b*t + c = 0\nexport const solveDepressedQuartic = (a: number, b: number, c: number): number[] => {\n const p = -sqr(a) / 12 - c;\n const q = -cub(a) / 108 + a * c / 3 - sqr(b) / 8;\n\n const q_2 = q / 2;\n const p_3 = p / 3;\n\n const p3_27 = cub(p_3);\n const ds = p3_27 + sqr(q_2);\n\n const solutions: number[] = [];\n\n let y = -Infinity;\n if (ds >= 0) {\n // Real R\n const r = -q_2 - sqrt(ds) * sign(ds);\n const u = cbrt(r);\n\n y = -5/6 * a + (u ? u - p / (3 * u) : -cbrt(q));\n }\n else {\n // Complex R\n const dp = sqrt(-p3_27);\n const theta = acos(-q_2 / dp) / 3;\n const ct = cos(theta);\n const ul = cbrt(dp);\n\n // U - P/(3U) is always real\n y = -5/6 * a + (ul ? ct * (ul - p_3 / ul) : -cbrt(q));\n }\n\n const w2 = a + 2 * y;\n const w = sqrt(w2);\n if (w2 < 0) {\n return solutions;\n }\n\n const qw1 = -(3 * a + 2 * y + 2 * b / w);\n const qw2 = -(3 * a + 2 * y - 2 * b / w);\n\n if (qw1 > 0) {\n const t1 = (w + sqrt(qw1)) / 2;\n const t2 = (w - sqrt(qw1)) / 2;\n solutions.push(t1, t2);\n }\n if (qw1 === 0) {\n solutions.push(w / 2);\n }\n if (qw2 > 0) {\n const t3 = (-w + sqrt(qw2)) / 2;\n const t4 = (-w - sqrt(qw2)) / 2;\n if (!solutions.includes(t3)) solutions.push(t3);\n if (!solutions.includes(t4)) solutions.push(t4);\n }\n if (qw2 === 0) {\n const t = -w / 2;\n if (!solutions.includes(t)) solutions.push(t);\n }\n \n return solutions;\n};\n"],"names":["π","sqr","cub","acos","cbrt","cos","sign","sqrt","Math","solveQuadratic","a","b","c","d","x1","x2","solveCubic","o","p","q","solveDepressedCubic","map","x","p_3","q_2","p3_27","ds","r1","r2","w","cw","dp","theta","r","rs","i","cc","v","push","solveQuartic","e","aa","bb","length","solutions","q1","q2","solveDepressedQuartic","y","Infinity","u","ct","ul","w2","qw1","qw2","t1","t2","t3","t4","includes","t"],"mappings":"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"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { π, sqr, cub } from './number.mjs';
|
|
2
|
+
const { acos, cbrt, cos, sign, sqrt } = Math;
|
|
3
|
+
// Solve a quadratic a*x^2 + b*x + c = 0
|
|
4
|
+
export const solveQuadratic = (a, b, c)=>{
|
|
5
|
+
const d = b * b - 4 * a * c;
|
|
6
|
+
if (d < 0) return [];
|
|
7
|
+
if (d === 0) return [
|
|
8
|
+
-b / (2 * a)
|
|
9
|
+
];
|
|
10
|
+
const x1 = (-b - sqrt(d)) / (2 * a);
|
|
11
|
+
const x2 = (-b + sqrt(d)) / (2 * a);
|
|
12
|
+
return [
|
|
13
|
+
x1,
|
|
14
|
+
x2
|
|
15
|
+
];
|
|
16
|
+
};
|
|
17
|
+
// Solve a cubic a*x^3 + b*x^2 + c*x + d = 0
|
|
18
|
+
export const solveCubic = (a, b, c, d)=>{
|
|
19
|
+
const o = -b / (3 * a);
|
|
20
|
+
const p = (3 * a * c - b * b) / (3 * a * a);
|
|
21
|
+
const q = (2 * b * b * b - 9 * a * b * c + 27 * a * a * d) / (27 * a * a * a);
|
|
22
|
+
return solveDepressedCubic(p, q).map((x)=>x + o);
|
|
23
|
+
};
|
|
24
|
+
// Solve a depressed cubic t^3 + p*t + q = 0
|
|
25
|
+
export const solveDepressedCubic = (p, q)=>{
|
|
26
|
+
const p_3 = p / 3;
|
|
27
|
+
const q_2 = q / 2;
|
|
28
|
+
const p3_27 = cub(p_3);
|
|
29
|
+
const ds = p3_27 + sqr(q_2);
|
|
30
|
+
if (ds === 0) {
|
|
31
|
+
// Multiple root
|
|
32
|
+
if (p) {
|
|
33
|
+
// Double root
|
|
34
|
+
const r1 = q / p_3;
|
|
35
|
+
const r2 = -q_2 / p_3;
|
|
36
|
+
return [
|
|
37
|
+
r1,
|
|
38
|
+
r2
|
|
39
|
+
];
|
|
40
|
+
} else {
|
|
41
|
+
return [
|
|
42
|
+
0
|
|
43
|
+
];
|
|
44
|
+
}
|
|
45
|
+
} else if (ds > 0) {
|
|
46
|
+
// Single real root
|
|
47
|
+
// Vieta's substitution. Pick matching sign for better precision.
|
|
48
|
+
const w = -q_2 - sqrt(ds) * sign(q);
|
|
49
|
+
const cw = cbrt(w);
|
|
50
|
+
return [
|
|
51
|
+
cw - p_3 / cw
|
|
52
|
+
];
|
|
53
|
+
} else {
|
|
54
|
+
// Three distinct real roots
|
|
55
|
+
// Imaginary sqrt(ds)
|
|
56
|
+
const dp = sqrt(-p3_27);
|
|
57
|
+
const theta = acos(-q_2 / dp) / 3;
|
|
58
|
+
const cw = cbrt(dp);
|
|
59
|
+
const r = cw - p_3 / cw;
|
|
60
|
+
const rs = [];
|
|
61
|
+
for(let i = 0; i < 3; ++i){
|
|
62
|
+
const cc = cos(theta - i * (2 / 3) * π);
|
|
63
|
+
const v = cc * r;
|
|
64
|
+
rs.push(v);
|
|
65
|
+
}
|
|
66
|
+
return rs;
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
// Solve a quartic a*x^4 + b*x^3 + c*x^2 + d*x + e = 0
|
|
70
|
+
export const solveQuartic = (a, b, c, d, e)=>{
|
|
71
|
+
const o = -b / (4 * a);
|
|
72
|
+
const aa = -3 * sqr(b) / (8 * sqr(a)) + c / a;
|
|
73
|
+
const bb = cub(b) / (8 * cub(a)) - b * c / (2 * sqr(a)) + d / a;
|
|
74
|
+
const cc = -3 * sqr(sqr(b)) / (256 * sqr(sqr(a))) + c * sqr(b) / (16 * cub(a)) - b * d / (4 * sqr(a)) + e / a;
|
|
75
|
+
if (bb === 0) {
|
|
76
|
+
// Biquadratic case
|
|
77
|
+
const q = solveQuadratic(1, aa, cc);
|
|
78
|
+
if (!q.length) return q;
|
|
79
|
+
const solutions = [];
|
|
80
|
+
const [q1, q2] = q;
|
|
81
|
+
if (q1 > 0) {
|
|
82
|
+
solutions.push(sqrt(q1) + o);
|
|
83
|
+
solutions.push(-sqrt(q1) + o);
|
|
84
|
+
}
|
|
85
|
+
if (q2 > 0) {
|
|
86
|
+
solutions.push(sqrt(q2) + o);
|
|
87
|
+
solutions.push(-sqrt(q2) + o);
|
|
88
|
+
}
|
|
89
|
+
if (q1 === 0) {
|
|
90
|
+
solutions.push(o);
|
|
91
|
+
}
|
|
92
|
+
if (q2 === 0) {
|
|
93
|
+
solutions.push(o);
|
|
94
|
+
}
|
|
95
|
+
return solutions;
|
|
96
|
+
}
|
|
97
|
+
// Quartic case
|
|
98
|
+
return solveDepressedQuartic(aa, bb, cc).map((x)=>x + o);
|
|
99
|
+
};
|
|
100
|
+
// Solve a depressed quartic t^4 + a*t^2 + b*t + c = 0
|
|
101
|
+
export const solveDepressedQuartic = (a, b, c)=>{
|
|
102
|
+
const p = -sqr(a) / 12 - c;
|
|
103
|
+
const q = -cub(a) / 108 + a * c / 3 - sqr(b) / 8;
|
|
104
|
+
const q_2 = q / 2;
|
|
105
|
+
const p_3 = p / 3;
|
|
106
|
+
const p3_27 = cub(p_3);
|
|
107
|
+
const ds = p3_27 + sqr(q_2);
|
|
108
|
+
const solutions = [];
|
|
109
|
+
let y = -Infinity;
|
|
110
|
+
if (ds >= 0) {
|
|
111
|
+
// Real R
|
|
112
|
+
const r = -q_2 - sqrt(ds) * sign(ds);
|
|
113
|
+
const u = cbrt(r);
|
|
114
|
+
y = -5 / 6 * a + (u ? u - p / (3 * u) : -cbrt(q));
|
|
115
|
+
} else {
|
|
116
|
+
// Complex R
|
|
117
|
+
const dp = sqrt(-p3_27);
|
|
118
|
+
const theta = acos(-q_2 / dp) / 3;
|
|
119
|
+
const ct = cos(theta);
|
|
120
|
+
const ul = cbrt(dp);
|
|
121
|
+
// U - P/(3U) is always real
|
|
122
|
+
y = -5 / 6 * a + (ul ? ct * (ul - p_3 / ul) : -cbrt(q));
|
|
123
|
+
}
|
|
124
|
+
const w2 = a + 2 * y;
|
|
125
|
+
const w = sqrt(w2);
|
|
126
|
+
if (w2 < 0) {
|
|
127
|
+
return solutions;
|
|
128
|
+
}
|
|
129
|
+
const qw1 = -(3 * a + 2 * y + 2 * b / w);
|
|
130
|
+
const qw2 = -(3 * a + 2 * y - 2 * b / w);
|
|
131
|
+
if (qw1 > 0) {
|
|
132
|
+
const t1 = (w + sqrt(qw1)) / 2;
|
|
133
|
+
const t2 = (w - sqrt(qw1)) / 2;
|
|
134
|
+
solutions.push(t1, t2);
|
|
135
|
+
}
|
|
136
|
+
if (qw1 === 0) {
|
|
137
|
+
solutions.push(w / 2);
|
|
138
|
+
}
|
|
139
|
+
if (qw2 > 0) {
|
|
140
|
+
const t3 = (-w + sqrt(qw2)) / 2;
|
|
141
|
+
const t4 = (-w - sqrt(qw2)) / 2;
|
|
142
|
+
if (!solutions.includes(t3)) solutions.push(t3);
|
|
143
|
+
if (!solutions.includes(t4)) solutions.push(t4);
|
|
144
|
+
}
|
|
145
|
+
if (qw2 === 0) {
|
|
146
|
+
const t = -w / 2;
|
|
147
|
+
if (!solutions.includes(t)) solutions.push(t);
|
|
148
|
+
}
|
|
149
|
+
return solutions;
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
//# sourceMappingURL=polynomial.js.map
|
package/mjs/vector.d.mts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { VectorLike } from './number.d.mts';
|
|
2
|
+
export declare const Vector: {
|
|
3
|
+
binary: (f: (a: number, b: number) => number) => <T extends VectorLike>(a: T, b: T) => T;
|
|
4
|
+
reduce: (f: (a: number, b: number, i: number) => number) => <T extends VectorLike>(v: T, accum?: number) => number;
|
|
5
|
+
reduce2: (f: (a: number, b: number, c: number, i: number) => number) => <T extends VectorLike>(a: T, b: T, accum?: number) => number;
|
|
6
|
+
add: <T extends VectorLike>(a: T, b: T) => T;
|
|
7
|
+
sub: <T extends VectorLike>(a: T, b: T) => T;
|
|
8
|
+
mul: <T extends VectorLike>(a: T, b: T) => T;
|
|
9
|
+
div: <T extends VectorLike>(a: T, b: T) => T;
|
|
10
|
+
dot: <T extends VectorLike>(a: T, b: T, accum?: number) => number;
|
|
11
|
+
adds: <T extends VectorLike>(a: T, s: number) => T;
|
|
12
|
+
subs: <T extends VectorLike>(a: T, s: number) => T;
|
|
13
|
+
muls: <T extends VectorLike>(a: T, s: number) => T;
|
|
14
|
+
mins: <T extends VectorLike>(a: T, b: number) => T;
|
|
15
|
+
maxs: <T extends VectorLike>(a: T, b: number) => T;
|
|
16
|
+
scale: <T extends VectorLike>(a: T, s: number) => T;
|
|
17
|
+
sum: <T extends VectorLike>(v: T, accum?: number) => number;
|
|
18
|
+
len2: <T extends VectorLike>(v: T, accum?: number) => number;
|
|
19
|
+
len: <T extends VectorLike>(a: T) => number;
|
|
20
|
+
dist2: <T extends VectorLike>(a: T, b: T, accum?: number) => number;
|
|
21
|
+
dist: <T extends VectorLike>(a: T, b: T) => number;
|
|
22
|
+
abs: <T extends VectorLike>(a: T) => T;
|
|
23
|
+
unit: <T extends VectorLike>(a: T) => T;
|
|
24
|
+
minEl: <T extends VectorLike>(a: T) => number;
|
|
25
|
+
maxEl: <T extends VectorLike>(a: T) => number;
|
|
26
|
+
min: <T extends VectorLike>(a: T, b: T) => T;
|
|
27
|
+
max: <T extends VectorLike>(a: T, b: T) => T;
|
|
28
|
+
clamp: <T extends VectorLike>(vector: T, a?: number, b?: number) => T;
|
|
29
|
+
lerp: <T extends VectorLike>(a: T, b: T, t: number) => T;
|
|
30
|
+
project: <T extends VectorLike>(a: T, n: T) => T;
|
|
31
|
+
select: <T extends VectorLike>(a: T, b: T, m: T) => T;
|
|
32
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../packages/math/src/vector.ts"],"sourcesContent":["import type { VectorLike } from './number';\n\n// Binary dot-like operator\nconst binary = (f: (a: number, b: number) => number) =>\n <T extends VectorLike>(a: T, b: T): T => {\n const {length} = a;\n const c = a.slice() as T;\n for (let i = 0; i < length; ++i) {\n c[i] = f(a[i], b[i]);\n }\n return c;\n }\n\n// Unary reduction operator\nconst reduce = (f: (a: number, b: number, i: number) => number) =>\n <T extends VectorLike>(v: T, accum: number = 0): number => {\n const {length} = v;\n for (let i = 0; i < length; ++i) {\n accum = f(accum, v[i], i);\n }\n return accum;\n };\n\n// Binary reduction operator\nconst reduce2 = (f: (a: number, b: number, c: number, i: number) => number) =>\n <T extends VectorLike>(a: T, b: T, accum: number = 0): number => {\n const {length} = a;\n for (let i = 0; i < length; ++i) {\n accum = f(accum, a[i], b[i], i);\n }\n return accum;\n };\n\n// Scalar operators\nconst plus = (x: number, y: number) => x + y;\nconst minus = (x: number, y: number) => x - y;\nconst multiply = (x: number, y: number) => x * y;\nconst divide = (x: number, y: number) => x / y;\nconst minimum = (x: number, y: number) => Math.min(x, y);\nconst maximum = (x: number, y: number) => Math.max(x, y);\n\nconst plus2 = (x: number, y: number) => x + y*y;\nconst mad = (x: number, y: number, z: number) => x + y*z;\nconst madl2 = (x: number, y: number, z: number) => x + (y - z) * (y - z);\n\n// Vector operators\nconst add = binary(plus);\nconst sub = binary(minus);\nconst mul = binary(multiply);\nconst div = binary(divide);\nconst dot = reduce2(mad);\nconst adds = <T extends VectorLike>(a: T, s: number) => a.map(x => x + s) as T;\nconst subs = <T extends VectorLike>(a: T, s: number) => a.map(x => x - s) as T;\nconst muls = <T extends VectorLike>(a: T, s: number) => a.map(x => x * s) as T;\nconst scale = muls;\n\nconst sum = reduce(plus);\nconst len2 = reduce(plus2);\nconst len = <T extends VectorLike>(a: T): number => Math.sqrt(len2(a));\nconst dist2 = reduce2(madl2);\nconst dist = <T extends VectorLike>(a: T, b: T): number => Math.sqrt(dist2(a, b));\n\nconst abs = <T extends VectorLike>(a: T): T => a.map(x => Math.abs(x)) as T;\nconst unit = <T extends VectorLike>(a: T): T => {\n const l = len(a);\n return scale(a, l ? 1/l : 0);\n};\n\nconst minEl = <T extends VectorLike>(a: T) => reduce(minimum)(a, Infinity);\nconst maxEl = <T extends VectorLike>(a: T) => reduce(maximum)(a, -Infinity);\n\nconst min = <T extends VectorLike>(a: T, b: T): T => a.map((_, i) => Math.min(a[i], b[i])) as T;\nconst max = <T extends VectorLike>(a: T, b: T): T => a.map((_, i) => Math.max(a[i], b[i])) as T;\nconst clamp = <T extends VectorLike>(vector: T, a: number = 0, b: number = 1): T => vector.map(v => Math.max(a, Math.min(b, v))) as T;\n\nconst mins = <T extends VectorLike>(a: T, b: number): T => a.map((_, i) => Math.min(a[i], b)) as T;\nconst maxs = <T extends VectorLike>(a: T, b: number): T => a.map((_, i) => Math.max(a[i], b)) as T;\n\nconst lerp = <T extends VectorLike>(a: T, b: T, t: number): T => add(a, scale(sub(b, a), t));\nconst project = <T extends VectorLike>(a: T, n: T): T => sub(a, scale(n, dot(a, n)));\nconst select = <T extends VectorLike>(a: T, b: T, m: T): T => m.map((s, i) => s ? b[i] : a[i]) as T;\n\nexport const Vector = {\n binary,\n reduce,\n reduce2,\n add,\n sub,\n mul,\n div,\n dot,\n adds,\n subs,\n muls,\n mins,\n maxs,\n scale,\n sum,\n len2,\n len,\n dist2,\n dist,\n abs,\n unit,\n minEl,\n maxEl,\n min,\n max,\n clamp,\n lerp,\n project,\n select,\n};\n"],"names":["binary","f","a","b","length","c","slice","i","reduce","v","accum","reduce2","plus","x","y","minus","multiply","divide","minimum","Math","min","maximum","max","plus2","mad","z","madl2","add","sub","mul","div","dot","adds","s","map","subs","muls","scale","sum","len2","len","sqrt","dist2","dist","abs","unit","l","minEl","Infinity","maxEl","_","clamp","vector","mins","maxs","lerp","t","project","n","select","m","Vector"],"mappings":"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"}
|
package/mjs/vector.mjs
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
// Binary dot-like operator
|
|
2
|
+
const binary = (f)=>(a, b)=>{
|
|
3
|
+
const { length } = a;
|
|
4
|
+
const c = a.slice();
|
|
5
|
+
for(let i = 0; i < length; ++i){
|
|
6
|
+
c[i] = f(a[i], b[i]);
|
|
7
|
+
}
|
|
8
|
+
return c;
|
|
9
|
+
};
|
|
10
|
+
// Unary reduction operator
|
|
11
|
+
const reduce = (f)=>(v, accum = 0)=>{
|
|
12
|
+
const { length } = v;
|
|
13
|
+
for(let i = 0; i < length; ++i){
|
|
14
|
+
accum = f(accum, v[i], i);
|
|
15
|
+
}
|
|
16
|
+
return accum;
|
|
17
|
+
};
|
|
18
|
+
// Binary reduction operator
|
|
19
|
+
const reduce2 = (f)=>(a, b, accum = 0)=>{
|
|
20
|
+
const { length } = a;
|
|
21
|
+
for(let i = 0; i < length; ++i){
|
|
22
|
+
accum = f(accum, a[i], b[i], i);
|
|
23
|
+
}
|
|
24
|
+
return accum;
|
|
25
|
+
};
|
|
26
|
+
// Scalar operators
|
|
27
|
+
const plus = (x, y)=>x + y;
|
|
28
|
+
const minus = (x, y)=>x - y;
|
|
29
|
+
const multiply = (x, y)=>x * y;
|
|
30
|
+
const divide = (x, y)=>x / y;
|
|
31
|
+
const minimum = (x, y)=>Math.min(x, y);
|
|
32
|
+
const maximum = (x, y)=>Math.max(x, y);
|
|
33
|
+
const plus2 = (x, y)=>x + y * y;
|
|
34
|
+
const mad = (x, y, z)=>x + y * z;
|
|
35
|
+
const madl2 = (x, y, z)=>x + (y - z) * (y - z);
|
|
36
|
+
// Vector operators
|
|
37
|
+
const add = binary(plus);
|
|
38
|
+
const sub = binary(minus);
|
|
39
|
+
const mul = binary(multiply);
|
|
40
|
+
const div = binary(divide);
|
|
41
|
+
const dot = reduce2(mad);
|
|
42
|
+
const adds = (a, s)=>a.map((x)=>x + s);
|
|
43
|
+
const subs = (a, s)=>a.map((x)=>x - s);
|
|
44
|
+
const muls = (a, s)=>a.map((x)=>x * s);
|
|
45
|
+
const scale = muls;
|
|
46
|
+
const sum = reduce(plus);
|
|
47
|
+
const len2 = reduce(plus2);
|
|
48
|
+
const len = (a)=>Math.sqrt(len2(a));
|
|
49
|
+
const dist2 = reduce2(madl2);
|
|
50
|
+
const dist = (a, b)=>Math.sqrt(dist2(a, b));
|
|
51
|
+
const abs = (a)=>a.map((x)=>Math.abs(x));
|
|
52
|
+
const unit = (a)=>{
|
|
53
|
+
const l = len(a);
|
|
54
|
+
return scale(a, l ? 1 / l : 0);
|
|
55
|
+
};
|
|
56
|
+
const minEl = (a)=>reduce(minimum)(a, Infinity);
|
|
57
|
+
const maxEl = (a)=>reduce(maximum)(a, -Infinity);
|
|
58
|
+
const min = (a, b)=>a.map((_, i)=>Math.min(a[i], b[i]));
|
|
59
|
+
const max = (a, b)=>a.map((_, i)=>Math.max(a[i], b[i]));
|
|
60
|
+
const clamp = (vector, a = 0, b = 1)=>vector.map((v)=>Math.max(a, Math.min(b, v)));
|
|
61
|
+
const mins = (a, b)=>a.map((_, i)=>Math.min(a[i], b));
|
|
62
|
+
const maxs = (a, b)=>a.map((_, i)=>Math.max(a[i], b));
|
|
63
|
+
const lerp = (a, b, t)=>add(a, scale(sub(b, a), t));
|
|
64
|
+
const project = (a, n)=>sub(a, scale(n, dot(a, n)));
|
|
65
|
+
const select = (a, b, m)=>m.map((s, i)=>s ? b[i] : a[i]);
|
|
66
|
+
export const Vector = {
|
|
67
|
+
binary,
|
|
68
|
+
reduce,
|
|
69
|
+
reduce2,
|
|
70
|
+
add,
|
|
71
|
+
sub,
|
|
72
|
+
mul,
|
|
73
|
+
div,
|
|
74
|
+
dot,
|
|
75
|
+
adds,
|
|
76
|
+
subs,
|
|
77
|
+
muls,
|
|
78
|
+
mins,
|
|
79
|
+
maxs,
|
|
80
|
+
scale,
|
|
81
|
+
sum,
|
|
82
|
+
len2,
|
|
83
|
+
len,
|
|
84
|
+
dist2,
|
|
85
|
+
dist,
|
|
86
|
+
abs,
|
|
87
|
+
unit,
|
|
88
|
+
minEl,
|
|
89
|
+
maxEl,
|
|
90
|
+
min,
|
|
91
|
+
max,
|
|
92
|
+
clamp,
|
|
93
|
+
lerp,
|
|
94
|
+
project,
|
|
95
|
+
select
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
//# sourceMappingURL=vector.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@use-gpu/math",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.21.0",
|
|
4
|
+
"main": "./cjs/index.cjs",
|
|
5
|
+
"author": "Steven Wittens <steven@acko.net>",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"test": "vitest --watch",
|
|
10
|
+
"lint": "eslint src",
|
|
11
|
+
"coverage": "vitest --coverage",
|
|
12
|
+
"types": "tsc --noEmit",
|
|
13
|
+
"types:watch": "yarn run types -- --watch",
|
|
14
|
+
"build": "NPM_PACKAGE=math ../../scripts/build-mjs-cjs.sh"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"use-gpu",
|
|
18
|
+
"use-gpu-library"
|
|
19
|
+
],
|
|
20
|
+
"sideEffects": false,
|
|
21
|
+
"module": "./mjs/index.mjs"
|
|
6
22
|
}
|