numbl 0.4.18 → 0.4.21
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/dist-browser/browser.js +1 -1
- package/dist-browser/numbl-core/executors/jit/callExecutor.d.ts +7 -1
- package/dist-browser/numbl-core/executors/jit/loopExecutor.d.ts +12 -7
- package/dist-browser/numbl-core/executors/jit/topLevelExecutor.d.ts +3 -0
- package/dist-browser/numbl-core/executors/jit/valueAdapter.d.ts +9 -2
- package/dist-browser/numbl-core/executors/registry.d.ts +8 -0
- package/dist-browser/numbl-core/helpers/sparse-direct.d.ts +107 -0
- package/dist-browser/numbl-core/helpers/warn.d.ts +9 -0
- package/dist-browser/numbl-core/interpreter/builtins/index.d.ts +1 -0
- package/dist-browser/numbl-core/interpreter/builtins/sparse-solvers.d.ts +16 -0
- package/dist-browser/numbl-core/interpreter/interpreter.d.ts +11 -0
- package/dist-browser/numbl-core/jit/builtins/runtime/system/cscalar.d.ts +4 -4
- package/dist-browser/numbl-core/jit/codegen/emitIndex.d.ts +1 -1
- package/dist-browser/numbl-core/jit/compileSpec.d.ts +4 -0
- package/dist-browser/numbl-core/jit/lowering/lower.d.ts +13 -0
- package/dist-browser/numbl-core/jitDeclineDiagnostics.d.ts +6 -0
- package/dist-browser/numbl-core/native/lapack-bridge.d.ts +29 -1
- package/dist-browser/numbl-core/native/ts-lapack-eig-hermitian.d.ts +33 -0
- package/dist-browser/numbl-core/runtime/types.d.ts +12 -0
- package/dist-browser/numbl-core/version.d.ts +1 -1
- package/dist-browser/ts-lapack/src/BLAS/dsymv.d.ts +1 -0
- package/dist-browser/ts-lapack/src/BLAS/dsyr2.d.ts +1 -0
- package/dist-browser/ts-lapack/src/SRC/dlae2.d.ts +4 -0
- package/dist-browser/ts-lapack/src/SRC/dlaev2.d.ts +6 -0
- package/dist-browser/ts-lapack/src/SRC/dlanst.d.ts +1 -0
- package/dist-browser/ts-lapack/src/SRC/dlansy.d.ts +1 -0
- package/dist-browser/ts-lapack/src/SRC/dlasrt.d.ts +1 -0
- package/dist-browser/ts-lapack/src/SRC/dorgtr.d.ts +1 -0
- package/dist-browser/ts-lapack/src/SRC/dsteqr.d.ts +4 -0
- package/dist-browser/ts-lapack/src/SRC/dsyev.d.ts +1 -0
- package/dist-browser/ts-lapack/src/SRC/dsytd2.d.ts +1 -0
- package/dist-cli/cli.js +3824 -280
- package/dist-lib/lib.js +3636 -113
- package/dist-lib/numbl-core/executors/jit/callExecutor.d.ts +7 -1
- package/dist-lib/numbl-core/executors/jit/loopExecutor.d.ts +12 -7
- package/dist-lib/numbl-core/executors/jit/topLevelExecutor.d.ts +3 -0
- package/dist-lib/numbl-core/executors/jit/valueAdapter.d.ts +9 -2
- package/dist-lib/numbl-core/executors/registry.d.ts +8 -0
- package/dist-lib/numbl-core/helpers/sparse-direct.d.ts +107 -0
- package/dist-lib/numbl-core/helpers/warn.d.ts +9 -0
- package/dist-lib/numbl-core/interpreter/builtins/index.d.ts +1 -0
- package/dist-lib/numbl-core/interpreter/builtins/sparse-solvers.d.ts +16 -0
- package/dist-lib/numbl-core/interpreter/interpreter.d.ts +11 -0
- package/dist-lib/numbl-core/jit/builtins/runtime/system/cscalar.d.ts +4 -4
- package/dist-lib/numbl-core/jit/codegen/emitIndex.d.ts +1 -1
- package/dist-lib/numbl-core/jit/compileSpec.d.ts +4 -0
- package/dist-lib/numbl-core/jit/lowering/lower.d.ts +13 -0
- package/dist-lib/numbl-core/jitDeclineDiagnostics.d.ts +6 -0
- package/dist-lib/numbl-core/native/lapack-bridge.d.ts +29 -1
- package/dist-lib/numbl-core/native/ts-lapack-eig-hermitian.d.ts +33 -0
- package/dist-lib/numbl-core/runtime/types.d.ts +12 -0
- package/dist-lib/numbl-core/version.d.ts +1 -1
- package/dist-lib/ts-lapack/src/BLAS/dsymv.d.ts +1 -0
- package/dist-lib/ts-lapack/src/BLAS/dsyr2.d.ts +1 -0
- package/dist-lib/ts-lapack/src/SRC/dlae2.d.ts +4 -0
- package/dist-lib/ts-lapack/src/SRC/dlaev2.d.ts +6 -0
- package/dist-lib/ts-lapack/src/SRC/dlanst.d.ts +1 -0
- package/dist-lib/ts-lapack/src/SRC/dlansy.d.ts +1 -0
- package/dist-lib/ts-lapack/src/SRC/dlasrt.d.ts +1 -0
- package/dist-lib/ts-lapack/src/SRC/dorgtr.d.ts +1 -0
- package/dist-lib/ts-lapack/src/SRC/dsteqr.d.ts +4 -0
- package/dist-lib/ts-lapack/src/SRC/dsyev.d.ts +1 -0
- package/dist-lib/ts-lapack/src/SRC/dsytd2.d.ts +1 -0
- package/dist-site-viewer/assets/index-DrtkDG_M.js +4832 -0
- package/dist-site-viewer/assets/numbl-worker-Dz_Z8B9u.js +5327 -0
- package/dist-site-viewer/index.html +1 -1
- package/native/lapack_eig.cpp +156 -0
- package/native/numbl_addon.cpp +7 -1
- package/native/numbl_addon_common.h +14 -0
- package/package.json +1 -1
- package/dist-site-viewer/assets/index-34LVPucU.js +0 -4831
- package/dist-site-viewer/assets/numbl-worker-BCMSGYEy.js +0 -5339
package/dist-lib/lib.js
CHANGED
|
@@ -372,6 +372,9 @@ var RuntimeSparseMatrix = class extends Refcounted {
|
|
|
372
372
|
jc;
|
|
373
373
|
pr;
|
|
374
374
|
pi;
|
|
375
|
+
/** Lazily computed by triangularInfo(); valid because sparse matrices are
|
|
376
|
+
* never mutated in place (indexed assignment builds a new matrix). */
|
|
377
|
+
_triInfo = void 0;
|
|
375
378
|
constructor(m, n, ir, jc, pr, pi2) {
|
|
376
379
|
super();
|
|
377
380
|
this.m = m;
|
|
@@ -1171,6 +1174,7 @@ function formatClassInstance(v) {
|
|
|
1171
1174
|
const lines = [` ${v.className} with properties:
|
|
1172
1175
|
`];
|
|
1173
1176
|
for (const [key, val] of v.fields) {
|
|
1177
|
+
if (key.startsWith("_")) continue;
|
|
1174
1178
|
lines.push(` ${key}: ${displayValue(val)}`);
|
|
1175
1179
|
}
|
|
1176
1180
|
return lines.join("\n");
|
|
@@ -1484,6 +1488,8 @@ var PIVOT_T = 1;
|
|
|
1484
1488
|
var PIVOT_B = 2;
|
|
1485
1489
|
var DIRECT_F = 0;
|
|
1486
1490
|
var DIRECT_B = 1;
|
|
1491
|
+
var SORT_INC = 0;
|
|
1492
|
+
var SORT_DEC = 1;
|
|
1487
1493
|
var VECT_Q = 0;
|
|
1488
1494
|
var VECT_P = 1;
|
|
1489
1495
|
|
|
@@ -18090,6 +18096,1357 @@ function eigComplexTs(dataRe, dataIm, n, computeVL, computeVR) {
|
|
|
18090
18096
|
return result;
|
|
18091
18097
|
}
|
|
18092
18098
|
|
|
18099
|
+
// src/ts-lapack/src/SRC/dlanst.ts
|
|
18100
|
+
var NORM_MAX5 = 0;
|
|
18101
|
+
var NORM_ONE2 = 1;
|
|
18102
|
+
var NORM_INF2 = 2;
|
|
18103
|
+
var NORM_FRO2 = 3;
|
|
18104
|
+
function dlanst(norm2, n, d, dOff, e, eOff) {
|
|
18105
|
+
let anorm = 0;
|
|
18106
|
+
if (n <= 0) {
|
|
18107
|
+
anorm = 0;
|
|
18108
|
+
} else if (norm2 === NORM_MAX5) {
|
|
18109
|
+
anorm = Math.abs(d[dOff + (n - 1)]);
|
|
18110
|
+
for (let i = 1; i <= n - 1; i++) {
|
|
18111
|
+
let sum2 = Math.abs(d[dOff + (i - 1)]);
|
|
18112
|
+
if (anorm < sum2 || Number.isNaN(sum2)) anorm = sum2;
|
|
18113
|
+
sum2 = Math.abs(e[eOff + (i - 1)]);
|
|
18114
|
+
if (anorm < sum2 || Number.isNaN(sum2)) anorm = sum2;
|
|
18115
|
+
}
|
|
18116
|
+
} else if (norm2 === NORM_ONE2 || norm2 === NORM_INF2) {
|
|
18117
|
+
if (n === 1) {
|
|
18118
|
+
anorm = Math.abs(d[dOff]);
|
|
18119
|
+
} else {
|
|
18120
|
+
anorm = Math.abs(d[dOff]) + Math.abs(e[eOff]);
|
|
18121
|
+
let sum2 = Math.abs(e[eOff + (n - 2)]) + Math.abs(d[dOff + (n - 1)]);
|
|
18122
|
+
if (anorm < sum2 || Number.isNaN(sum2)) anorm = sum2;
|
|
18123
|
+
for (let i = 2; i <= n - 1; i++) {
|
|
18124
|
+
sum2 = Math.abs(d[dOff + (i - 1)]) + Math.abs(e[eOff + (i - 1)]) + Math.abs(e[eOff + (i - 2)]);
|
|
18125
|
+
if (anorm < sum2 || Number.isNaN(sum2)) anorm = sum2;
|
|
18126
|
+
}
|
|
18127
|
+
}
|
|
18128
|
+
} else if (norm2 === NORM_FRO2) {
|
|
18129
|
+
const scale = { val: 0 };
|
|
18130
|
+
const sum2 = { val: 1 };
|
|
18131
|
+
if (n > 1) {
|
|
18132
|
+
dlassq(n - 1, e, eOff, 1, scale, sum2);
|
|
18133
|
+
sum2.val = 2 * sum2.val;
|
|
18134
|
+
}
|
|
18135
|
+
dlassq(n, d, dOff, 1, scale, sum2);
|
|
18136
|
+
anorm = scale.val * Math.sqrt(sum2.val);
|
|
18137
|
+
}
|
|
18138
|
+
return anorm;
|
|
18139
|
+
}
|
|
18140
|
+
|
|
18141
|
+
// src/ts-lapack/src/SRC/dlae2.ts
|
|
18142
|
+
function dlae2(a, b, c) {
|
|
18143
|
+
const ONE10 = 1;
|
|
18144
|
+
const TWO = 2;
|
|
18145
|
+
const HALF = 0.5;
|
|
18146
|
+
const sm = a + c;
|
|
18147
|
+
const df = a - c;
|
|
18148
|
+
const adf = Math.abs(df);
|
|
18149
|
+
const tb = b + b;
|
|
18150
|
+
const ab = Math.abs(tb);
|
|
18151
|
+
let acmx, acmn;
|
|
18152
|
+
if (Math.abs(a) > Math.abs(c)) {
|
|
18153
|
+
acmx = a;
|
|
18154
|
+
acmn = c;
|
|
18155
|
+
} else {
|
|
18156
|
+
acmx = c;
|
|
18157
|
+
acmn = a;
|
|
18158
|
+
}
|
|
18159
|
+
let rt;
|
|
18160
|
+
if (adf > ab) {
|
|
18161
|
+
rt = adf * Math.sqrt(ONE10 + (ab / adf) ** 2);
|
|
18162
|
+
} else if (adf < ab) {
|
|
18163
|
+
rt = ab * Math.sqrt(ONE10 + (adf / ab) ** 2);
|
|
18164
|
+
} else {
|
|
18165
|
+
rt = ab * Math.sqrt(TWO);
|
|
18166
|
+
}
|
|
18167
|
+
let rt1, rt2;
|
|
18168
|
+
if (sm < 0) {
|
|
18169
|
+
rt1 = HALF * (sm - rt);
|
|
18170
|
+
rt2 = acmx / rt1 * acmn - b / rt1 * b;
|
|
18171
|
+
} else if (sm > 0) {
|
|
18172
|
+
rt1 = HALF * (sm + rt);
|
|
18173
|
+
rt2 = acmx / rt1 * acmn - b / rt1 * b;
|
|
18174
|
+
} else {
|
|
18175
|
+
rt1 = HALF * rt;
|
|
18176
|
+
rt2 = -HALF * rt;
|
|
18177
|
+
}
|
|
18178
|
+
return { rt1, rt2 };
|
|
18179
|
+
}
|
|
18180
|
+
|
|
18181
|
+
// src/ts-lapack/src/SRC/dlaev2.ts
|
|
18182
|
+
function dlaev2(a, b, c) {
|
|
18183
|
+
const ONE10 = 1;
|
|
18184
|
+
const TWO = 2;
|
|
18185
|
+
const HALF = 0.5;
|
|
18186
|
+
const sm = a + c;
|
|
18187
|
+
const df = a - c;
|
|
18188
|
+
const adf = Math.abs(df);
|
|
18189
|
+
const tb = b + b;
|
|
18190
|
+
const ab = Math.abs(tb);
|
|
18191
|
+
let acmx, acmn;
|
|
18192
|
+
if (Math.abs(a) > Math.abs(c)) {
|
|
18193
|
+
acmx = a;
|
|
18194
|
+
acmn = c;
|
|
18195
|
+
} else {
|
|
18196
|
+
acmx = c;
|
|
18197
|
+
acmn = a;
|
|
18198
|
+
}
|
|
18199
|
+
let rt;
|
|
18200
|
+
if (adf > ab) {
|
|
18201
|
+
rt = adf * Math.sqrt(ONE10 + (ab / adf) ** 2);
|
|
18202
|
+
} else if (adf < ab) {
|
|
18203
|
+
rt = ab * Math.sqrt(ONE10 + (adf / ab) ** 2);
|
|
18204
|
+
} else {
|
|
18205
|
+
rt = ab * Math.sqrt(TWO);
|
|
18206
|
+
}
|
|
18207
|
+
let rt1, rt2, sgn1;
|
|
18208
|
+
if (sm < 0) {
|
|
18209
|
+
rt1 = HALF * (sm - rt);
|
|
18210
|
+
sgn1 = -1;
|
|
18211
|
+
rt2 = acmx / rt1 * acmn - b / rt1 * b;
|
|
18212
|
+
} else if (sm > 0) {
|
|
18213
|
+
rt1 = HALF * (sm + rt);
|
|
18214
|
+
sgn1 = 1;
|
|
18215
|
+
rt2 = acmx / rt1 * acmn - b / rt1 * b;
|
|
18216
|
+
} else {
|
|
18217
|
+
rt1 = HALF * rt;
|
|
18218
|
+
rt2 = -HALF * rt;
|
|
18219
|
+
sgn1 = 1;
|
|
18220
|
+
}
|
|
18221
|
+
let cs, sgn2;
|
|
18222
|
+
if (df >= 0) {
|
|
18223
|
+
cs = df + rt;
|
|
18224
|
+
sgn2 = 1;
|
|
18225
|
+
} else {
|
|
18226
|
+
cs = df - rt;
|
|
18227
|
+
sgn2 = -1;
|
|
18228
|
+
}
|
|
18229
|
+
let cs1, sn1;
|
|
18230
|
+
const acs = Math.abs(cs);
|
|
18231
|
+
if (acs > ab) {
|
|
18232
|
+
const ct = -tb / cs;
|
|
18233
|
+
sn1 = ONE10 / Math.sqrt(ONE10 + ct * ct);
|
|
18234
|
+
cs1 = ct * sn1;
|
|
18235
|
+
} else {
|
|
18236
|
+
if (ab === 0) {
|
|
18237
|
+
cs1 = ONE10;
|
|
18238
|
+
sn1 = 0;
|
|
18239
|
+
} else {
|
|
18240
|
+
const tn = -cs / tb;
|
|
18241
|
+
cs1 = ONE10 / Math.sqrt(ONE10 + tn * tn);
|
|
18242
|
+
sn1 = tn * cs1;
|
|
18243
|
+
}
|
|
18244
|
+
}
|
|
18245
|
+
if (sgn1 === sgn2) {
|
|
18246
|
+
const tn = cs1;
|
|
18247
|
+
cs1 = -sn1;
|
|
18248
|
+
sn1 = tn;
|
|
18249
|
+
}
|
|
18250
|
+
return { rt1, rt2, cs1, sn1 };
|
|
18251
|
+
}
|
|
18252
|
+
|
|
18253
|
+
// src/ts-lapack/src/SRC/dlasrt.ts
|
|
18254
|
+
function dlasrt(id, n, d, dOff) {
|
|
18255
|
+
const SELECT = 20;
|
|
18256
|
+
let info = 0;
|
|
18257
|
+
let dir = -1;
|
|
18258
|
+
if (id === SORT_DEC) {
|
|
18259
|
+
dir = 0;
|
|
18260
|
+
} else if (id === SORT_INC) {
|
|
18261
|
+
dir = 1;
|
|
18262
|
+
}
|
|
18263
|
+
if (dir === -1) {
|
|
18264
|
+
info = -1;
|
|
18265
|
+
} else if (n < 0) {
|
|
18266
|
+
info = -2;
|
|
18267
|
+
}
|
|
18268
|
+
if (info !== 0) {
|
|
18269
|
+
return info;
|
|
18270
|
+
}
|
|
18271
|
+
if (n <= 1) {
|
|
18272
|
+
return 0;
|
|
18273
|
+
}
|
|
18274
|
+
const stack1 = new Int32Array(33);
|
|
18275
|
+
const stack2 = new Int32Array(33);
|
|
18276
|
+
let stkpnt = 1;
|
|
18277
|
+
stack1[1] = 1;
|
|
18278
|
+
stack2[1] = n;
|
|
18279
|
+
while (stkpnt > 0) {
|
|
18280
|
+
const start = stack1[stkpnt];
|
|
18281
|
+
const endd = stack2[stkpnt];
|
|
18282
|
+
stkpnt--;
|
|
18283
|
+
if (endd - start <= SELECT && endd - start > 0) {
|
|
18284
|
+
if (dir === 0) {
|
|
18285
|
+
for (let i = start + 1; i <= endd; i++) {
|
|
18286
|
+
for (let j = i; j >= start + 1; j--) {
|
|
18287
|
+
if (d[dOff + (j - 1)] > d[dOff + (j - 2)]) {
|
|
18288
|
+
const dmnmx = d[dOff + (j - 1)];
|
|
18289
|
+
d[dOff + (j - 1)] = d[dOff + (j - 2)];
|
|
18290
|
+
d[dOff + (j - 2)] = dmnmx;
|
|
18291
|
+
} else {
|
|
18292
|
+
break;
|
|
18293
|
+
}
|
|
18294
|
+
}
|
|
18295
|
+
}
|
|
18296
|
+
} else {
|
|
18297
|
+
for (let i = start + 1; i <= endd; i++) {
|
|
18298
|
+
for (let j = i; j >= start + 1; j--) {
|
|
18299
|
+
if (d[dOff + (j - 1)] < d[dOff + (j - 2)]) {
|
|
18300
|
+
const dmnmx = d[dOff + (j - 1)];
|
|
18301
|
+
d[dOff + (j - 1)] = d[dOff + (j - 2)];
|
|
18302
|
+
d[dOff + (j - 2)] = dmnmx;
|
|
18303
|
+
} else {
|
|
18304
|
+
break;
|
|
18305
|
+
}
|
|
18306
|
+
}
|
|
18307
|
+
}
|
|
18308
|
+
}
|
|
18309
|
+
} else if (endd - start > SELECT) {
|
|
18310
|
+
const d1 = d[dOff + (start - 1)];
|
|
18311
|
+
const d2 = d[dOff + (endd - 1)];
|
|
18312
|
+
const ii = Math.trunc((start + endd) / 2);
|
|
18313
|
+
const d3 = d[dOff + (ii - 1)];
|
|
18314
|
+
let dmnmx;
|
|
18315
|
+
if (d1 < d2) {
|
|
18316
|
+
if (d3 < d1) {
|
|
18317
|
+
dmnmx = d1;
|
|
18318
|
+
} else if (d3 < d2) {
|
|
18319
|
+
dmnmx = d3;
|
|
18320
|
+
} else {
|
|
18321
|
+
dmnmx = d2;
|
|
18322
|
+
}
|
|
18323
|
+
} else {
|
|
18324
|
+
if (d3 < d2) {
|
|
18325
|
+
dmnmx = d2;
|
|
18326
|
+
} else if (d3 < d1) {
|
|
18327
|
+
dmnmx = d3;
|
|
18328
|
+
} else {
|
|
18329
|
+
dmnmx = d1;
|
|
18330
|
+
}
|
|
18331
|
+
}
|
|
18332
|
+
let i;
|
|
18333
|
+
let j;
|
|
18334
|
+
if (dir === 0) {
|
|
18335
|
+
i = start - 1;
|
|
18336
|
+
j = endd + 1;
|
|
18337
|
+
while (true) {
|
|
18338
|
+
do {
|
|
18339
|
+
j--;
|
|
18340
|
+
} while (d[dOff + (j - 1)] < dmnmx);
|
|
18341
|
+
do {
|
|
18342
|
+
i++;
|
|
18343
|
+
} while (d[dOff + (i - 1)] > dmnmx);
|
|
18344
|
+
if (i < j) {
|
|
18345
|
+
const tmp = d[dOff + (i - 1)];
|
|
18346
|
+
d[dOff + (i - 1)] = d[dOff + (j - 1)];
|
|
18347
|
+
d[dOff + (j - 1)] = tmp;
|
|
18348
|
+
} else {
|
|
18349
|
+
break;
|
|
18350
|
+
}
|
|
18351
|
+
}
|
|
18352
|
+
if (j - start > endd - j - 1) {
|
|
18353
|
+
stkpnt++;
|
|
18354
|
+
stack1[stkpnt] = start;
|
|
18355
|
+
stack2[stkpnt] = j;
|
|
18356
|
+
stkpnt++;
|
|
18357
|
+
stack1[stkpnt] = j + 1;
|
|
18358
|
+
stack2[stkpnt] = endd;
|
|
18359
|
+
} else {
|
|
18360
|
+
stkpnt++;
|
|
18361
|
+
stack1[stkpnt] = j + 1;
|
|
18362
|
+
stack2[stkpnt] = endd;
|
|
18363
|
+
stkpnt++;
|
|
18364
|
+
stack1[stkpnt] = start;
|
|
18365
|
+
stack2[stkpnt] = j;
|
|
18366
|
+
}
|
|
18367
|
+
} else {
|
|
18368
|
+
i = start - 1;
|
|
18369
|
+
j = endd + 1;
|
|
18370
|
+
while (true) {
|
|
18371
|
+
do {
|
|
18372
|
+
j--;
|
|
18373
|
+
} while (d[dOff + (j - 1)] > dmnmx);
|
|
18374
|
+
do {
|
|
18375
|
+
i++;
|
|
18376
|
+
} while (d[dOff + (i - 1)] < dmnmx);
|
|
18377
|
+
if (i < j) {
|
|
18378
|
+
const tmp = d[dOff + (i - 1)];
|
|
18379
|
+
d[dOff + (i - 1)] = d[dOff + (j - 1)];
|
|
18380
|
+
d[dOff + (j - 1)] = tmp;
|
|
18381
|
+
} else {
|
|
18382
|
+
break;
|
|
18383
|
+
}
|
|
18384
|
+
}
|
|
18385
|
+
if (j - start > endd - j - 1) {
|
|
18386
|
+
stkpnt++;
|
|
18387
|
+
stack1[stkpnt] = start;
|
|
18388
|
+
stack2[stkpnt] = j;
|
|
18389
|
+
stkpnt++;
|
|
18390
|
+
stack1[stkpnt] = j + 1;
|
|
18391
|
+
stack2[stkpnt] = endd;
|
|
18392
|
+
} else {
|
|
18393
|
+
stkpnt++;
|
|
18394
|
+
stack1[stkpnt] = j + 1;
|
|
18395
|
+
stack2[stkpnt] = endd;
|
|
18396
|
+
stkpnt++;
|
|
18397
|
+
stack1[stkpnt] = start;
|
|
18398
|
+
stack2[stkpnt] = j;
|
|
18399
|
+
}
|
|
18400
|
+
}
|
|
18401
|
+
}
|
|
18402
|
+
}
|
|
18403
|
+
return 0;
|
|
18404
|
+
}
|
|
18405
|
+
|
|
18406
|
+
// src/ts-lapack/src/SRC/dsteqr.ts
|
|
18407
|
+
var COMPZ_N = 0;
|
|
18408
|
+
var COMPZ_V = 1;
|
|
18409
|
+
var COMPZ_I = 2;
|
|
18410
|
+
var NORM_MAX6 = 0;
|
|
18411
|
+
var TYPE_G3 = 0;
|
|
18412
|
+
var UPLO_FULL2 = -1;
|
|
18413
|
+
function fsign6(a, b) {
|
|
18414
|
+
return b >= 0 ? Math.abs(a) : -Math.abs(a);
|
|
18415
|
+
}
|
|
18416
|
+
function dsteqr(compz, n, d, dOff, e, eOff, z, zOff, ldz, work, workOff) {
|
|
18417
|
+
const ZERO9 = 0;
|
|
18418
|
+
const ONE10 = 1;
|
|
18419
|
+
const TWO = 2;
|
|
18420
|
+
const THREE = 3;
|
|
18421
|
+
const MAXIT = 30;
|
|
18422
|
+
let info = 0;
|
|
18423
|
+
if (compz !== COMPZ_N && compz !== COMPZ_V && compz !== COMPZ_I) {
|
|
18424
|
+
info = -1;
|
|
18425
|
+
} else if (n < 0) {
|
|
18426
|
+
info = -2;
|
|
18427
|
+
} else if (ldz < 1 || compz > 0 && ldz < Math.max(1, n)) {
|
|
18428
|
+
info = -6;
|
|
18429
|
+
}
|
|
18430
|
+
if (info !== 0) {
|
|
18431
|
+
xerbla("DSTEQR", -info);
|
|
18432
|
+
return info;
|
|
18433
|
+
}
|
|
18434
|
+
if (n === 0) return 0;
|
|
18435
|
+
if (n === 1) {
|
|
18436
|
+
if (compz === COMPZ_I) z[zOff] = ONE10;
|
|
18437
|
+
return 0;
|
|
18438
|
+
}
|
|
18439
|
+
const D = (i) => dOff + (i - 1);
|
|
18440
|
+
const E = (i) => eOff + (i - 1);
|
|
18441
|
+
const Zc = (j) => zOff + (j - 1) * ldz;
|
|
18442
|
+
const W = (i) => workOff + (i - 1);
|
|
18443
|
+
const eps2 = dlamch(MACH_EPS);
|
|
18444
|
+
const eps22 = eps2 * eps2;
|
|
18445
|
+
const safmin = dlamch(MACH_SFMIN);
|
|
18446
|
+
const safmax = ONE10 / safmin;
|
|
18447
|
+
const ssfmax = Math.sqrt(safmax) / THREE;
|
|
18448
|
+
const ssfmin = Math.sqrt(safmin) / eps22;
|
|
18449
|
+
if (compz === COMPZ_I) dlaset(UPLO_FULL2, n, n, ZERO9, ONE10, z, zOff, ldz);
|
|
18450
|
+
const nmaxit = n * MAXIT;
|
|
18451
|
+
let jtot = 0;
|
|
18452
|
+
let l1 = 1;
|
|
18453
|
+
const nm1 = n - 1;
|
|
18454
|
+
let ordered = false;
|
|
18455
|
+
outer: for (; ; ) {
|
|
18456
|
+
if (l1 > n) {
|
|
18457
|
+
ordered = true;
|
|
18458
|
+
break outer;
|
|
18459
|
+
}
|
|
18460
|
+
if (l1 > 1) e[E(l1 - 1)] = ZERO9;
|
|
18461
|
+
let m = n;
|
|
18462
|
+
if (l1 <= nm1) {
|
|
18463
|
+
let split = false;
|
|
18464
|
+
for (m = l1; m <= nm1; m++) {
|
|
18465
|
+
const tst = Math.abs(e[E(m)]);
|
|
18466
|
+
if (tst === ZERO9) {
|
|
18467
|
+
split = true;
|
|
18468
|
+
break;
|
|
18469
|
+
}
|
|
18470
|
+
if (tst <= Math.sqrt(Math.abs(d[D(m)])) * Math.sqrt(Math.abs(d[D(m + 1)])) * eps2) {
|
|
18471
|
+
e[E(m)] = ZERO9;
|
|
18472
|
+
split = true;
|
|
18473
|
+
break;
|
|
18474
|
+
}
|
|
18475
|
+
}
|
|
18476
|
+
if (!split) m = n;
|
|
18477
|
+
}
|
|
18478
|
+
let l = l1;
|
|
18479
|
+
const lsv = l;
|
|
18480
|
+
let lend = m;
|
|
18481
|
+
const lendsv = lend;
|
|
18482
|
+
l1 = m + 1;
|
|
18483
|
+
if (lend === l) continue outer;
|
|
18484
|
+
const anorm = dlanst(NORM_MAX6, lend - l + 1, d, D(l), e, E(l));
|
|
18485
|
+
let iscale = 0;
|
|
18486
|
+
if (anorm === ZERO9) continue outer;
|
|
18487
|
+
if (anorm > ssfmax) {
|
|
18488
|
+
iscale = 1;
|
|
18489
|
+
dlascl(TYPE_G3, 0, 0, anorm, ssfmax, lend - l + 1, 1, d, D(l), n);
|
|
18490
|
+
dlascl(TYPE_G3, 0, 0, anorm, ssfmax, lend - l, 1, e, E(l), n);
|
|
18491
|
+
} else if (anorm < ssfmin) {
|
|
18492
|
+
iscale = 2;
|
|
18493
|
+
dlascl(TYPE_G3, 0, 0, anorm, ssfmin, lend - l + 1, 1, d, D(l), n);
|
|
18494
|
+
dlascl(TYPE_G3, 0, 0, anorm, ssfmin, lend - l, 1, e, E(l), n);
|
|
18495
|
+
}
|
|
18496
|
+
if (Math.abs(d[D(lend)]) < Math.abs(d[D(l)])) {
|
|
18497
|
+
lend = lsv;
|
|
18498
|
+
l = lendsv;
|
|
18499
|
+
}
|
|
18500
|
+
if (lend > l) {
|
|
18501
|
+
ql: for (; ; ) {
|
|
18502
|
+
if (l !== lend) {
|
|
18503
|
+
let found = false;
|
|
18504
|
+
for (m = l; m <= lend - 1; m++) {
|
|
18505
|
+
const tst = Math.abs(e[E(m)]) ** 2;
|
|
18506
|
+
if (tst <= eps22 * Math.abs(d[D(m)]) * Math.abs(d[D(m + 1)]) + safmin) {
|
|
18507
|
+
found = true;
|
|
18508
|
+
break;
|
|
18509
|
+
}
|
|
18510
|
+
}
|
|
18511
|
+
if (!found) m = lend;
|
|
18512
|
+
} else {
|
|
18513
|
+
m = lend;
|
|
18514
|
+
}
|
|
18515
|
+
if (m < lend) e[E(m)] = ZERO9;
|
|
18516
|
+
let p2 = d[D(l)];
|
|
18517
|
+
if (m === l) {
|
|
18518
|
+
d[D(l)] = p2;
|
|
18519
|
+
l = l + 1;
|
|
18520
|
+
if (l <= lend) continue ql;
|
|
18521
|
+
break ql;
|
|
18522
|
+
}
|
|
18523
|
+
if (m === l + 1) {
|
|
18524
|
+
if (compz > 0) {
|
|
18525
|
+
const r2 = dlaev2(d[D(l)], e[E(l)], d[D(l + 1)]);
|
|
18526
|
+
work[W(l)] = r2.cs1;
|
|
18527
|
+
work[W(n - 1 + l)] = r2.sn1;
|
|
18528
|
+
dlasr(
|
|
18529
|
+
RIGHT,
|
|
18530
|
+
PIVOT_V,
|
|
18531
|
+
DIRECT_B,
|
|
18532
|
+
n,
|
|
18533
|
+
2,
|
|
18534
|
+
work,
|
|
18535
|
+
W(l),
|
|
18536
|
+
work,
|
|
18537
|
+
W(n - 1 + l),
|
|
18538
|
+
z,
|
|
18539
|
+
Zc(l),
|
|
18540
|
+
ldz
|
|
18541
|
+
);
|
|
18542
|
+
d[D(l)] = r2.rt1;
|
|
18543
|
+
d[D(l + 1)] = r2.rt2;
|
|
18544
|
+
} else {
|
|
18545
|
+
const r2 = dlae2(d[D(l)], e[E(l)], d[D(l + 1)]);
|
|
18546
|
+
d[D(l)] = r2.rt1;
|
|
18547
|
+
d[D(l + 1)] = r2.rt2;
|
|
18548
|
+
}
|
|
18549
|
+
e[E(l)] = ZERO9;
|
|
18550
|
+
l = l + 2;
|
|
18551
|
+
if (l <= lend) continue ql;
|
|
18552
|
+
break ql;
|
|
18553
|
+
}
|
|
18554
|
+
if (jtot === nmaxit) break ql;
|
|
18555
|
+
jtot = jtot + 1;
|
|
18556
|
+
let g = (d[D(l + 1)] - p2) / (TWO * e[E(l)]);
|
|
18557
|
+
let r = dlapy2(g, ONE10);
|
|
18558
|
+
g = d[D(m)] - p2 + e[E(l)] / (g + fsign6(r, g));
|
|
18559
|
+
let s = ONE10;
|
|
18560
|
+
let c = ONE10;
|
|
18561
|
+
p2 = ZERO9;
|
|
18562
|
+
for (let i = m - 1; i >= l; i--) {
|
|
18563
|
+
const f = s * e[E(i)];
|
|
18564
|
+
const b = c * e[E(i)];
|
|
18565
|
+
const rot = dlartg(g, f);
|
|
18566
|
+
c = rot.cs;
|
|
18567
|
+
s = rot.sn;
|
|
18568
|
+
r = rot.r;
|
|
18569
|
+
if (i !== m - 1) e[E(i + 1)] = r;
|
|
18570
|
+
g = d[D(i + 1)] - p2;
|
|
18571
|
+
r = (d[D(i)] - g) * s + TWO * c * b;
|
|
18572
|
+
p2 = s * r;
|
|
18573
|
+
d[D(i + 1)] = g + p2;
|
|
18574
|
+
g = c * r - b;
|
|
18575
|
+
if (compz > 0) {
|
|
18576
|
+
work[W(i)] = c;
|
|
18577
|
+
work[W(n - 1 + i)] = -s;
|
|
18578
|
+
}
|
|
18579
|
+
}
|
|
18580
|
+
if (compz > 0) {
|
|
18581
|
+
const mm = m - l + 1;
|
|
18582
|
+
dlasr(
|
|
18583
|
+
RIGHT,
|
|
18584
|
+
PIVOT_V,
|
|
18585
|
+
DIRECT_B,
|
|
18586
|
+
n,
|
|
18587
|
+
mm,
|
|
18588
|
+
work,
|
|
18589
|
+
W(l),
|
|
18590
|
+
work,
|
|
18591
|
+
W(n - 1 + l),
|
|
18592
|
+
z,
|
|
18593
|
+
Zc(l),
|
|
18594
|
+
ldz
|
|
18595
|
+
);
|
|
18596
|
+
}
|
|
18597
|
+
d[D(l)] = d[D(l)] - p2;
|
|
18598
|
+
e[E(l)] = g;
|
|
18599
|
+
continue ql;
|
|
18600
|
+
}
|
|
18601
|
+
} else {
|
|
18602
|
+
qr: for (; ; ) {
|
|
18603
|
+
if (l !== lend) {
|
|
18604
|
+
let found = false;
|
|
18605
|
+
for (m = l; m >= lend + 1; m--) {
|
|
18606
|
+
const tst = Math.abs(e[E(m - 1)]) ** 2;
|
|
18607
|
+
if (tst <= eps22 * Math.abs(d[D(m)]) * Math.abs(d[D(m - 1)]) + safmin) {
|
|
18608
|
+
found = true;
|
|
18609
|
+
break;
|
|
18610
|
+
}
|
|
18611
|
+
}
|
|
18612
|
+
if (!found) m = lend;
|
|
18613
|
+
} else {
|
|
18614
|
+
m = lend;
|
|
18615
|
+
}
|
|
18616
|
+
if (m > lend) e[E(m - 1)] = ZERO9;
|
|
18617
|
+
let p2 = d[D(l)];
|
|
18618
|
+
if (m === l) {
|
|
18619
|
+
d[D(l)] = p2;
|
|
18620
|
+
l = l - 1;
|
|
18621
|
+
if (l >= lend) continue qr;
|
|
18622
|
+
break qr;
|
|
18623
|
+
}
|
|
18624
|
+
if (m === l - 1) {
|
|
18625
|
+
if (compz > 0) {
|
|
18626
|
+
const r2 = dlaev2(d[D(l - 1)], e[E(l - 1)], d[D(l)]);
|
|
18627
|
+
work[W(m)] = r2.cs1;
|
|
18628
|
+
work[W(n - 1 + m)] = r2.sn1;
|
|
18629
|
+
dlasr(
|
|
18630
|
+
RIGHT,
|
|
18631
|
+
PIVOT_V,
|
|
18632
|
+
DIRECT_F,
|
|
18633
|
+
n,
|
|
18634
|
+
2,
|
|
18635
|
+
work,
|
|
18636
|
+
W(m),
|
|
18637
|
+
work,
|
|
18638
|
+
W(n - 1 + m),
|
|
18639
|
+
z,
|
|
18640
|
+
Zc(l - 1),
|
|
18641
|
+
ldz
|
|
18642
|
+
);
|
|
18643
|
+
d[D(l - 1)] = r2.rt1;
|
|
18644
|
+
d[D(l)] = r2.rt2;
|
|
18645
|
+
} else {
|
|
18646
|
+
const r2 = dlae2(d[D(l - 1)], e[E(l - 1)], d[D(l)]);
|
|
18647
|
+
d[D(l - 1)] = r2.rt1;
|
|
18648
|
+
d[D(l)] = r2.rt2;
|
|
18649
|
+
}
|
|
18650
|
+
e[E(l - 1)] = ZERO9;
|
|
18651
|
+
l = l - 2;
|
|
18652
|
+
if (l >= lend) continue qr;
|
|
18653
|
+
break qr;
|
|
18654
|
+
}
|
|
18655
|
+
if (jtot === nmaxit) break qr;
|
|
18656
|
+
jtot = jtot + 1;
|
|
18657
|
+
let g = (d[D(l - 1)] - p2) / (TWO * e[E(l - 1)]);
|
|
18658
|
+
let r = dlapy2(g, ONE10);
|
|
18659
|
+
g = d[D(m)] - p2 + e[E(l - 1)] / (g + fsign6(r, g));
|
|
18660
|
+
let s = ONE10;
|
|
18661
|
+
let c = ONE10;
|
|
18662
|
+
p2 = ZERO9;
|
|
18663
|
+
for (let i = m; i <= l - 1; i++) {
|
|
18664
|
+
const f = s * e[E(i)];
|
|
18665
|
+
const b = c * e[E(i)];
|
|
18666
|
+
const rot = dlartg(g, f);
|
|
18667
|
+
c = rot.cs;
|
|
18668
|
+
s = rot.sn;
|
|
18669
|
+
r = rot.r;
|
|
18670
|
+
if (i !== m) e[E(i - 1)] = r;
|
|
18671
|
+
g = d[D(i)] - p2;
|
|
18672
|
+
r = (d[D(i + 1)] - g) * s + TWO * c * b;
|
|
18673
|
+
p2 = s * r;
|
|
18674
|
+
d[D(i)] = g + p2;
|
|
18675
|
+
g = c * r - b;
|
|
18676
|
+
if (compz > 0) {
|
|
18677
|
+
work[W(i)] = c;
|
|
18678
|
+
work[W(n - 1 + i)] = s;
|
|
18679
|
+
}
|
|
18680
|
+
}
|
|
18681
|
+
if (compz > 0) {
|
|
18682
|
+
const mm = l - m + 1;
|
|
18683
|
+
dlasr(
|
|
18684
|
+
RIGHT,
|
|
18685
|
+
PIVOT_V,
|
|
18686
|
+
DIRECT_F,
|
|
18687
|
+
n,
|
|
18688
|
+
mm,
|
|
18689
|
+
work,
|
|
18690
|
+
W(m),
|
|
18691
|
+
work,
|
|
18692
|
+
W(n - 1 + m),
|
|
18693
|
+
z,
|
|
18694
|
+
Zc(m),
|
|
18695
|
+
ldz
|
|
18696
|
+
);
|
|
18697
|
+
}
|
|
18698
|
+
d[D(l)] = d[D(l)] - p2;
|
|
18699
|
+
e[E(l - 1)] = g;
|
|
18700
|
+
continue qr;
|
|
18701
|
+
}
|
|
18702
|
+
}
|
|
18703
|
+
if (iscale === 1) {
|
|
18704
|
+
dlascl(TYPE_G3, 0, 0, ssfmax, anorm, lendsv - lsv + 1, 1, d, D(lsv), n);
|
|
18705
|
+
dlascl(TYPE_G3, 0, 0, ssfmax, anorm, lendsv - lsv, 1, e, E(lsv), n);
|
|
18706
|
+
} else if (iscale === 2) {
|
|
18707
|
+
dlascl(TYPE_G3, 0, 0, ssfmin, anorm, lendsv - lsv + 1, 1, d, D(lsv), n);
|
|
18708
|
+
dlascl(TYPE_G3, 0, 0, ssfmin, anorm, lendsv - lsv, 1, e, E(lsv), n);
|
|
18709
|
+
}
|
|
18710
|
+
if (jtot < nmaxit) continue outer;
|
|
18711
|
+
for (let i = 1; i <= n - 1; i++) {
|
|
18712
|
+
if (e[E(i)] !== ZERO9) info = info + 1;
|
|
18713
|
+
}
|
|
18714
|
+
break outer;
|
|
18715
|
+
}
|
|
18716
|
+
if (!ordered) return info;
|
|
18717
|
+
if (compz === COMPZ_N) {
|
|
18718
|
+
const sortInfo = dlasrt(SORT_INC, n, d, dOff);
|
|
18719
|
+
if (sortInfo !== 0) return sortInfo;
|
|
18720
|
+
} else {
|
|
18721
|
+
for (let ii = 2; ii <= n; ii++) {
|
|
18722
|
+
const i = ii - 1;
|
|
18723
|
+
let k = i;
|
|
18724
|
+
let p2 = d[D(i)];
|
|
18725
|
+
for (let j = ii; j <= n; j++) {
|
|
18726
|
+
if (d[D(j)] < p2) {
|
|
18727
|
+
k = j;
|
|
18728
|
+
p2 = d[D(j)];
|
|
18729
|
+
}
|
|
18730
|
+
}
|
|
18731
|
+
if (k !== i) {
|
|
18732
|
+
d[D(k)] = d[D(i)];
|
|
18733
|
+
d[D(i)] = p2;
|
|
18734
|
+
dswap(n, z, Zc(i), 1, z, Zc(k), 1);
|
|
18735
|
+
}
|
|
18736
|
+
}
|
|
18737
|
+
}
|
|
18738
|
+
return info;
|
|
18739
|
+
}
|
|
18740
|
+
|
|
18741
|
+
// src/numbl-core/native/ts-lapack-eig-hermitian.ts
|
|
18742
|
+
var EPS2 = 2220446049250313e-31;
|
|
18743
|
+
var SAFMIN2 = 22250738585072014e-324;
|
|
18744
|
+
function dlapy3(x, y, z) {
|
|
18745
|
+
const w = Math.max(Math.abs(x), Math.abs(y), Math.abs(z));
|
|
18746
|
+
if (w === 0 || !Number.isFinite(w))
|
|
18747
|
+
return Math.abs(x) + Math.abs(y) + Math.abs(z);
|
|
18748
|
+
return w * Math.sqrt((x / w) ** 2 + (y / w) ** 2 + (z / w) ** 2);
|
|
18749
|
+
}
|
|
18750
|
+
function fsign7(mag2, s) {
|
|
18751
|
+
return s >= 0 ? Math.abs(mag2) : -Math.abs(mag2);
|
|
18752
|
+
}
|
|
18753
|
+
function cdiv2(ar, ai, br, bi) {
|
|
18754
|
+
if (Math.abs(br) >= Math.abs(bi)) {
|
|
18755
|
+
const r2 = bi / br;
|
|
18756
|
+
const t2 = br + bi * r2;
|
|
18757
|
+
return [(ar + ai * r2) / t2, (ai - ar * r2) / t2];
|
|
18758
|
+
}
|
|
18759
|
+
const r = br / bi;
|
|
18760
|
+
const t = br * r + bi;
|
|
18761
|
+
return [(ar * r + ai) / t, (ai * r - ar) / t];
|
|
18762
|
+
}
|
|
18763
|
+
function dznrm2(n, re, im, off, incx) {
|
|
18764
|
+
let scale = 0;
|
|
18765
|
+
let ssq = 1;
|
|
18766
|
+
for (let i = 0, k = off; i < n; i++, k += incx) {
|
|
18767
|
+
for (const v of [re[k], im[k]]) {
|
|
18768
|
+
if (v !== 0) {
|
|
18769
|
+
const a = Math.abs(v);
|
|
18770
|
+
if (scale < a) {
|
|
18771
|
+
ssq = 1 + ssq * (scale / a) ** 2;
|
|
18772
|
+
scale = a;
|
|
18773
|
+
} else {
|
|
18774
|
+
ssq += (a / scale) ** 2;
|
|
18775
|
+
}
|
|
18776
|
+
}
|
|
18777
|
+
}
|
|
18778
|
+
}
|
|
18779
|
+
return scale * Math.sqrt(ssq);
|
|
18780
|
+
}
|
|
18781
|
+
function zlarfg2(n, re, im, off, incx) {
|
|
18782
|
+
if (n <= 0) return { tauRe: 0, tauIm: 0 };
|
|
18783
|
+
let xnorm = dznrm2(n - 1, re, im, off + incx, incx);
|
|
18784
|
+
let alphr = re[off];
|
|
18785
|
+
let alphi = im[off];
|
|
18786
|
+
if (xnorm === 0 && alphi === 0) {
|
|
18787
|
+
return { tauRe: 0, tauIm: 0 };
|
|
18788
|
+
}
|
|
18789
|
+
let beta = -fsign7(dlapy3(alphr, alphi, xnorm), alphr);
|
|
18790
|
+
const safmin = SAFMIN2 / EPS2;
|
|
18791
|
+
const rsafmn = 1 / safmin;
|
|
18792
|
+
let knt = 0;
|
|
18793
|
+
if (Math.abs(beta) < safmin) {
|
|
18794
|
+
do {
|
|
18795
|
+
knt++;
|
|
18796
|
+
for (let i = 1, k = off + incx; i < n; i++, k += incx) {
|
|
18797
|
+
re[k] *= rsafmn;
|
|
18798
|
+
im[k] *= rsafmn;
|
|
18799
|
+
}
|
|
18800
|
+
beta *= rsafmn;
|
|
18801
|
+
alphi *= rsafmn;
|
|
18802
|
+
alphr *= rsafmn;
|
|
18803
|
+
} while (Math.abs(beta) < safmin && knt < 20);
|
|
18804
|
+
xnorm = dznrm2(n - 1, re, im, off + incx, incx);
|
|
18805
|
+
beta = -fsign7(dlapy3(alphr, alphi, xnorm), alphr);
|
|
18806
|
+
}
|
|
18807
|
+
const tauRe = (beta - alphr) / beta;
|
|
18808
|
+
const tauIm = -alphi / beta;
|
|
18809
|
+
const [sr, si] = cdiv2(1, 0, alphr - beta, alphi);
|
|
18810
|
+
for (let i = 1, k = off + incx; i < n; i++, k += incx) {
|
|
18811
|
+
const xr = re[k];
|
|
18812
|
+
const xi = im[k];
|
|
18813
|
+
re[k] = xr * sr - xi * si;
|
|
18814
|
+
im[k] = xr * si + xi * sr;
|
|
18815
|
+
}
|
|
18816
|
+
for (let j = 1; j <= knt; j++) beta *= safmin;
|
|
18817
|
+
re[off] = beta;
|
|
18818
|
+
im[off] = 0;
|
|
18819
|
+
return { tauRe, tauIm };
|
|
18820
|
+
}
|
|
18821
|
+
function zhemvLower(n, alphaRe, alphaIm, aRe, aIm, aOff, lda, xRe, xIm, xOff, yRe, yIm, yOff) {
|
|
18822
|
+
for (let i = 0; i < n; i++) {
|
|
18823
|
+
yRe[yOff + i] = 0;
|
|
18824
|
+
yIm[yOff + i] = 0;
|
|
18825
|
+
}
|
|
18826
|
+
for (let j = 0; j < n; j++) {
|
|
18827
|
+
const xjr = xRe[xOff + j];
|
|
18828
|
+
const xji = xIm[xOff + j];
|
|
18829
|
+
const t1r = alphaRe * xjr - alphaIm * xji;
|
|
18830
|
+
const t1i = alphaRe * xji + alphaIm * xjr;
|
|
18831
|
+
let t2r = 0;
|
|
18832
|
+
let t2i = 0;
|
|
18833
|
+
const col = aOff + j * lda;
|
|
18834
|
+
yRe[yOff + j] += t1r * aRe[col + j];
|
|
18835
|
+
yIm[yOff + j] += t1i * aRe[col + j];
|
|
18836
|
+
for (let i = j + 1; i < n; i++) {
|
|
18837
|
+
const ar = aRe[col + i];
|
|
18838
|
+
const ai = aIm[col + i];
|
|
18839
|
+
yRe[yOff + i] += t1r * ar - t1i * ai;
|
|
18840
|
+
yIm[yOff + i] += t1r * ai + t1i * ar;
|
|
18841
|
+
const xir = xRe[xOff + i];
|
|
18842
|
+
const xii = xIm[xOff + i];
|
|
18843
|
+
t2r += ar * xir + ai * xii;
|
|
18844
|
+
t2i += ar * xii - ai * xir;
|
|
18845
|
+
}
|
|
18846
|
+
yRe[yOff + j] += alphaRe * t2r - alphaIm * t2i;
|
|
18847
|
+
yIm[yOff + j] += alphaRe * t2i + alphaIm * t2r;
|
|
18848
|
+
}
|
|
18849
|
+
}
|
|
18850
|
+
function zher2LowerMinus(n, xRe, xIm, xOff, yRe, yIm, yOff, aRe, aIm, aOff, lda) {
|
|
18851
|
+
for (let j = 0; j < n; j++) {
|
|
18852
|
+
const xjr = xRe[xOff + j];
|
|
18853
|
+
const xji = xIm[xOff + j];
|
|
18854
|
+
const yjr = yRe[yOff + j];
|
|
18855
|
+
const yji = yIm[yOff + j];
|
|
18856
|
+
const col = aOff + j * lda;
|
|
18857
|
+
if (xjr !== 0 || xji !== 0 || yjr !== 0 || yji !== 0) {
|
|
18858
|
+
const t1r = -yjr;
|
|
18859
|
+
const t1i = yji;
|
|
18860
|
+
const t2r = -xjr;
|
|
18861
|
+
const t2i = xji;
|
|
18862
|
+
aRe[col + j] = aRe[col + j] + (xjr * t1r - xji * t1i) + (yjr * t2r - yji * t2i);
|
|
18863
|
+
aIm[col + j] = 0;
|
|
18864
|
+
for (let i = j + 1; i < n; i++) {
|
|
18865
|
+
const xir = xRe[xOff + i];
|
|
18866
|
+
const xii = xIm[xOff + i];
|
|
18867
|
+
const yir = yRe[yOff + i];
|
|
18868
|
+
const yii = yIm[yOff + i];
|
|
18869
|
+
aRe[col + i] += xir * t1r - xii * t1i + (yir * t2r - yii * t2i);
|
|
18870
|
+
aIm[col + i] += xir * t1i + xii * t1r + (yir * t2i + yii * t2r);
|
|
18871
|
+
}
|
|
18872
|
+
} else {
|
|
18873
|
+
aIm[col + j] = 0;
|
|
18874
|
+
}
|
|
18875
|
+
}
|
|
18876
|
+
}
|
|
18877
|
+
function zhetd2Lower(n, aRe, aIm, lda, d, e, tauRe, tauIm) {
|
|
18878
|
+
const wRe = allocFloat64Array(Math.max(1, n));
|
|
18879
|
+
const wIm = allocFloat64Array(Math.max(1, n));
|
|
18880
|
+
for (let i = 1; i <= n - 1; i++) {
|
|
18881
|
+
const off = i + (i - 1) * lda;
|
|
18882
|
+
const t = zlarfg2(n - i, aRe, aIm, off, 1);
|
|
18883
|
+
e[i - 1] = aRe[off];
|
|
18884
|
+
const taur = t.tauRe;
|
|
18885
|
+
const taui = t.tauIm;
|
|
18886
|
+
if (taur !== 0 || taui !== 0) {
|
|
18887
|
+
aRe[off] = 1;
|
|
18888
|
+
aIm[off] = 0;
|
|
18889
|
+
const m = n - i;
|
|
18890
|
+
const a11 = i + i * lda;
|
|
18891
|
+
zhemvLower(m, taur, taui, aRe, aIm, a11, lda, aRe, aIm, off, wRe, wIm, 0);
|
|
18892
|
+
let dr = 0;
|
|
18893
|
+
let di = 0;
|
|
18894
|
+
for (let k = 0; k < m; k++) {
|
|
18895
|
+
const vr = aRe[off + k];
|
|
18896
|
+
const vi = aIm[off + k];
|
|
18897
|
+
dr += wRe[k] * vr + wIm[k] * vi;
|
|
18898
|
+
di += wRe[k] * vi - wIm[k] * vr;
|
|
18899
|
+
}
|
|
18900
|
+
const ar = -0.5 * (taur * dr - taui * di);
|
|
18901
|
+
const ai = -0.5 * (taur * di + taui * dr);
|
|
18902
|
+
for (let k = 0; k < m; k++) {
|
|
18903
|
+
const vr = aRe[off + k];
|
|
18904
|
+
const vi = aIm[off + k];
|
|
18905
|
+
wRe[k] += ar * vr - ai * vi;
|
|
18906
|
+
wIm[k] += ar * vi + ai * vr;
|
|
18907
|
+
}
|
|
18908
|
+
zher2LowerMinus(m, aRe, aIm, off, wRe, wIm, 0, aRe, aIm, a11, lda);
|
|
18909
|
+
} else {
|
|
18910
|
+
const a11 = i + i * lda;
|
|
18911
|
+
aIm[a11] = 0;
|
|
18912
|
+
}
|
|
18913
|
+
aRe[off] = e[i - 1];
|
|
18914
|
+
aIm[off] = 0;
|
|
18915
|
+
d[i - 1] = aRe[i - 1 + (i - 1) * lda];
|
|
18916
|
+
tauRe[i - 1] = taur;
|
|
18917
|
+
tauIm[i - 1] = taui;
|
|
18918
|
+
}
|
|
18919
|
+
d[n - 1] = aRe[n - 1 + (n - 1) * lda];
|
|
18920
|
+
}
|
|
18921
|
+
function zungtrLower(n, aRe, aIm, lda, tauRe, tauIm) {
|
|
18922
|
+
for (let j = n; j >= 2; j--) {
|
|
18923
|
+
aRe[(j - 1) * lda] = 0;
|
|
18924
|
+
aIm[(j - 1) * lda] = 0;
|
|
18925
|
+
for (let i = j + 1; i <= n; i++) {
|
|
18926
|
+
aRe[i - 1 + (j - 1) * lda] = aRe[i - 1 + (j - 2) * lda];
|
|
18927
|
+
aIm[i - 1 + (j - 1) * lda] = aIm[i - 1 + (j - 2) * lda];
|
|
18928
|
+
}
|
|
18929
|
+
}
|
|
18930
|
+
aRe[0] = 1;
|
|
18931
|
+
aIm[0] = 0;
|
|
18932
|
+
for (let i = 2; i <= n; i++) {
|
|
18933
|
+
aRe[i - 1] = 0;
|
|
18934
|
+
aIm[i - 1] = 0;
|
|
18935
|
+
}
|
|
18936
|
+
if (n <= 1) return;
|
|
18937
|
+
const m = n - 1;
|
|
18938
|
+
const base = 1 + lda;
|
|
18939
|
+
const workRe = allocFloat64Array(Math.max(1, m));
|
|
18940
|
+
const workIm = allocFloat64Array(Math.max(1, m));
|
|
18941
|
+
for (let i = m; i >= 1; i--) {
|
|
18942
|
+
const vOff = base + (i - 1) + (i - 1) * lda;
|
|
18943
|
+
const tr = tauRe[i - 1];
|
|
18944
|
+
const ti = tauIm[i - 1];
|
|
18945
|
+
if (i < m) {
|
|
18946
|
+
aRe[vOff] = 1;
|
|
18947
|
+
aIm[vOff] = 0;
|
|
18948
|
+
const rows = m - i + 1;
|
|
18949
|
+
const cols = m - i;
|
|
18950
|
+
const cOff = base + (i - 1) + i * lda;
|
|
18951
|
+
for (let j = 0; j < cols; j++) {
|
|
18952
|
+
let sr = 0;
|
|
18953
|
+
let si = 0;
|
|
18954
|
+
for (let k = 0; k < rows; k++) {
|
|
18955
|
+
const cr = aRe[cOff + k + j * lda];
|
|
18956
|
+
const ci = aIm[cOff + k + j * lda];
|
|
18957
|
+
const vr = aRe[vOff + k];
|
|
18958
|
+
const vi = aIm[vOff + k];
|
|
18959
|
+
sr += cr * vr + ci * vi;
|
|
18960
|
+
si += cr * vi - ci * vr;
|
|
18961
|
+
}
|
|
18962
|
+
workRe[j] = sr;
|
|
18963
|
+
workIm[j] = si;
|
|
18964
|
+
}
|
|
18965
|
+
for (let j = 0; j < cols; j++) {
|
|
18966
|
+
const wr = workRe[j];
|
|
18967
|
+
const wi = -workIm[j];
|
|
18968
|
+
const fr = -(tr * wr - ti * wi);
|
|
18969
|
+
const fi = -(tr * wi + ti * wr);
|
|
18970
|
+
for (let k = 0; k < rows; k++) {
|
|
18971
|
+
const vr = aRe[vOff + k];
|
|
18972
|
+
const vi = aIm[vOff + k];
|
|
18973
|
+
aRe[cOff + k + j * lda] += fr * vr - fi * vi;
|
|
18974
|
+
aIm[cOff + k + j * lda] += fr * vi + fi * vr;
|
|
18975
|
+
}
|
|
18976
|
+
}
|
|
18977
|
+
}
|
|
18978
|
+
if (i < m) {
|
|
18979
|
+
for (let k = 1; k <= m - i; k++) {
|
|
18980
|
+
const vr = aRe[vOff + k];
|
|
18981
|
+
const vi = aIm[vOff + k];
|
|
18982
|
+
aRe[vOff + k] = -(tr * vr - ti * vi);
|
|
18983
|
+
aIm[vOff + k] = -(tr * vi + ti * vr);
|
|
18984
|
+
}
|
|
18985
|
+
}
|
|
18986
|
+
aRe[vOff] = 1 - tr;
|
|
18987
|
+
aIm[vOff] = -ti;
|
|
18988
|
+
for (let k = 1; k <= i - 1; k++) {
|
|
18989
|
+
aRe[base + (k - 1) + (i - 1) * lda] = 0;
|
|
18990
|
+
aIm[base + (k - 1) + (i - 1) * lda] = 0;
|
|
18991
|
+
}
|
|
18992
|
+
}
|
|
18993
|
+
}
|
|
18994
|
+
function eigHermTs(dataRe, dataIm, n, computeV) {
|
|
18995
|
+
const w = allocFloat64Array(n);
|
|
18996
|
+
if (n === 0)
|
|
18997
|
+
return { w, VRe: allocFloat64Array(0), VIm: allocFloat64Array(0) };
|
|
18998
|
+
if (n === 1) {
|
|
18999
|
+
w[0] = dataRe[0];
|
|
19000
|
+
if (!computeV) return { w };
|
|
19001
|
+
const VRe2 = allocFloat64Array(1);
|
|
19002
|
+
VRe2[0] = 1;
|
|
19003
|
+
return { w, VRe: VRe2, VIm: allocFloat64Array(1) };
|
|
19004
|
+
}
|
|
19005
|
+
const aRe = allocFloat64Array(dataRe);
|
|
19006
|
+
const aIm = allocFloat64Array(dataIm);
|
|
19007
|
+
const e = allocFloat64Array(Math.max(1, n - 1));
|
|
19008
|
+
const tauRe = allocFloat64Array(Math.max(1, n - 1));
|
|
19009
|
+
const tauIm = allocFloat64Array(Math.max(1, n - 1));
|
|
19010
|
+
zhetd2Lower(n, aRe, aIm, n, w, e, tauRe, tauIm);
|
|
19011
|
+
if (!computeV) {
|
|
19012
|
+
const work2 = allocFloat64Array(Math.max(1, 2 * n - 2));
|
|
19013
|
+
const dummy = allocFloat64Array(1);
|
|
19014
|
+
dsteqr(COMPZ_N, n, w, 0, e, 0, dummy, 0, 1, work2, 0);
|
|
19015
|
+
return { w };
|
|
19016
|
+
}
|
|
19017
|
+
zungtrLower(n, aRe, aIm, n, tauRe, tauIm);
|
|
19018
|
+
const S = allocFloat64Array(n * n);
|
|
19019
|
+
const work = allocFloat64Array(Math.max(1, 2 * n - 2));
|
|
19020
|
+
dsteqr(COMPZ_I, n, w, 0, e, 0, S, 0, n, work, 0);
|
|
19021
|
+
const VRe = allocFloat64Array(n * n);
|
|
19022
|
+
const VIm = allocFloat64Array(n * n);
|
|
19023
|
+
for (let j = 0; j < n; j++) {
|
|
19024
|
+
for (let k = 0; k < n; k++) {
|
|
19025
|
+
const s = S[k + j * n];
|
|
19026
|
+
if (s === 0) continue;
|
|
19027
|
+
for (let i = 0; i < n; i++) {
|
|
19028
|
+
VRe[i + j * n] += aRe[i + k * n] * s;
|
|
19029
|
+
VIm[i + j * n] += aIm[i + k * n] * s;
|
|
19030
|
+
}
|
|
19031
|
+
}
|
|
19032
|
+
}
|
|
19033
|
+
return { w, VRe, VIm };
|
|
19034
|
+
}
|
|
19035
|
+
|
|
19036
|
+
// src/ts-lapack/src/SRC/dlansy.ts
|
|
19037
|
+
var NORM_MAX7 = 0;
|
|
19038
|
+
var NORM_ONE3 = 1;
|
|
19039
|
+
var NORM_INF3 = 2;
|
|
19040
|
+
var NORM_FRO3 = 3;
|
|
19041
|
+
function dlansy(norm2, uplo, n, a, aOff, lda, work, workOff) {
|
|
19042
|
+
let value = 0;
|
|
19043
|
+
if (n === 0) {
|
|
19044
|
+
value = 0;
|
|
19045
|
+
} else if (norm2 === NORM_MAX7) {
|
|
19046
|
+
value = 0;
|
|
19047
|
+
if (uplo === UPPER) {
|
|
19048
|
+
for (let j = 1; j <= n; j++) {
|
|
19049
|
+
for (let i = 1; i <= j; i++) {
|
|
19050
|
+
const sum2 = Math.abs(a[aOff + (i - 1) + (j - 1) * lda]);
|
|
19051
|
+
if (value < sum2 || Number.isNaN(sum2)) value = sum2;
|
|
19052
|
+
}
|
|
19053
|
+
}
|
|
19054
|
+
} else {
|
|
19055
|
+
for (let j = 1; j <= n; j++) {
|
|
19056
|
+
for (let i = j; i <= n; i++) {
|
|
19057
|
+
const sum2 = Math.abs(a[aOff + (i - 1) + (j - 1) * lda]);
|
|
19058
|
+
if (value < sum2 || Number.isNaN(sum2)) value = sum2;
|
|
19059
|
+
}
|
|
19060
|
+
}
|
|
19061
|
+
}
|
|
19062
|
+
} else if (norm2 === NORM_ONE3 || norm2 === NORM_INF3) {
|
|
19063
|
+
value = 0;
|
|
19064
|
+
if (uplo === UPPER) {
|
|
19065
|
+
for (let j = 1; j <= n; j++) {
|
|
19066
|
+
let sum2 = 0;
|
|
19067
|
+
for (let i = 1; i <= j - 1; i++) {
|
|
19068
|
+
const absa = Math.abs(a[aOff + (i - 1) + (j - 1) * lda]);
|
|
19069
|
+
sum2 += absa;
|
|
19070
|
+
work[workOff + (i - 1)] += absa;
|
|
19071
|
+
}
|
|
19072
|
+
work[workOff + (j - 1)] = sum2 + Math.abs(a[aOff + (j - 1) + (j - 1) * lda]);
|
|
19073
|
+
}
|
|
19074
|
+
for (let i = 1; i <= n; i++) {
|
|
19075
|
+
const sum2 = work[workOff + (i - 1)];
|
|
19076
|
+
if (value < sum2 || Number.isNaN(sum2)) value = sum2;
|
|
19077
|
+
}
|
|
19078
|
+
} else {
|
|
19079
|
+
for (let i = 1; i <= n; i++) work[workOff + (i - 1)] = 0;
|
|
19080
|
+
for (let j = 1; j <= n; j++) {
|
|
19081
|
+
let sum2 = work[workOff + (j - 1)] + Math.abs(a[aOff + (j - 1) + (j - 1) * lda]);
|
|
19082
|
+
for (let i = j + 1; i <= n; i++) {
|
|
19083
|
+
const absa = Math.abs(a[aOff + (i - 1) + (j - 1) * lda]);
|
|
19084
|
+
sum2 += absa;
|
|
19085
|
+
work[workOff + (i - 1)] += absa;
|
|
19086
|
+
}
|
|
19087
|
+
if (value < sum2 || Number.isNaN(sum2)) value = sum2;
|
|
19088
|
+
}
|
|
19089
|
+
}
|
|
19090
|
+
} else if (norm2 === NORM_FRO3) {
|
|
19091
|
+
const scale = { val: 0 };
|
|
19092
|
+
const sum2 = { val: 1 };
|
|
19093
|
+
if (uplo === UPPER) {
|
|
19094
|
+
for (let j = 2; j <= n; j++) {
|
|
19095
|
+
dlassq(j - 1, a, aOff + (j - 1) * lda, 1, scale, sum2);
|
|
19096
|
+
}
|
|
19097
|
+
} else {
|
|
19098
|
+
for (let j = 1; j <= n - 1; j++) {
|
|
19099
|
+
dlassq(n - j, a, aOff + j + (j - 1) * lda, 1, scale, sum2);
|
|
19100
|
+
}
|
|
19101
|
+
}
|
|
19102
|
+
sum2.val = 2 * sum2.val;
|
|
19103
|
+
dlassq(n, a, aOff, lda + 1, scale, sum2);
|
|
19104
|
+
value = scale.val * Math.sqrt(sum2.val);
|
|
19105
|
+
}
|
|
19106
|
+
return value;
|
|
19107
|
+
}
|
|
19108
|
+
|
|
19109
|
+
// src/ts-lapack/src/BLAS/dsymv.ts
|
|
19110
|
+
function dsymv(uplo, n, alpha, a, aOff, lda, x, xOff, incx, beta, y, yOff, incy) {
|
|
19111
|
+
const ZERO9 = 0;
|
|
19112
|
+
const ONE10 = 1;
|
|
19113
|
+
let info = 0;
|
|
19114
|
+
if (uplo !== UPPER && uplo !== LOWER) {
|
|
19115
|
+
info = 1;
|
|
19116
|
+
} else if (n < 0) {
|
|
19117
|
+
info = 2;
|
|
19118
|
+
} else if (lda < Math.max(1, n)) {
|
|
19119
|
+
info = 5;
|
|
19120
|
+
} else if (incx === 0) {
|
|
19121
|
+
info = 7;
|
|
19122
|
+
} else if (incy === 0) {
|
|
19123
|
+
info = 10;
|
|
19124
|
+
}
|
|
19125
|
+
if (info !== 0) {
|
|
19126
|
+
xerbla("DSYMV ", info);
|
|
19127
|
+
return;
|
|
19128
|
+
}
|
|
19129
|
+
if (n === 0 || alpha === ZERO9 && beta === ONE10) return;
|
|
19130
|
+
const kx = incx > 0 ? 0 : -(n - 1) * incx;
|
|
19131
|
+
const ky = incy > 0 ? 0 : -(n - 1) * incy;
|
|
19132
|
+
if (beta !== ONE10) {
|
|
19133
|
+
let iy = ky;
|
|
19134
|
+
if (beta === ZERO9) {
|
|
19135
|
+
for (let i = 0; i < n; i++) {
|
|
19136
|
+
y[yOff + iy] = ZERO9;
|
|
19137
|
+
iy += incy;
|
|
19138
|
+
}
|
|
19139
|
+
} else {
|
|
19140
|
+
for (let i = 0; i < n; i++) {
|
|
19141
|
+
y[yOff + iy] *= beta;
|
|
19142
|
+
iy += incy;
|
|
19143
|
+
}
|
|
19144
|
+
}
|
|
19145
|
+
}
|
|
19146
|
+
if (alpha === ZERO9) return;
|
|
19147
|
+
if (uplo === UPPER) {
|
|
19148
|
+
let jx = kx;
|
|
19149
|
+
let jy = ky;
|
|
19150
|
+
for (let j = 1; j <= n; j++) {
|
|
19151
|
+
const temp1 = alpha * x[xOff + jx];
|
|
19152
|
+
let temp2 = ZERO9;
|
|
19153
|
+
const aCol = aOff + (j - 1) * lda;
|
|
19154
|
+
let ix = kx;
|
|
19155
|
+
let iy = ky;
|
|
19156
|
+
for (let i = 1; i <= j - 1; i++) {
|
|
19157
|
+
const aij = a[aCol + (i - 1)];
|
|
19158
|
+
y[yOff + iy] += temp1 * aij;
|
|
19159
|
+
temp2 += aij * x[xOff + ix];
|
|
19160
|
+
ix += incx;
|
|
19161
|
+
iy += incy;
|
|
19162
|
+
}
|
|
19163
|
+
y[yOff + jy] += temp1 * a[aCol + (j - 1)] + alpha * temp2;
|
|
19164
|
+
jx += incx;
|
|
19165
|
+
jy += incy;
|
|
19166
|
+
}
|
|
19167
|
+
} else {
|
|
19168
|
+
let jx = kx;
|
|
19169
|
+
let jy = ky;
|
|
19170
|
+
for (let j = 1; j <= n; j++) {
|
|
19171
|
+
const temp1 = alpha * x[xOff + jx];
|
|
19172
|
+
let temp2 = ZERO9;
|
|
19173
|
+
const aCol = aOff + (j - 1) * lda;
|
|
19174
|
+
y[yOff + jy] += temp1 * a[aCol + (j - 1)];
|
|
19175
|
+
let ix = jx;
|
|
19176
|
+
let iy = jy;
|
|
19177
|
+
for (let i = j + 1; i <= n; i++) {
|
|
19178
|
+
ix += incx;
|
|
19179
|
+
iy += incy;
|
|
19180
|
+
const aij = a[aCol + (i - 1)];
|
|
19181
|
+
y[yOff + iy] += temp1 * aij;
|
|
19182
|
+
temp2 += aij * x[xOff + ix];
|
|
19183
|
+
}
|
|
19184
|
+
y[yOff + jy] += alpha * temp2;
|
|
19185
|
+
jx += incx;
|
|
19186
|
+
jy += incy;
|
|
19187
|
+
}
|
|
19188
|
+
}
|
|
19189
|
+
}
|
|
19190
|
+
|
|
19191
|
+
// src/ts-lapack/src/BLAS/dsyr2.ts
|
|
19192
|
+
function dsyr2(uplo, n, alpha, x, xOff, incx, y, yOff, incy, a, aOff, lda) {
|
|
19193
|
+
const ZERO9 = 0;
|
|
19194
|
+
let info = 0;
|
|
19195
|
+
if (uplo !== UPPER && uplo !== LOWER) {
|
|
19196
|
+
info = 1;
|
|
19197
|
+
} else if (n < 0) {
|
|
19198
|
+
info = 2;
|
|
19199
|
+
} else if (incx === 0) {
|
|
19200
|
+
info = 5;
|
|
19201
|
+
} else if (incy === 0) {
|
|
19202
|
+
info = 7;
|
|
19203
|
+
} else if (lda < Math.max(1, n)) {
|
|
19204
|
+
info = 9;
|
|
19205
|
+
}
|
|
19206
|
+
if (info !== 0) {
|
|
19207
|
+
xerbla("DSYR2 ", info);
|
|
19208
|
+
return;
|
|
19209
|
+
}
|
|
19210
|
+
if (n === 0 || alpha === ZERO9) return;
|
|
19211
|
+
const kx = incx > 0 ? 0 : -(n - 1) * incx;
|
|
19212
|
+
const ky = incy > 0 ? 0 : -(n - 1) * incy;
|
|
19213
|
+
let jx = kx;
|
|
19214
|
+
let jy = ky;
|
|
19215
|
+
if (uplo === UPPER) {
|
|
19216
|
+
for (let j = 1; j <= n; j++) {
|
|
19217
|
+
const xj = x[xOff + jx];
|
|
19218
|
+
const yj = y[yOff + jy];
|
|
19219
|
+
if (xj !== ZERO9 || yj !== ZERO9) {
|
|
19220
|
+
const temp1 = alpha * yj;
|
|
19221
|
+
const temp2 = alpha * xj;
|
|
19222
|
+
const aCol = aOff + (j - 1) * lda;
|
|
19223
|
+
let ix = kx;
|
|
19224
|
+
let iy = ky;
|
|
19225
|
+
for (let i = 1; i <= j; i++) {
|
|
19226
|
+
a[aCol + (i - 1)] += x[xOff + ix] * temp1 + y[yOff + iy] * temp2;
|
|
19227
|
+
ix += incx;
|
|
19228
|
+
iy += incy;
|
|
19229
|
+
}
|
|
19230
|
+
}
|
|
19231
|
+
jx += incx;
|
|
19232
|
+
jy += incy;
|
|
19233
|
+
}
|
|
19234
|
+
} else {
|
|
19235
|
+
for (let j = 1; j <= n; j++) {
|
|
19236
|
+
const xj = x[xOff + jx];
|
|
19237
|
+
const yj = y[yOff + jy];
|
|
19238
|
+
if (xj !== ZERO9 || yj !== ZERO9) {
|
|
19239
|
+
const temp1 = alpha * yj;
|
|
19240
|
+
const temp2 = alpha * xj;
|
|
19241
|
+
const aCol = aOff + (j - 1) * lda;
|
|
19242
|
+
let ix = jx;
|
|
19243
|
+
let iy = jy;
|
|
19244
|
+
for (let i = j; i <= n; i++) {
|
|
19245
|
+
a[aCol + (i - 1)] += x[xOff + ix] * temp1 + y[yOff + iy] * temp2;
|
|
19246
|
+
ix += incx;
|
|
19247
|
+
iy += incy;
|
|
19248
|
+
}
|
|
19249
|
+
}
|
|
19250
|
+
jx += incx;
|
|
19251
|
+
jy += incy;
|
|
19252
|
+
}
|
|
19253
|
+
}
|
|
19254
|
+
}
|
|
19255
|
+
|
|
19256
|
+
// src/ts-lapack/src/SRC/dsytd2.ts
|
|
19257
|
+
function dsytd2(uplo, n, a, aOff, lda, d, dOff, e, eOff, tau, tauOff) {
|
|
19258
|
+
const ONE10 = 1;
|
|
19259
|
+
const ZERO9 = 0;
|
|
19260
|
+
const HALF = 0.5;
|
|
19261
|
+
let info = 0;
|
|
19262
|
+
const upper = uplo === UPPER;
|
|
19263
|
+
if (!upper && uplo !== LOWER) {
|
|
19264
|
+
info = -1;
|
|
19265
|
+
} else if (n < 0) {
|
|
19266
|
+
info = -2;
|
|
19267
|
+
} else if (lda < Math.max(1, n)) {
|
|
19268
|
+
info = -4;
|
|
19269
|
+
}
|
|
19270
|
+
if (info !== 0) {
|
|
19271
|
+
xerbla("DSYTD2", -info);
|
|
19272
|
+
return info;
|
|
19273
|
+
}
|
|
19274
|
+
if (n <= 0) return 0;
|
|
19275
|
+
const A = (i, j) => aOff + (i - 1) + (j - 1) * lda;
|
|
19276
|
+
if (upper) {
|
|
19277
|
+
for (let i = n - 1; i >= 1; i--) {
|
|
19278
|
+
const r = dlarfg(i, a[A(i, i + 1)], a, A(1, i + 1), 1);
|
|
19279
|
+
a[A(i, i + 1)] = r.alpha;
|
|
19280
|
+
const taui = r.tau;
|
|
19281
|
+
e[eOff + (i - 1)] = a[A(i, i + 1)];
|
|
19282
|
+
if (taui !== ZERO9) {
|
|
19283
|
+
a[A(i, i + 1)] = ONE10;
|
|
19284
|
+
dsymv(
|
|
19285
|
+
uplo,
|
|
19286
|
+
i,
|
|
19287
|
+
taui,
|
|
19288
|
+
a,
|
|
19289
|
+
aOff,
|
|
19290
|
+
lda,
|
|
19291
|
+
a,
|
|
19292
|
+
A(1, i + 1),
|
|
19293
|
+
1,
|
|
19294
|
+
ZERO9,
|
|
19295
|
+
tau,
|
|
19296
|
+
tauOff,
|
|
19297
|
+
1
|
|
19298
|
+
);
|
|
19299
|
+
const alpha = -HALF * taui * ddot(i, tau, tauOff, 1, a, A(1, i + 1), 1);
|
|
19300
|
+
daxpy(i, alpha, a, A(1, i + 1), 1, tau, tauOff, 1);
|
|
19301
|
+
dsyr2(uplo, i, -ONE10, a, A(1, i + 1), 1, tau, tauOff, 1, a, aOff, lda);
|
|
19302
|
+
a[A(i, i + 1)] = e[eOff + (i - 1)];
|
|
19303
|
+
}
|
|
19304
|
+
d[dOff + i] = a[A(i + 1, i + 1)];
|
|
19305
|
+
tau[tauOff + (i - 1)] = taui;
|
|
19306
|
+
}
|
|
19307
|
+
d[dOff] = a[A(1, 1)];
|
|
19308
|
+
} else {
|
|
19309
|
+
for (let i = 1; i <= n - 1; i++) {
|
|
19310
|
+
const r = dlarfg(n - i, a[A(i + 1, i)], a, A(Math.min(i + 2, n), i), 1);
|
|
19311
|
+
a[A(i + 1, i)] = r.alpha;
|
|
19312
|
+
const taui = r.tau;
|
|
19313
|
+
e[eOff + (i - 1)] = a[A(i + 1, i)];
|
|
19314
|
+
if (taui !== ZERO9) {
|
|
19315
|
+
a[A(i + 1, i)] = ONE10;
|
|
19316
|
+
dsymv(
|
|
19317
|
+
uplo,
|
|
19318
|
+
n - i,
|
|
19319
|
+
taui,
|
|
19320
|
+
a,
|
|
19321
|
+
A(i + 1, i + 1),
|
|
19322
|
+
lda,
|
|
19323
|
+
a,
|
|
19324
|
+
A(i + 1, i),
|
|
19325
|
+
1,
|
|
19326
|
+
ZERO9,
|
|
19327
|
+
tau,
|
|
19328
|
+
tauOff + (i - 1),
|
|
19329
|
+
1
|
|
19330
|
+
);
|
|
19331
|
+
const alpha = -HALF * taui * ddot(n - i, tau, tauOff + (i - 1), 1, a, A(i + 1, i), 1);
|
|
19332
|
+
daxpy(n - i, alpha, a, A(i + 1, i), 1, tau, tauOff + (i - 1), 1);
|
|
19333
|
+
dsyr2(
|
|
19334
|
+
uplo,
|
|
19335
|
+
n - i,
|
|
19336
|
+
-ONE10,
|
|
19337
|
+
a,
|
|
19338
|
+
A(i + 1, i),
|
|
19339
|
+
1,
|
|
19340
|
+
tau,
|
|
19341
|
+
tauOff + (i - 1),
|
|
19342
|
+
1,
|
|
19343
|
+
a,
|
|
19344
|
+
A(i + 1, i + 1),
|
|
19345
|
+
lda
|
|
19346
|
+
);
|
|
19347
|
+
a[A(i + 1, i)] = e[eOff + (i - 1)];
|
|
19348
|
+
}
|
|
19349
|
+
d[dOff + (i - 1)] = a[A(i, i)];
|
|
19350
|
+
tau[tauOff + (i - 1)] = taui;
|
|
19351
|
+
}
|
|
19352
|
+
d[dOff + (n - 1)] = a[A(n, n)];
|
|
19353
|
+
}
|
|
19354
|
+
return 0;
|
|
19355
|
+
}
|
|
19356
|
+
|
|
19357
|
+
// src/ts-lapack/src/SRC/dorgtr.ts
|
|
19358
|
+
function dorgtr(uplo, n, a, aOff, lda, tau, tauOff) {
|
|
19359
|
+
const ONE10 = 1;
|
|
19360
|
+
const ZERO9 = 0;
|
|
19361
|
+
let info = 0;
|
|
19362
|
+
if (uplo !== LOWER) {
|
|
19363
|
+
info = -1;
|
|
19364
|
+
} else if (n < 0) {
|
|
19365
|
+
info = -2;
|
|
19366
|
+
} else if (lda < Math.max(1, n)) {
|
|
19367
|
+
info = -4;
|
|
19368
|
+
}
|
|
19369
|
+
if (info !== 0) {
|
|
19370
|
+
xerbla("DORGTR", -info);
|
|
19371
|
+
return info;
|
|
19372
|
+
}
|
|
19373
|
+
if (n === 0) return 0;
|
|
19374
|
+
const A = (i, j) => aOff + (i - 1) + (j - 1) * lda;
|
|
19375
|
+
for (let j = n; j >= 2; j--) {
|
|
19376
|
+
a[A(1, j)] = ZERO9;
|
|
19377
|
+
for (let i = j + 1; i <= n; i++) {
|
|
19378
|
+
a[A(i, j)] = a[A(i, j - 1)];
|
|
19379
|
+
}
|
|
19380
|
+
}
|
|
19381
|
+
a[A(1, 1)] = ONE10;
|
|
19382
|
+
for (let i = 2; i <= n; i++) {
|
|
19383
|
+
a[A(i, 1)] = ZERO9;
|
|
19384
|
+
}
|
|
19385
|
+
if (n > 1) {
|
|
19386
|
+
info = dorgqr(n - 1, n - 1, n - 1, a, A(2, 2), lda, tau, tauOff);
|
|
19387
|
+
}
|
|
19388
|
+
return info;
|
|
19389
|
+
}
|
|
19390
|
+
|
|
19391
|
+
// src/ts-lapack/src/SRC/dsyev.ts
|
|
19392
|
+
var NORM_MAX8 = 0;
|
|
19393
|
+
var TYPE_L2 = 1;
|
|
19394
|
+
function dsyev(wantz, uplo, n, a, aOff, lda, w, wOff) {
|
|
19395
|
+
const ONE10 = 1;
|
|
19396
|
+
const ZERO9 = 0;
|
|
19397
|
+
let info = 0;
|
|
19398
|
+
if (uplo !== LOWER) {
|
|
19399
|
+
info = -2;
|
|
19400
|
+
} else if (n < 0) {
|
|
19401
|
+
info = -3;
|
|
19402
|
+
} else if (lda < Math.max(1, n)) {
|
|
19403
|
+
info = -5;
|
|
19404
|
+
}
|
|
19405
|
+
if (info !== 0) {
|
|
19406
|
+
xerbla("DSYEV ", -info);
|
|
19407
|
+
return info;
|
|
19408
|
+
}
|
|
19409
|
+
if (n === 0) return 0;
|
|
19410
|
+
if (n === 1) {
|
|
19411
|
+
w[wOff] = a[aOff];
|
|
19412
|
+
if (wantz) a[aOff] = ONE10;
|
|
19413
|
+
return 0;
|
|
19414
|
+
}
|
|
19415
|
+
const safmin = dlamch(MACH_SFMIN);
|
|
19416
|
+
const eps2 = dlamch(MACH_PREC);
|
|
19417
|
+
const smlnum = safmin / eps2;
|
|
19418
|
+
const bignum = ONE10 / smlnum;
|
|
19419
|
+
const rmin = Math.sqrt(smlnum);
|
|
19420
|
+
const rmax = Math.sqrt(bignum);
|
|
19421
|
+
const work = allocFloat64Array(Math.max(1, 3 * n));
|
|
19422
|
+
const anrm = dlansy(NORM_MAX8, uplo, n, a, aOff, lda, work, 0);
|
|
19423
|
+
let iscale = 0;
|
|
19424
|
+
let sigma = ONE10;
|
|
19425
|
+
if (anrm > ZERO9 && anrm < rmin) {
|
|
19426
|
+
iscale = 1;
|
|
19427
|
+
sigma = rmin / anrm;
|
|
19428
|
+
} else if (anrm > rmax) {
|
|
19429
|
+
iscale = 1;
|
|
19430
|
+
sigma = rmax / anrm;
|
|
19431
|
+
}
|
|
19432
|
+
if (iscale === 1) dlascl(TYPE_L2, 0, 0, ONE10, sigma, n, n, a, aOff, lda);
|
|
19433
|
+
const e = allocFloat64Array(Math.max(1, n - 1));
|
|
19434
|
+
const tau = allocFloat64Array(Math.max(1, n - 1));
|
|
19435
|
+
dsytd2(uplo, n, a, aOff, lda, w, wOff, e, 0, tau, 0);
|
|
19436
|
+
if (!wantz) {
|
|
19437
|
+
info = dsteqr(COMPZ_N, n, w, wOff, e, 0, a, aOff, lda, work, 0);
|
|
19438
|
+
} else {
|
|
19439
|
+
const iinfo = dorgtr(uplo, n, a, aOff, lda, tau, 0);
|
|
19440
|
+
if (iinfo !== 0) return iinfo;
|
|
19441
|
+
info = dsteqr(COMPZ_V, n, w, wOff, e, 0, a, aOff, lda, work, 0);
|
|
19442
|
+
}
|
|
19443
|
+
if (iscale === 1) {
|
|
19444
|
+
const imax = info === 0 ? n : info - 1;
|
|
19445
|
+
dscal(imax, ONE10 / sigma, w, wOff, 1);
|
|
19446
|
+
}
|
|
19447
|
+
return info;
|
|
19448
|
+
}
|
|
19449
|
+
|
|
18093
19450
|
// src/numbl-core/native/ts-lapack-bridge.ts
|
|
18094
19451
|
function inv(data, n) {
|
|
18095
19452
|
const a = allocFloat64Array(data);
|
|
@@ -18263,6 +19620,20 @@ function linsolve(A, m, n, B, nrhs) {
|
|
|
18263
19620
|
return x;
|
|
18264
19621
|
}
|
|
18265
19622
|
}
|
|
19623
|
+
function eigSym(data, n, computeV) {
|
|
19624
|
+
const a = allocFloat64Array(data);
|
|
19625
|
+
const w = allocFloat64Array(n);
|
|
19626
|
+
const info = dsyev(computeV, LOWER, n, a, 0, n, w, 0);
|
|
19627
|
+
if (info !== 0) {
|
|
19628
|
+
throw new Error(
|
|
19629
|
+
info < 0 ? "eig: illegal argument passed to dsyev" : "QR algorithm failed to converge in dsyev"
|
|
19630
|
+
);
|
|
19631
|
+
}
|
|
19632
|
+
return computeV ? { w, V: a } : { w };
|
|
19633
|
+
}
|
|
19634
|
+
function eigHerm(dataRe, dataIm, n, computeV) {
|
|
19635
|
+
return eigHermTs(dataRe, dataIm, n, computeV);
|
|
19636
|
+
}
|
|
18266
19637
|
function eig(data, n, computeVL, computeVR, balance) {
|
|
18267
19638
|
const a = allocFloat64Array(data);
|
|
18268
19639
|
const wr = allocFloat64Array(n);
|
|
@@ -19001,7 +20372,9 @@ var _bridge2 = {
|
|
|
19001
20372
|
linsolve,
|
|
19002
20373
|
linsolveComplex,
|
|
19003
20374
|
eig,
|
|
20375
|
+
eigSym,
|
|
19004
20376
|
eigComplex: eigComplexTs,
|
|
20377
|
+
eigHerm,
|
|
19005
20378
|
lu,
|
|
19006
20379
|
svd,
|
|
19007
20380
|
chol,
|
|
@@ -21461,6 +22834,21 @@ function mMulSparse(a, b) {
|
|
|
21461
22834
|
const m = a.m;
|
|
21462
22835
|
const hasImag = isComplexSparse(a) || b.imag !== void 0;
|
|
21463
22836
|
const result = allocFloat64Array(m * bCols);
|
|
22837
|
+
if (!hasImag) {
|
|
22838
|
+
const ir = a.ir, jc = a.jc, pr = a.pr, bd = b.data;
|
|
22839
|
+
for (let col = 0; col < bCols; col++) {
|
|
22840
|
+
const boff = col * bRows;
|
|
22841
|
+
const roff = col * m;
|
|
22842
|
+
for (let k = 0; k < a.n; k++) {
|
|
22843
|
+
const bk = bd[boff + k];
|
|
22844
|
+
if (bk === 0) continue;
|
|
22845
|
+
const end = jc[k + 1];
|
|
22846
|
+
for (let ka = jc[k]; ka < end; ka++)
|
|
22847
|
+
result[roff + ir[ka]] += pr[ka] * bk;
|
|
22848
|
+
}
|
|
22849
|
+
}
|
|
22850
|
+
return RTV.tensor(result, [m, bCols]);
|
|
22851
|
+
}
|
|
21464
22852
|
const resultImag = hasImag ? allocFloat64Array(m * bCols) : void 0;
|
|
21465
22853
|
for (let col = 0; col < bCols; col++) {
|
|
21466
22854
|
for (let k = 0; k < a.n; k++) {
|
|
@@ -21826,7 +23214,7 @@ function applyUnaryElemwiseMaybeComplex(v, realFn, complexFn, name, nativeOpCode
|
|
|
21826
23214
|
if (typeof v === "boolean") v = v ? 1 : 0;
|
|
21827
23215
|
if (typeof v === "number") {
|
|
21828
23216
|
const r = realFn(v);
|
|
21829
|
-
if (!Number.isNaN(r)) return r;
|
|
23217
|
+
if (!Number.isNaN(r) || Number.isNaN(v)) return r;
|
|
21830
23218
|
const c = complexFn(v, 0);
|
|
21831
23219
|
return mkc(c.re, c.im);
|
|
21832
23220
|
}
|
|
@@ -21842,7 +23230,7 @@ function applyUnaryElemwiseMaybeComplex(v, realFn, complexFn, name, nativeOpCode
|
|
|
21842
23230
|
tensorOps.realUnaryElemwise(nativeOpCode, n, v.data, nativeOut);
|
|
21843
23231
|
let firstNaN = -1;
|
|
21844
23232
|
for (let i = 0; i < n; i++) {
|
|
21845
|
-
if (Number.isNaN(nativeOut[i])) {
|
|
23233
|
+
if (Number.isNaN(nativeOut[i]) && !Number.isNaN(v.data[i])) {
|
|
21846
23234
|
firstNaN = i;
|
|
21847
23235
|
break;
|
|
21848
23236
|
}
|
|
@@ -21854,7 +23242,7 @@ function applyUnaryElemwiseMaybeComplex(v, realFn, complexFn, name, nativeOpCode
|
|
|
21854
23242
|
const outI3 = allocFloat64Array(n);
|
|
21855
23243
|
let hasImag2 = false;
|
|
21856
23244
|
for (let i = 0; i < n; i++) {
|
|
21857
|
-
if (!Number.isNaN(nativeOut[i])) {
|
|
23245
|
+
if (!Number.isNaN(nativeOut[i]) || Number.isNaN(v.data[i])) {
|
|
21858
23246
|
outR3[i] = nativeOut[i];
|
|
21859
23247
|
} else {
|
|
21860
23248
|
const c = complexFn(v.data[i], 0);
|
|
@@ -21870,7 +23258,7 @@ function applyUnaryElemwiseMaybeComplex(v, realFn, complexFn, name, nativeOpCode
|
|
|
21870
23258
|
let hasImag = false;
|
|
21871
23259
|
for (let i = 0; i < n; i++) {
|
|
21872
23260
|
const r = realFn(v.data[i]);
|
|
21873
|
-
if (!Number.isNaN(r)) {
|
|
23261
|
+
if (!Number.isNaN(r) || Number.isNaN(v.data[i])) {
|
|
21874
23262
|
outR2[i] = r;
|
|
21875
23263
|
outI2[i] = 0;
|
|
21876
23264
|
} else {
|
|
@@ -22580,6 +23968,707 @@ function sprintfFormat(fmt, args) {
|
|
|
22580
23968
|
return result;
|
|
22581
23969
|
}
|
|
22582
23970
|
|
|
23971
|
+
// src/numbl-core/helpers/warn.ts
|
|
23972
|
+
var sink = (msg) => console.warn("Warning: " + msg);
|
|
23973
|
+
function setWarningSink(fn) {
|
|
23974
|
+
sink = fn;
|
|
23975
|
+
}
|
|
23976
|
+
function emitWarning(msg) {
|
|
23977
|
+
sink(msg);
|
|
23978
|
+
}
|
|
23979
|
+
|
|
23980
|
+
// src/numbl-core/helpers/sparse-direct.ts
|
|
23981
|
+
var SINGULAR_WARNING = "Matrix is singular to working precision.";
|
|
23982
|
+
function denseToSparse(t) {
|
|
23983
|
+
const m = t.shape[0] ?? 1;
|
|
23984
|
+
const n = t.shape.length >= 2 ? t.shape[1] : 1;
|
|
23985
|
+
const irList = [];
|
|
23986
|
+
const prList = [];
|
|
23987
|
+
const piList = t.imag ? [] : void 0;
|
|
23988
|
+
const jc = new Int32Array(n + 1);
|
|
23989
|
+
for (let c = 0; c < n; c++) {
|
|
23990
|
+
jc[c] = irList.length;
|
|
23991
|
+
for (let r = 0; r < m; r++) {
|
|
23992
|
+
const idx = c * m + r;
|
|
23993
|
+
const re = t.data[idx];
|
|
23994
|
+
const im = t.imag ? t.imag[idx] : 0;
|
|
23995
|
+
if (re !== 0 || im !== 0) {
|
|
23996
|
+
irList.push(r);
|
|
23997
|
+
prList.push(re);
|
|
23998
|
+
if (piList) piList.push(im);
|
|
23999
|
+
}
|
|
24000
|
+
}
|
|
24001
|
+
}
|
|
24002
|
+
jc[n] = irList.length;
|
|
24003
|
+
return RTV.sparseMatrix(
|
|
24004
|
+
m,
|
|
24005
|
+
n,
|
|
24006
|
+
new Int32Array(irList),
|
|
24007
|
+
jc,
|
|
24008
|
+
allocFloat64Array(prList),
|
|
24009
|
+
piList ? allocFloat64Array(piList) : void 0
|
|
24010
|
+
);
|
|
24011
|
+
}
|
|
24012
|
+
function denseDataToSparse(data, m, n) {
|
|
24013
|
+
return denseToSparse(RTV.tensor(data, [m, n]));
|
|
24014
|
+
}
|
|
24015
|
+
function fromUnsortedColumns(m, n, ir, jc, pr) {
|
|
24016
|
+
return sparseTranspose(sparseTranspose(RTV.sparseMatrix(m, n, ir, jc, pr)));
|
|
24017
|
+
}
|
|
24018
|
+
function permutationMatrix(p2) {
|
|
24019
|
+
const n = p2.length;
|
|
24020
|
+
const ir = new Int32Array(n);
|
|
24021
|
+
const jc = new Int32Array(n + 1);
|
|
24022
|
+
const pr = allocFloat64Array(n);
|
|
24023
|
+
for (let k = 0; k < n; k++) jc[p2[k] + 1]++;
|
|
24024
|
+
for (let c = 0; c < n; c++) jc[c + 1] += jc[c];
|
|
24025
|
+
for (let k = 0; k < n; k++) {
|
|
24026
|
+
ir[jc[p2[k]]] = k;
|
|
24027
|
+
pr[jc[p2[k]]] = 1;
|
|
24028
|
+
}
|
|
24029
|
+
return RTV.sparseMatrix(n, n, ir, jc, pr);
|
|
24030
|
+
}
|
|
24031
|
+
function permVectorTensor(p2) {
|
|
24032
|
+
const d = allocFloat64Array(p2.length);
|
|
24033
|
+
for (let i = 0; i < p2.length; i++) d[i] = p2[i] + 1;
|
|
24034
|
+
return RTV.tensor(d, [1, p2.length]);
|
|
24035
|
+
}
|
|
24036
|
+
function invertPerm(p2) {
|
|
24037
|
+
const inv2 = new Int32Array(p2.length);
|
|
24038
|
+
for (let i = 0; i < p2.length; i++) inv2[p2[i]] = i;
|
|
24039
|
+
return inv2;
|
|
24040
|
+
}
|
|
24041
|
+
function sparsePermute(A, p2, q) {
|
|
24042
|
+
const pinv = invertPerm(p2);
|
|
24043
|
+
const nnz = A.jc[A.n];
|
|
24044
|
+
const ir = new Int32Array(nnz);
|
|
24045
|
+
const jc = new Int32Array(A.n + 1);
|
|
24046
|
+
const pr = allocFloat64Array(nnz);
|
|
24047
|
+
let pos = 0;
|
|
24048
|
+
for (let k = 0; k < A.n; k++) {
|
|
24049
|
+
jc[k] = pos;
|
|
24050
|
+
const j = q[k];
|
|
24051
|
+
for (let t = A.jc[j]; t < A.jc[j + 1]; t++) {
|
|
24052
|
+
ir[pos] = pinv[A.ir[t]];
|
|
24053
|
+
pr[pos] = A.pr[t];
|
|
24054
|
+
pos++;
|
|
24055
|
+
}
|
|
24056
|
+
}
|
|
24057
|
+
jc[A.n] = pos;
|
|
24058
|
+
return fromUnsortedColumns(A.m, A.n, ir, jc, pr);
|
|
24059
|
+
}
|
|
24060
|
+
function sparseKron(A, B) {
|
|
24061
|
+
const m = A.m, n = A.n, p2 = B.m, q = B.n;
|
|
24062
|
+
const nnz = A.jc[n] * B.jc[q];
|
|
24063
|
+
const ir = new Int32Array(nnz);
|
|
24064
|
+
const jc = new Int32Array(n * q + 1);
|
|
24065
|
+
const pr = allocFloat64Array(nnz);
|
|
24066
|
+
const cplx = A.pi !== void 0 || B.pi !== void 0;
|
|
24067
|
+
const pi2 = cplx ? allocFloat64Array(nnz) : void 0;
|
|
24068
|
+
let pos = 0;
|
|
24069
|
+
for (let ja = 0; ja < n; ja++) {
|
|
24070
|
+
for (let jb = 0; jb < q; jb++) {
|
|
24071
|
+
jc[ja * q + jb] = pos;
|
|
24072
|
+
for (let ka = A.jc[ja]; ka < A.jc[ja + 1]; ka++) {
|
|
24073
|
+
const rowBase = A.ir[ka] * p2;
|
|
24074
|
+
const aRe = A.pr[ka];
|
|
24075
|
+
const aIm = A.pi ? A.pi[ka] : 0;
|
|
24076
|
+
for (let kb = B.jc[jb]; kb < B.jc[jb + 1]; kb++) {
|
|
24077
|
+
ir[pos] = rowBase + B.ir[kb];
|
|
24078
|
+
const bRe = B.pr[kb];
|
|
24079
|
+
const bIm = B.pi ? B.pi[kb] : 0;
|
|
24080
|
+
pr[pos] = aRe * bRe - aIm * bIm;
|
|
24081
|
+
if (pi2) pi2[pos] = aRe * bIm + aIm * bRe;
|
|
24082
|
+
pos++;
|
|
24083
|
+
}
|
|
24084
|
+
}
|
|
24085
|
+
}
|
|
24086
|
+
}
|
|
24087
|
+
jc[n * q] = pos;
|
|
24088
|
+
return RTV.sparseMatrix(m * p2, n * q, ir, jc, pr, pi2);
|
|
24089
|
+
}
|
|
24090
|
+
function triangularInfo(S) {
|
|
24091
|
+
if (S._triInfo) return S._triInfo;
|
|
24092
|
+
const n = S.n;
|
|
24093
|
+
const ir = S.ir, jc = S.jc, pr = S.pr, pi2 = S.pi;
|
|
24094
|
+
const diagPos = new Int32Array(n).fill(-1);
|
|
24095
|
+
const diag2 = allocFloat64Array(n);
|
|
24096
|
+
let upper = true;
|
|
24097
|
+
let lower = true;
|
|
24098
|
+
for (let j = 0; j < n; j++) {
|
|
24099
|
+
const end = jc[j + 1];
|
|
24100
|
+
for (let k = jc[j]; k < end; k++) {
|
|
24101
|
+
const i = ir[k];
|
|
24102
|
+
if (i === j) {
|
|
24103
|
+
diagPos[j] = k;
|
|
24104
|
+
diag2[j] = pr[k];
|
|
24105
|
+
continue;
|
|
24106
|
+
}
|
|
24107
|
+
if (pr[k] === 0 && (!pi2 || pi2[k] === 0)) continue;
|
|
24108
|
+
if (i > j) upper = false;
|
|
24109
|
+
else lower = false;
|
|
24110
|
+
}
|
|
24111
|
+
}
|
|
24112
|
+
const info = { upper, lower, diagPos, diag: diag2 };
|
|
24113
|
+
S._triInfo = info;
|
|
24114
|
+
return info;
|
|
24115
|
+
}
|
|
24116
|
+
function sparseIsUpper(S) {
|
|
24117
|
+
return triangularInfo(S).upper;
|
|
24118
|
+
}
|
|
24119
|
+
function sparseIsLower(S) {
|
|
24120
|
+
return triangularInfo(S).lower;
|
|
24121
|
+
}
|
|
24122
|
+
function sparseIsSymmetric(S) {
|
|
24123
|
+
if (S.m !== S.n || S.pi) return false;
|
|
24124
|
+
const T = sparseTranspose(S);
|
|
24125
|
+
const nnz = S.jc[S.n];
|
|
24126
|
+
if (T.jc[T.n] !== nnz) return false;
|
|
24127
|
+
for (let j = 0; j <= S.n; j++) if (S.jc[j] !== T.jc[j]) return false;
|
|
24128
|
+
for (let k = 0; k < nnz; k++)
|
|
24129
|
+
if (S.ir[k] !== T.ir[k] || S.pr[k] !== T.pr[k]) return false;
|
|
24130
|
+
return true;
|
|
24131
|
+
}
|
|
24132
|
+
function sparseAt(S, i, j) {
|
|
24133
|
+
let lo = S.jc[j], hi = S.jc[j + 1] - 1;
|
|
24134
|
+
while (lo <= hi) {
|
|
24135
|
+
const mid = lo + hi >> 1;
|
|
24136
|
+
const r = S.ir[mid];
|
|
24137
|
+
if (r === i) return S.pr[mid];
|
|
24138
|
+
if (r < i) lo = mid + 1;
|
|
24139
|
+
else hi = mid - 1;
|
|
24140
|
+
}
|
|
24141
|
+
return 0;
|
|
24142
|
+
}
|
|
24143
|
+
function allDiagPositive(S) {
|
|
24144
|
+
for (let j = 0; j < S.n; j++) if (!(sparseAt(S, j, j) > 0)) return false;
|
|
24145
|
+
return true;
|
|
24146
|
+
}
|
|
24147
|
+
function sparseSolveUpper(R, B, nrhs) {
|
|
24148
|
+
const n = R.n;
|
|
24149
|
+
const { diagPos, diag: diag2 } = triangularInfo(R);
|
|
24150
|
+
const ir = R.ir, jc = R.jc, pr = R.pr;
|
|
24151
|
+
const x = allocFloat64Array(B);
|
|
24152
|
+
let singular = false;
|
|
24153
|
+
for (let j = 0; j < n; j++) if (diag2[j] === 0) singular = true;
|
|
24154
|
+
for (let c = 0; c < nrhs; c++) {
|
|
24155
|
+
const off = c * n;
|
|
24156
|
+
for (let j = n - 1; j >= 0; j--) {
|
|
24157
|
+
const xj = x[off + j] / diag2[j];
|
|
24158
|
+
x[off + j] = xj;
|
|
24159
|
+
if (xj === 0) continue;
|
|
24160
|
+
const dp = diagPos[j];
|
|
24161
|
+
const end = dp >= 0 ? dp : jc[j + 1];
|
|
24162
|
+
for (let k = jc[j]; k < end; k++) x[off + ir[k]] -= pr[k] * xj;
|
|
24163
|
+
}
|
|
24164
|
+
}
|
|
24165
|
+
return { x, singular };
|
|
24166
|
+
}
|
|
24167
|
+
function sparseSolveLower(L, B, nrhs) {
|
|
24168
|
+
const n = L.n;
|
|
24169
|
+
const { diagPos, diag: diag2 } = triangularInfo(L);
|
|
24170
|
+
const ir = L.ir, jc = L.jc, pr = L.pr;
|
|
24171
|
+
const x = allocFloat64Array(B);
|
|
24172
|
+
let singular = false;
|
|
24173
|
+
for (let j = 0; j < n; j++) if (diag2[j] === 0) singular = true;
|
|
24174
|
+
for (let c = 0; c < nrhs; c++) {
|
|
24175
|
+
const off = c * n;
|
|
24176
|
+
for (let j = 0; j < n; j++) {
|
|
24177
|
+
const xj = x[off + j] / diag2[j];
|
|
24178
|
+
x[off + j] = xj;
|
|
24179
|
+
if (xj === 0) continue;
|
|
24180
|
+
const dp = diagPos[j];
|
|
24181
|
+
const end = jc[j + 1];
|
|
24182
|
+
for (let k = dp >= 0 ? dp + 1 : jc[j]; k < end; k++)
|
|
24183
|
+
x[off + ir[k]] -= pr[k] * xj;
|
|
24184
|
+
}
|
|
24185
|
+
}
|
|
24186
|
+
return { x, singular };
|
|
24187
|
+
}
|
|
24188
|
+
function permuteRows(X, n, nrhs, p2) {
|
|
24189
|
+
const Y = allocFloat64Array(X.length);
|
|
24190
|
+
for (let c = 0; c < nrhs; c++) {
|
|
24191
|
+
const off = c * n;
|
|
24192
|
+
for (let k = 0; k < n; k++) Y[off + k] = X[off + p2[k]];
|
|
24193
|
+
}
|
|
24194
|
+
return Y;
|
|
24195
|
+
}
|
|
24196
|
+
function unpermuteRows(X, n, nrhs, p2) {
|
|
24197
|
+
const Y = allocFloat64Array(X.length);
|
|
24198
|
+
for (let c = 0; c < nrhs; c++) {
|
|
24199
|
+
const off = c * n;
|
|
24200
|
+
for (let k = 0; k < n; k++) Y[off + p2[k]] = X[off + k];
|
|
24201
|
+
}
|
|
24202
|
+
return Y;
|
|
24203
|
+
}
|
|
24204
|
+
function eliminationTree(A) {
|
|
24205
|
+
const n = A.n;
|
|
24206
|
+
const parent = new Int32Array(n).fill(-1);
|
|
24207
|
+
const ancestor = new Int32Array(n).fill(-1);
|
|
24208
|
+
for (let k = 0; k < n; k++) {
|
|
24209
|
+
for (let p2 = A.jc[k]; p2 < A.jc[k + 1]; p2++) {
|
|
24210
|
+
let i = A.ir[p2];
|
|
24211
|
+
while (i !== -1 && i < k) {
|
|
24212
|
+
const inext = ancestor[i];
|
|
24213
|
+
ancestor[i] = k;
|
|
24214
|
+
if (inext === -1) parent[i] = k;
|
|
24215
|
+
i = inext;
|
|
24216
|
+
}
|
|
24217
|
+
}
|
|
24218
|
+
}
|
|
24219
|
+
return parent;
|
|
24220
|
+
}
|
|
24221
|
+
function etreeReach(A, k, parent, s, mark) {
|
|
24222
|
+
const n = A.n;
|
|
24223
|
+
let top = n;
|
|
24224
|
+
mark[k] = k;
|
|
24225
|
+
for (let p2 = A.jc[k]; p2 < A.jc[k + 1]; p2++) {
|
|
24226
|
+
let i = A.ir[p2];
|
|
24227
|
+
if (i > k) continue;
|
|
24228
|
+
let len = 0;
|
|
24229
|
+
for (; mark[i] !== k; i = parent[i]) {
|
|
24230
|
+
s[len++] = i;
|
|
24231
|
+
mark[i] = k;
|
|
24232
|
+
}
|
|
24233
|
+
while (len > 0) s[--top] = s[--len];
|
|
24234
|
+
}
|
|
24235
|
+
return top;
|
|
24236
|
+
}
|
|
24237
|
+
function sparseChol(A) {
|
|
24238
|
+
const n = A.n;
|
|
24239
|
+
if (A.m !== n) throw new RuntimeError("chol: Matrix must be square.");
|
|
24240
|
+
const parent = eliminationTree(A);
|
|
24241
|
+
const s = new Int32Array(n);
|
|
24242
|
+
const mark = new Int32Array(n).fill(-1);
|
|
24243
|
+
const colCount = new Int32Array(n);
|
|
24244
|
+
for (let k = 0; k < n; k++) {
|
|
24245
|
+
const top = etreeReach(A, k, parent, s, mark);
|
|
24246
|
+
for (let t = top; t < n; t++) colCount[s[t]]++;
|
|
24247
|
+
colCount[k]++;
|
|
24248
|
+
}
|
|
24249
|
+
const Lp = new Int32Array(n + 1);
|
|
24250
|
+
for (let j = 0; j < n; j++) Lp[j + 1] = Lp[j] + colCount[j];
|
|
24251
|
+
const nnzL = Lp[n];
|
|
24252
|
+
const Li = new Int32Array(nnzL);
|
|
24253
|
+
const Lx = allocFloat64Array(nnzL);
|
|
24254
|
+
const c = new Int32Array(n);
|
|
24255
|
+
for (let j = 0; j < n; j++) c[j] = Lp[j];
|
|
24256
|
+
const x = allocFloat64Array(n);
|
|
24257
|
+
mark.fill(-1);
|
|
24258
|
+
for (let k = 0; k < n; k++) {
|
|
24259
|
+
const top = etreeReach(A, k, parent, s, mark);
|
|
24260
|
+
x[k] = 0;
|
|
24261
|
+
for (let p2 = A.jc[k]; p2 < A.jc[k + 1]; p2++) {
|
|
24262
|
+
if (A.ir[p2] <= k) x[A.ir[p2]] = A.pr[p2];
|
|
24263
|
+
}
|
|
24264
|
+
let d = x[k];
|
|
24265
|
+
x[k] = 0;
|
|
24266
|
+
for (let t = top; t < n; t++) {
|
|
24267
|
+
const i = s[t];
|
|
24268
|
+
const lki = x[i] / Lx[Lp[i]];
|
|
24269
|
+
x[i] = 0;
|
|
24270
|
+
for (let p2 = Lp[i] + 1; p2 < c[i]; p2++) x[Li[p2]] -= Lx[p2] * lki;
|
|
24271
|
+
d -= lki * lki;
|
|
24272
|
+
const pos2 = c[i]++;
|
|
24273
|
+
Li[pos2] = k;
|
|
24274
|
+
Lx[pos2] = lki;
|
|
24275
|
+
}
|
|
24276
|
+
if (!(d > 0)) {
|
|
24277
|
+
for (let i = k + 1; i < n; i++) {
|
|
24278
|
+
const top2 = etreeReach(A, i, parent, s, mark);
|
|
24279
|
+
for (let p2 = A.jc[i]; p2 < A.jc[i + 1]; p2++)
|
|
24280
|
+
if (A.ir[p2] < k) x[A.ir[p2]] = A.pr[p2];
|
|
24281
|
+
for (let t = top2; t < n; t++) {
|
|
24282
|
+
const j = s[t];
|
|
24283
|
+
if (j >= k) {
|
|
24284
|
+
x[j] = 0;
|
|
24285
|
+
continue;
|
|
24286
|
+
}
|
|
24287
|
+
const lij = x[j] / Lx[Lp[j]];
|
|
24288
|
+
x[j] = 0;
|
|
24289
|
+
for (let p2 = Lp[j] + 1; p2 < c[j]; p2++) x[Li[p2]] -= Lx[p2] * lij;
|
|
24290
|
+
const pos2 = c[j]++;
|
|
24291
|
+
Li[pos2] = i;
|
|
24292
|
+
Lx[pos2] = lij;
|
|
24293
|
+
}
|
|
24294
|
+
}
|
|
24295
|
+
return { L: leadingColumns(n, k, Lp, Li, Lx, c), ok: false, p: k + 1 };
|
|
24296
|
+
}
|
|
24297
|
+
const pos = c[k]++;
|
|
24298
|
+
Li[pos] = k;
|
|
24299
|
+
Lx[pos] = Math.sqrt(d);
|
|
24300
|
+
}
|
|
24301
|
+
return { L: RTV.sparseMatrix(n, n, Li, Lp, Lx), ok: true, p: 0 };
|
|
24302
|
+
}
|
|
24303
|
+
function leadingColumns(n, k, Lp, Li, Lx, c) {
|
|
24304
|
+
let nnz = 0;
|
|
24305
|
+
for (let j = 0; j < k; j++) nnz += c[j] - Lp[j];
|
|
24306
|
+
const ir = new Int32Array(nnz);
|
|
24307
|
+
const pr = allocFloat64Array(nnz);
|
|
24308
|
+
const jc = new Int32Array(k + 1);
|
|
24309
|
+
let pos = 0;
|
|
24310
|
+
for (let j = 0; j < k; j++) {
|
|
24311
|
+
jc[j] = pos;
|
|
24312
|
+
for (let p2 = Lp[j]; p2 < c[j]; p2++) {
|
|
24313
|
+
ir[pos] = Li[p2];
|
|
24314
|
+
pr[pos] = Lx[p2];
|
|
24315
|
+
pos++;
|
|
24316
|
+
}
|
|
24317
|
+
}
|
|
24318
|
+
jc[k] = pos;
|
|
24319
|
+
return RTV.sparseMatrix(n, k, ir, jc, pr);
|
|
24320
|
+
}
|
|
24321
|
+
function sparseLu(A, q, tol) {
|
|
24322
|
+
const m = A.m, n = A.n;
|
|
24323
|
+
const kmin = Math.min(m, n);
|
|
24324
|
+
const Lp = [0];
|
|
24325
|
+
const Li = [];
|
|
24326
|
+
const Lx = [];
|
|
24327
|
+
const Up = [0];
|
|
24328
|
+
const Ui = [];
|
|
24329
|
+
const Ux = [];
|
|
24330
|
+
const pinv = new Int32Array(m).fill(-1);
|
|
24331
|
+
const x = allocFloat64Array(m);
|
|
24332
|
+
const xi = new Int32Array(m);
|
|
24333
|
+
const stack = new Int32Array(m);
|
|
24334
|
+
const pstack = new Int32Array(m);
|
|
24335
|
+
const mark = new Int32Array(m).fill(-1);
|
|
24336
|
+
let singular = false;
|
|
24337
|
+
for (let k = 0; k < n; k++) {
|
|
24338
|
+
const col = q ? q[k] : k;
|
|
24339
|
+
let top = m;
|
|
24340
|
+
for (let t = A.jc[col]; t < A.jc[col + 1]; t++) {
|
|
24341
|
+
const i0 = A.ir[t];
|
|
24342
|
+
if (mark[i0] === k) continue;
|
|
24343
|
+
let head = 0;
|
|
24344
|
+
stack[0] = i0;
|
|
24345
|
+
mark[i0] = k;
|
|
24346
|
+
pstack[i0] = pinv[i0] >= 0 ? Lp[pinv[i0]] : -1;
|
|
24347
|
+
while (head >= 0) {
|
|
24348
|
+
const j = stack[head];
|
|
24349
|
+
const J = pinv[j];
|
|
24350
|
+
let descended = false;
|
|
24351
|
+
if (J >= 0) {
|
|
24352
|
+
const end = Lp[J + 1];
|
|
24353
|
+
let p3 = pstack[j];
|
|
24354
|
+
for (; p3 < end; p3++) {
|
|
24355
|
+
const i = Li[p3];
|
|
24356
|
+
if (mark[i] !== k) {
|
|
24357
|
+
mark[i] = k;
|
|
24358
|
+
pstack[j] = p3 + 1;
|
|
24359
|
+
stack[++head] = i;
|
|
24360
|
+
pstack[i] = pinv[i] >= 0 ? Lp[pinv[i]] : -1;
|
|
24361
|
+
descended = true;
|
|
24362
|
+
break;
|
|
24363
|
+
}
|
|
24364
|
+
}
|
|
24365
|
+
if (descended) continue;
|
|
24366
|
+
}
|
|
24367
|
+
head--;
|
|
24368
|
+
xi[--top] = j;
|
|
24369
|
+
}
|
|
24370
|
+
}
|
|
24371
|
+
for (let t = A.jc[col]; t < A.jc[col + 1]; t++) x[A.ir[t]] = A.pr[t];
|
|
24372
|
+
for (let t = top; t < m; t++) {
|
|
24373
|
+
const j = xi[t];
|
|
24374
|
+
const J = pinv[j];
|
|
24375
|
+
if (J < 0) continue;
|
|
24376
|
+
const xj = x[j];
|
|
24377
|
+
if (xj === 0) continue;
|
|
24378
|
+
for (let p3 = Lp[J] + 1; p3 < Lp[J + 1]; p3++) x[Li[p3]] -= Lx[p3] * xj;
|
|
24379
|
+
}
|
|
24380
|
+
let ipiv = -1;
|
|
24381
|
+
let amax = -1;
|
|
24382
|
+
for (let t = top; t < m; t++) {
|
|
24383
|
+
const i = xi[t];
|
|
24384
|
+
if (pinv[i] >= 0) {
|
|
24385
|
+
Ui.push(pinv[i]);
|
|
24386
|
+
Ux.push(x[i]);
|
|
24387
|
+
} else {
|
|
24388
|
+
const a = Math.abs(x[i]);
|
|
24389
|
+
if (a > amax) {
|
|
24390
|
+
amax = a;
|
|
24391
|
+
ipiv = i;
|
|
24392
|
+
}
|
|
24393
|
+
}
|
|
24394
|
+
}
|
|
24395
|
+
if (k < kmin) {
|
|
24396
|
+
if (ipiv < 0 || amax === 0) {
|
|
24397
|
+
singular = true;
|
|
24398
|
+
if (ipiv < 0) {
|
|
24399
|
+
for (let i = 0; i < m; i++)
|
|
24400
|
+
if (pinv[i] < 0) {
|
|
24401
|
+
ipiv = i;
|
|
24402
|
+
break;
|
|
24403
|
+
}
|
|
24404
|
+
}
|
|
24405
|
+
} else if (col < m && pinv[col] < 0 && Math.abs(x[col]) >= tol * amax && x[col] !== 0) {
|
|
24406
|
+
ipiv = col;
|
|
24407
|
+
}
|
|
24408
|
+
const pivot = x[ipiv];
|
|
24409
|
+
if (!Number.isFinite(pivot)) singular = true;
|
|
24410
|
+
pinv[ipiv] = k;
|
|
24411
|
+
Ui.push(k);
|
|
24412
|
+
Ux.push(pivot);
|
|
24413
|
+
Li.push(ipiv);
|
|
24414
|
+
Lx.push(1);
|
|
24415
|
+
if (pivot !== 0 && Number.isFinite(pivot)) {
|
|
24416
|
+
for (let t = top; t < m; t++) {
|
|
24417
|
+
const i = xi[t];
|
|
24418
|
+
if (pinv[i] >= 0) continue;
|
|
24419
|
+
const v = x[i] / pivot;
|
|
24420
|
+
if (v !== 0) {
|
|
24421
|
+
Li.push(i);
|
|
24422
|
+
Lx.push(v);
|
|
24423
|
+
}
|
|
24424
|
+
}
|
|
24425
|
+
}
|
|
24426
|
+
Lp.push(Li.length);
|
|
24427
|
+
}
|
|
24428
|
+
Up.push(Ui.length);
|
|
24429
|
+
for (let t = top; t < m; t++) x[xi[t]] = 0;
|
|
24430
|
+
}
|
|
24431
|
+
let next = kmin;
|
|
24432
|
+
for (let i = 0; i < m; i++) if (pinv[i] < 0) pinv[i] = next++;
|
|
24433
|
+
const LiArr = new Int32Array(Li.length);
|
|
24434
|
+
for (let p3 = 0; p3 < Li.length; p3++) LiArr[p3] = pinv[Li[p3]];
|
|
24435
|
+
const L = fromUnsortedColumns(
|
|
24436
|
+
m,
|
|
24437
|
+
kmin,
|
|
24438
|
+
LiArr,
|
|
24439
|
+
new Int32Array(Lp),
|
|
24440
|
+
allocFloat64Array(Lx)
|
|
24441
|
+
);
|
|
24442
|
+
const U = fromUnsortedColumns(
|
|
24443
|
+
kmin,
|
|
24444
|
+
n,
|
|
24445
|
+
new Int32Array(Ui),
|
|
24446
|
+
new Int32Array(Up),
|
|
24447
|
+
allocFloat64Array(Ux)
|
|
24448
|
+
);
|
|
24449
|
+
const p2 = invertPerm(pinv);
|
|
24450
|
+
const qOut = q ? Int32Array.from(q) : identityPerm(n);
|
|
24451
|
+
return { L, U, p: p2, q: qOut, singular };
|
|
24452
|
+
}
|
|
24453
|
+
function identityPerm(n) {
|
|
24454
|
+
const p2 = new Int32Array(n);
|
|
24455
|
+
for (let i = 0; i < n; i++) p2[i] = i;
|
|
24456
|
+
return p2;
|
|
24457
|
+
}
|
|
24458
|
+
function symmetricAdjacency(A) {
|
|
24459
|
+
const n = Math.max(A.m, A.n);
|
|
24460
|
+
const adj = new Array(n);
|
|
24461
|
+
for (let i = 0; i < n; i++) adj[i] = /* @__PURE__ */ new Set();
|
|
24462
|
+
for (let j = 0; j < A.n; j++)
|
|
24463
|
+
for (let k = A.jc[j]; k < A.jc[j + 1]; k++) {
|
|
24464
|
+
const i = A.ir[k];
|
|
24465
|
+
if (i === j) continue;
|
|
24466
|
+
adj[i].add(j);
|
|
24467
|
+
adj[j].add(i);
|
|
24468
|
+
}
|
|
24469
|
+
return adj;
|
|
24470
|
+
}
|
|
24471
|
+
function minimumDegreeOrdering(A) {
|
|
24472
|
+
const adj = symmetricAdjacency(A);
|
|
24473
|
+
const n = adj.length;
|
|
24474
|
+
const perm = new Int32Array(n);
|
|
24475
|
+
if (n === 0) return perm;
|
|
24476
|
+
const head = new Int32Array(n + 1).fill(-1);
|
|
24477
|
+
const next = new Int32Array(n).fill(-1);
|
|
24478
|
+
const prev = new Int32Array(n).fill(-1);
|
|
24479
|
+
const deg = new Int32Array(n);
|
|
24480
|
+
const insert = (v) => {
|
|
24481
|
+
const d = deg[v];
|
|
24482
|
+
next[v] = head[d];
|
|
24483
|
+
prev[v] = -1;
|
|
24484
|
+
if (head[d] >= 0) prev[head[d]] = v;
|
|
24485
|
+
head[d] = v;
|
|
24486
|
+
};
|
|
24487
|
+
const remove = (v) => {
|
|
24488
|
+
const d = deg[v];
|
|
24489
|
+
if (prev[v] >= 0) next[prev[v]] = next[v];
|
|
24490
|
+
else head[d] = next[v];
|
|
24491
|
+
if (next[v] >= 0) prev[next[v]] = prev[v];
|
|
24492
|
+
};
|
|
24493
|
+
for (let v = 0; v < n; v++) {
|
|
24494
|
+
deg[v] = adj[v].size;
|
|
24495
|
+
insert(v);
|
|
24496
|
+
}
|
|
24497
|
+
let mind = 0;
|
|
24498
|
+
for (let step = 0; step < n; step++) {
|
|
24499
|
+
while (head[mind] < 0) mind++;
|
|
24500
|
+
const v = head[mind];
|
|
24501
|
+
remove(v);
|
|
24502
|
+
perm[step] = v;
|
|
24503
|
+
const nbrs = Array.from(adj[v]);
|
|
24504
|
+
for (const u of nbrs) adj[u].delete(v);
|
|
24505
|
+
for (let a = 0; a < nbrs.length; a++) {
|
|
24506
|
+
const u = nbrs[a];
|
|
24507
|
+
const su = adj[u];
|
|
24508
|
+
for (let b = a + 1; b < nbrs.length; b++) {
|
|
24509
|
+
const w = nbrs[b];
|
|
24510
|
+
if (!su.has(w)) {
|
|
24511
|
+
su.add(w);
|
|
24512
|
+
adj[w].add(u);
|
|
24513
|
+
}
|
|
24514
|
+
}
|
|
24515
|
+
}
|
|
24516
|
+
for (const u of nbrs) {
|
|
24517
|
+
remove(u);
|
|
24518
|
+
deg[u] = adj[u].size;
|
|
24519
|
+
insert(u);
|
|
24520
|
+
if (deg[u] < mind) mind = deg[u];
|
|
24521
|
+
}
|
|
24522
|
+
adj[v].clear();
|
|
24523
|
+
}
|
|
24524
|
+
return perm;
|
|
24525
|
+
}
|
|
24526
|
+
function reverseCuthillMcKee(A) {
|
|
24527
|
+
const adj = symmetricAdjacency(A);
|
|
24528
|
+
const n = adj.length;
|
|
24529
|
+
const nb = adj.map(
|
|
24530
|
+
(s) => Array.from(s).sort((a, b) => adj[a].size - adj[b].size || a - b)
|
|
24531
|
+
);
|
|
24532
|
+
const visited = new Uint8Array(n);
|
|
24533
|
+
const order = [];
|
|
24534
|
+
const bfsLevels = (start) => {
|
|
24535
|
+
const seen = new Uint8Array(n);
|
|
24536
|
+
let frontier = [start];
|
|
24537
|
+
seen[start] = 1;
|
|
24538
|
+
let levels = 0;
|
|
24539
|
+
let last = start;
|
|
24540
|
+
while (frontier.length > 0) {
|
|
24541
|
+
const nextF = [];
|
|
24542
|
+
for (const u of frontier)
|
|
24543
|
+
for (const w of nb[u])
|
|
24544
|
+
if (!seen[w]) {
|
|
24545
|
+
seen[w] = 1;
|
|
24546
|
+
nextF.push(w);
|
|
24547
|
+
}
|
|
24548
|
+
if (nextF.length === 0) {
|
|
24549
|
+
last = frontier.reduce((a, b) => adj[b].size < adj[a].size ? b : a);
|
|
24550
|
+
break;
|
|
24551
|
+
}
|
|
24552
|
+
frontier = nextF;
|
|
24553
|
+
levels++;
|
|
24554
|
+
}
|
|
24555
|
+
return { last, levels };
|
|
24556
|
+
};
|
|
24557
|
+
for (let s0 = 0; s0 < n; s0++) {
|
|
24558
|
+
if (visited[s0]) continue;
|
|
24559
|
+
let start = s0;
|
|
24560
|
+
let info = bfsLevels(start);
|
|
24561
|
+
for (let iter = 0; iter < 4; iter++) {
|
|
24562
|
+
const cand = bfsLevels(info.last);
|
|
24563
|
+
if (cand.levels > info.levels) {
|
|
24564
|
+
start = info.last;
|
|
24565
|
+
info = cand;
|
|
24566
|
+
} else {
|
|
24567
|
+
start = info.last;
|
|
24568
|
+
break;
|
|
24569
|
+
}
|
|
24570
|
+
}
|
|
24571
|
+
const queue = [start];
|
|
24572
|
+
visited[start] = 1;
|
|
24573
|
+
let qh = 0;
|
|
24574
|
+
while (qh < queue.length) {
|
|
24575
|
+
const u = queue[qh++];
|
|
24576
|
+
order.push(u);
|
|
24577
|
+
for (const w of nb[u])
|
|
24578
|
+
if (!visited[w]) {
|
|
24579
|
+
visited[w] = 1;
|
|
24580
|
+
queue.push(w);
|
|
24581
|
+
}
|
|
24582
|
+
}
|
|
24583
|
+
}
|
|
24584
|
+
const perm = new Int32Array(n);
|
|
24585
|
+
for (let i = 0; i < n; i++) perm[i] = order[n - 1 - i];
|
|
24586
|
+
return perm;
|
|
24587
|
+
}
|
|
24588
|
+
function ataPattern(A) {
|
|
24589
|
+
const At = sparseTranspose(A);
|
|
24590
|
+
const n = A.n;
|
|
24591
|
+
const marker = new Int32Array(n).fill(-1);
|
|
24592
|
+
const ir = [];
|
|
24593
|
+
const jc = new Int32Array(n + 1);
|
|
24594
|
+
for (let j = 0; j < n; j++) {
|
|
24595
|
+
jc[j] = ir.length;
|
|
24596
|
+
for (let k = A.jc[j]; k < A.jc[j + 1]; k++) {
|
|
24597
|
+
const row = A.ir[k];
|
|
24598
|
+
for (let t = At.jc[row]; t < At.jc[row + 1]; t++) {
|
|
24599
|
+
const i = At.ir[t];
|
|
24600
|
+
if (marker[i] !== j) {
|
|
24601
|
+
marker[i] = j;
|
|
24602
|
+
ir.push(i);
|
|
24603
|
+
}
|
|
24604
|
+
}
|
|
24605
|
+
}
|
|
24606
|
+
}
|
|
24607
|
+
jc[n] = ir.length;
|
|
24608
|
+
const pr = allocFloat64Array(ir.length).fill(1);
|
|
24609
|
+
return fromUnsortedColumns(n, n, new Int32Array(ir), jc, pr);
|
|
24610
|
+
}
|
|
24611
|
+
function columnOrdering(A) {
|
|
24612
|
+
return minimumDegreeOrdering(ataPattern(A));
|
|
24613
|
+
}
|
|
24614
|
+
var DENSE_FRACTION = 0.5;
|
|
24615
|
+
function sparseSolve(A, B, nrhs) {
|
|
24616
|
+
const n = A.n;
|
|
24617
|
+
if (A.m !== n || A.pi) return null;
|
|
24618
|
+
if (n === 0) return allocFloat64Array(0);
|
|
24619
|
+
const nnz = A.jc[n];
|
|
24620
|
+
if (nnz > DENSE_FRACTION * n * n && n > 8) return null;
|
|
24621
|
+
if (sparseIsUpper(A)) {
|
|
24622
|
+
const r = sparseSolveUpper(A, B, nrhs);
|
|
24623
|
+
if (r.singular) emitWarning(SINGULAR_WARNING);
|
|
24624
|
+
return r.x;
|
|
24625
|
+
}
|
|
24626
|
+
if (sparseIsLower(A)) {
|
|
24627
|
+
const r = sparseSolveLower(A, B, nrhs);
|
|
24628
|
+
if (r.singular) emitWarning(SINGULAR_WARNING);
|
|
24629
|
+
return r.x;
|
|
24630
|
+
}
|
|
24631
|
+
const perm = reverseCuthillMcKee(A);
|
|
24632
|
+
if (sparseIsSymmetric(A) && allDiagPositive(A)) {
|
|
24633
|
+
const Ap = sparsePermute(A, perm, perm);
|
|
24634
|
+
const ch = sparseChol(Ap);
|
|
24635
|
+
if (ch.ok) {
|
|
24636
|
+
const Lt = sparseTranspose(ch.L);
|
|
24637
|
+
const bp = permuteRows(B, n, nrhs, perm);
|
|
24638
|
+
const y = sparseSolveLower(ch.L, bp, nrhs).x;
|
|
24639
|
+
const z = sparseSolveUpper(Lt, y, nrhs).x;
|
|
24640
|
+
return unpermuteRows(z, n, nrhs, perm);
|
|
24641
|
+
}
|
|
24642
|
+
}
|
|
24643
|
+
const lu2 = sparseLu(A, perm, 1);
|
|
24644
|
+
return luSolve(lu2, B, nrhs);
|
|
24645
|
+
}
|
|
24646
|
+
function luSolve(lu2, B, nrhs) {
|
|
24647
|
+
const n = lu2.U.n;
|
|
24648
|
+
const pb = permuteRows(B, n, nrhs, lu2.p);
|
|
24649
|
+
const y = sparseSolveLower(lu2.L, pb, nrhs);
|
|
24650
|
+
const z = sparseSolveUpper(lu2.U, y.x, nrhs);
|
|
24651
|
+
if (lu2.singular || z.singular) emitWarning(SINGULAR_WARNING);
|
|
24652
|
+
return unpermuteRows(z.x, n, nrhs, lu2.q);
|
|
24653
|
+
}
|
|
24654
|
+
function luSolveTransposed(lu2, B, nrhs) {
|
|
24655
|
+
const n = lu2.U.n;
|
|
24656
|
+
const qb = permuteRows(B, n, nrhs, lu2.q);
|
|
24657
|
+
const y = sparseSolveLower(sparseTranspose(lu2.U), qb, nrhs);
|
|
24658
|
+
const z = sparseSolveUpper(sparseTranspose(lu2.L), y.x, nrhs);
|
|
24659
|
+
if (lu2.singular || y.singular) emitWarning(SINGULAR_WARNING);
|
|
24660
|
+
return unpermuteRows(z.x, n, nrhs, lu2.p);
|
|
24661
|
+
}
|
|
24662
|
+
function sparseInverse(A) {
|
|
24663
|
+
const n = A.n;
|
|
24664
|
+
if (A.m !== n) throw new RuntimeError("inv: matrix must be square");
|
|
24665
|
+
const I = allocFloat64Array(n * n);
|
|
24666
|
+
for (let i = 0; i < n; i++) I[i + i * n] = 1;
|
|
24667
|
+
const X = sparseSolve(A, I, n);
|
|
24668
|
+
if (X === null) throw new RuntimeError("inv: unsupported sparse matrix");
|
|
24669
|
+
return denseDataToSparse(X, n, n);
|
|
24670
|
+
}
|
|
24671
|
+
|
|
22583
24672
|
// src/numbl-core/helpers/arithmetic.ts
|
|
22584
24673
|
function toComplex(v) {
|
|
22585
24674
|
if (isRuntimeComplexNumber(v)) return { re: v.re, im: v.im };
|
|
@@ -23170,6 +25259,12 @@ function mElemMul(a, b) {
|
|
|
23170
25259
|
}
|
|
23171
25260
|
function mDiv(a, b) {
|
|
23172
25261
|
if (isRuntimeSparseMatrix(a) || isRuntimeSparseMatrix(b)) {
|
|
25262
|
+
if (isRuntimeSparseMatrix(a) && (isRuntimeNumber(b) || isRuntimeLogical(b) || isRuntimeComplexNumber(b) || isRuntimeTensor(b) && b.data.length === 1))
|
|
25263
|
+
return mElemDivSparse(a, b);
|
|
25264
|
+
if (isRuntimeSparseMatrix(b) && !(b.m === 1 && b.n === 1)) {
|
|
25265
|
+
const result = mLeftDiv(mConjugateTranspose(b), mConjugateTranspose(a));
|
|
25266
|
+
return mConjugateTranspose(result);
|
|
25267
|
+
}
|
|
23173
25268
|
return mDiv(densify(a), densify(b));
|
|
23174
25269
|
}
|
|
23175
25270
|
if (isRuntimeTensor(a) && a.data.length === 1) a = unwrap1x1(a);
|
|
@@ -23225,8 +25320,50 @@ function mElemDiv(a, b) {
|
|
|
23225
25320
|
}
|
|
23226
25321
|
return binaryOp(a, b, (x, y) => x / y, BIN_OP_DIV);
|
|
23227
25322
|
}
|
|
25323
|
+
function sparseLeftDiv(A, b) {
|
|
25324
|
+
if (A.pi) return null;
|
|
25325
|
+
if (A.m === 1 && A.n === 1) return null;
|
|
25326
|
+
let B;
|
|
25327
|
+
let rows, nrhs;
|
|
25328
|
+
const bSparse = isRuntimeSparseMatrix(b);
|
|
25329
|
+
if (isRuntimeSparseMatrix(b)) {
|
|
25330
|
+
if (b.pi) return null;
|
|
25331
|
+
const d = sparseToDense(b);
|
|
25332
|
+
B = d.data;
|
|
25333
|
+
rows = b.m;
|
|
25334
|
+
nrhs = b.n;
|
|
25335
|
+
} else if (isRuntimeTensor(b)) {
|
|
25336
|
+
if (b.imag) return null;
|
|
25337
|
+
[rows, nrhs] = tensorSize2D(b);
|
|
25338
|
+
B = b.data;
|
|
25339
|
+
} else if (isRuntimeNumber(b) || isRuntimeLogical(b)) {
|
|
25340
|
+
B = allocFloat64Array([toNumber(b)]);
|
|
25341
|
+
rows = 1;
|
|
25342
|
+
nrhs = 1;
|
|
25343
|
+
} else {
|
|
25344
|
+
return null;
|
|
25345
|
+
}
|
|
25346
|
+
if (rows !== A.m)
|
|
25347
|
+
throw new RuntimeError(
|
|
25348
|
+
`mldivide (\\): A is ${A.m}\xD7${A.n} but B has ${rows} rows`
|
|
25349
|
+
);
|
|
25350
|
+
if (A.m !== A.n) {
|
|
25351
|
+
emitWarning(
|
|
25352
|
+
"mldivide: sparse least-squares uses a dense factorization; the sparse matrix is converted to full."
|
|
25353
|
+
);
|
|
25354
|
+
return null;
|
|
25355
|
+
}
|
|
25356
|
+
const X = sparseSolve(A, B, nrhs);
|
|
25357
|
+
if (X === null) return null;
|
|
25358
|
+
if (bSparse) return denseDataToSparse(X, A.n, nrhs);
|
|
25359
|
+
return unwrap1x1(RTV.tensor(X, [A.n, nrhs]));
|
|
25360
|
+
}
|
|
23228
25361
|
function mLeftDiv(a, b) {
|
|
23229
|
-
if (isRuntimeSparseMatrix(a))
|
|
25362
|
+
if (isRuntimeSparseMatrix(a)) {
|
|
25363
|
+
const r = sparseLeftDiv(a, b);
|
|
25364
|
+
if (r !== null) return r;
|
|
25365
|
+
return mLeftDiv(densify(a), densify(b));
|
|
25366
|
+
}
|
|
23230
25367
|
if (isRuntimeSparseMatrix(b)) return mLeftDiv(a, densify(b));
|
|
23231
25368
|
if (isRuntimeTensor(a) && a.data.length === 1) a = unwrap1x1(a);
|
|
23232
25369
|
if (isRuntimeTensor(b) && b.data.length === 1) b = unwrap1x1(b);
|
|
@@ -32626,7 +34763,11 @@ function binop(op, a, b) {
|
|
|
32626
34763
|
result = mElemDiv(mb, ma);
|
|
32627
34764
|
break;
|
|
32628
34765
|
}
|
|
32629
|
-
|
|
34766
|
+
if (isRuntimeSparseMatrix(ma)) {
|
|
34767
|
+
result = mLeftDiv(ma, mb);
|
|
34768
|
+
break;
|
|
34769
|
+
}
|
|
34770
|
+
const tensorA = ma;
|
|
32630
34771
|
const tensorB = isRuntimeNumber(mb) ? RTV.tensor(allocFloat64Array([mb]), [1, 1]) : isRuntimeSparseMatrix(mb) ? sparseToDense(mb) : mb;
|
|
32631
34772
|
if (!isRuntimeTensor(tensorA) || !isRuntimeTensor(tensorB))
|
|
32632
34773
|
throw new RuntimeError(
|
|
@@ -40039,6 +42180,24 @@ defineBuiltin({
|
|
|
40039
42180
|
});
|
|
40040
42181
|
|
|
40041
42182
|
// src/numbl-core/interpreter/builtins/linear-algebra.ts
|
|
42183
|
+
var SPARSE_TYPE = { kind: "sparse_matrix", isComplex: false };
|
|
42184
|
+
function toSparseOperand(v, name) {
|
|
42185
|
+
if (isRuntimeSparseMatrix(v)) return v;
|
|
42186
|
+
if (isRuntimeNumber(v) || typeof v === "boolean")
|
|
42187
|
+
return denseToSparse(RTV.tensor(allocFloat64Array([Number(v)]), [1, 1]));
|
|
42188
|
+
if (isRuntimeTensor(v)) return denseToSparse(v);
|
|
42189
|
+
throw new RuntimeError(`${name}: arguments must be numeric`);
|
|
42190
|
+
}
|
|
42191
|
+
function speyeSparse(n) {
|
|
42192
|
+
const ir = new Int32Array(n);
|
|
42193
|
+
const jc = new Int32Array(n + 1);
|
|
42194
|
+
const pr = allocFloat64Array(n).fill(1);
|
|
42195
|
+
for (let i = 0; i < n; i++) {
|
|
42196
|
+
ir[i] = i;
|
|
42197
|
+
jc[i + 1] = i + 1;
|
|
42198
|
+
}
|
|
42199
|
+
return RTV.sparseMatrix(n, n, ir, jc, pr);
|
|
42200
|
+
}
|
|
40042
42201
|
function isNumericJitType(t) {
|
|
40043
42202
|
return t.kind === "number" || t.kind === "boolean" || t.kind === "complex_or_number" || t.kind === "tensor" || t.kind === "sparse_matrix";
|
|
40044
42203
|
}
|
|
@@ -40079,12 +42238,53 @@ function normApply(args) {
|
|
|
40079
42238
|
const v = args[0];
|
|
40080
42239
|
if (isRuntimeNumber(v)) return RTV.num(Math.abs(v));
|
|
40081
42240
|
if (isRuntimeComplexNumber(v)) return RTV.num(Math.hypot(v.re, v.im));
|
|
40082
|
-
if (isRuntimeSparseMatrix(v))
|
|
42241
|
+
if (isRuntimeSparseMatrix(v)) {
|
|
42242
|
+
const fast = sparseNormFast(v, args[1]);
|
|
42243
|
+
if (fast !== null) return RTV.num(fast);
|
|
40083
42244
|
return normApply([sparseToDense(v), ...args.slice(1)]);
|
|
42245
|
+
}
|
|
40084
42246
|
if (!isRuntimeTensor(v))
|
|
40085
42247
|
throw new RuntimeError("norm: argument must be numeric");
|
|
40086
42248
|
return normImplTensor(v, args);
|
|
40087
42249
|
}
|
|
42250
|
+
function sparseNormFast(S, p2) {
|
|
42251
|
+
if (S.m === 1 || S.n === 1) return null;
|
|
42252
|
+
let kind = null;
|
|
42253
|
+
if (p2 === void 0) return null;
|
|
42254
|
+
if (isRuntimeNumber(p2)) {
|
|
42255
|
+
if (p2 === 1) kind = "one";
|
|
42256
|
+
else if (p2 === Infinity) kind = "inf";
|
|
42257
|
+
} else if (isRuntimeChar(p2) || isRuntimeString(p2)) {
|
|
42258
|
+
const s = parseStringArgLower(p2);
|
|
42259
|
+
if (s === "fro") kind = "fro";
|
|
42260
|
+
else if (s === "inf") kind = "inf";
|
|
42261
|
+
}
|
|
42262
|
+
if (kind === null) return null;
|
|
42263
|
+
const mag2 = (k) => S.pi ? Math.hypot(S.pr[k], S.pi[k]) : Math.abs(S.pr[k]);
|
|
42264
|
+
const nnz = S.jc[S.n];
|
|
42265
|
+
if (kind === "fro") {
|
|
42266
|
+
let sum2 = 0;
|
|
42267
|
+
for (let k = 0; k < nnz; k++) {
|
|
42268
|
+
const a = mag2(k);
|
|
42269
|
+
sum2 += a * a;
|
|
42270
|
+
}
|
|
42271
|
+
return Math.sqrt(sum2);
|
|
42272
|
+
}
|
|
42273
|
+
if (kind === "one") {
|
|
42274
|
+
let best2 = 0;
|
|
42275
|
+
for (let j = 0; j < S.n; j++) {
|
|
42276
|
+
let sum2 = 0;
|
|
42277
|
+
for (let k = S.jc[j]; k < S.jc[j + 1]; k++) sum2 += mag2(k);
|
|
42278
|
+
if (sum2 > best2) best2 = sum2;
|
|
42279
|
+
}
|
|
42280
|
+
return best2;
|
|
42281
|
+
}
|
|
42282
|
+
const rowSums = allocFloat64Array(S.m);
|
|
42283
|
+
for (let k = 0; k < nnz; k++) rowSums[S.ir[k]] += mag2(k);
|
|
42284
|
+
let best = 0;
|
|
42285
|
+
for (let i = 0; i < S.m; i++) if (rowSums[i] > best) best = rowSums[i];
|
|
42286
|
+
return best;
|
|
42287
|
+
}
|
|
40088
42288
|
function scaledEuclid(magnitudes, count) {
|
|
40089
42289
|
let scale = 0;
|
|
40090
42290
|
let ssq = 1;
|
|
@@ -40709,11 +42909,18 @@ defineBuiltin({
|
|
|
40709
42909
|
if (a.kind === "complex_or_number") return [COMPLEX_OR_NUM];
|
|
40710
42910
|
if (a.kind === "tensor")
|
|
40711
42911
|
return [{ kind: "tensor", isComplex: a.isComplex }];
|
|
42912
|
+
if (a.kind === "sparse_matrix")
|
|
42913
|
+
return [{ kind: "sparse_matrix", isComplex: a.isComplex }];
|
|
40712
42914
|
return null;
|
|
40713
42915
|
},
|
|
40714
|
-
apply: (args)
|
|
42916
|
+
apply: function invApply(args) {
|
|
40715
42917
|
if (args.length < 1) throw new RuntimeError("inv requires 1 argument");
|
|
40716
42918
|
const A = args[0];
|
|
42919
|
+
if (isRuntimeSparseMatrix(A)) {
|
|
42920
|
+
if (!A.pi) return sparseInverse(A);
|
|
42921
|
+
const dense = invApply([sparseToDense(A)]);
|
|
42922
|
+
return isRuntimeTensor(dense) ? denseToSparse(dense) : dense;
|
|
42923
|
+
}
|
|
40717
42924
|
if (isRuntimeComplexNumber(A)) {
|
|
40718
42925
|
const { re, im } = A;
|
|
40719
42926
|
if (re === 0 && im === 0)
|
|
@@ -41066,6 +43273,67 @@ registerIBuiltin({
|
|
|
41066
43273
|
return { outputTypes: outs, apply: (args, n) => bandwidthApply(args, n) };
|
|
41067
43274
|
}
|
|
41068
43275
|
});
|
|
43276
|
+
function isTriangularValue(A, upper) {
|
|
43277
|
+
if (isRuntimeNumber(A) || isRuntimeComplexNumber(A)) return true;
|
|
43278
|
+
if (isRuntimeSparseMatrix(A))
|
|
43279
|
+
return upper ? sparseIsUpper(A) : sparseIsLower(A);
|
|
43280
|
+
if (isRuntimeTensor(A)) {
|
|
43281
|
+
if (A.shape.length > 2) return false;
|
|
43282
|
+
const [m, n] = tensorSize2D(A);
|
|
43283
|
+
for (let j = 0; j < n; j++)
|
|
43284
|
+
for (let i = 0; i < m; i++) {
|
|
43285
|
+
if (upper ? i <= j : i >= j) continue;
|
|
43286
|
+
const idx = colMajorIndex(i, j, m);
|
|
43287
|
+
if (A.data[idx] !== 0 || A.imag && A.imag[idx] !== 0) return false;
|
|
43288
|
+
}
|
|
43289
|
+
return true;
|
|
43290
|
+
}
|
|
43291
|
+
throw new RuntimeError("istriu: argument must be a numeric matrix");
|
|
43292
|
+
}
|
|
43293
|
+
for (const [name, upper] of [
|
|
43294
|
+
["istriu", true],
|
|
43295
|
+
["istril", false]
|
|
43296
|
+
]) {
|
|
43297
|
+
registerIBuiltin({
|
|
43298
|
+
name,
|
|
43299
|
+
help: {
|
|
43300
|
+
signatures: [`tf = ${name}(A)`],
|
|
43301
|
+
description: `True if A is ${upper ? "upper" : "lower"} triangular (all entries ${upper ? "below" : "above"} the main diagonal are zero). Works for dense and sparse matrices.`
|
|
43302
|
+
},
|
|
43303
|
+
resolve: (argTypes, nargout) => {
|
|
43304
|
+
if (nargout > 1 || argTypes.length !== 1) return null;
|
|
43305
|
+
if (!isNumericJitType(argTypes[0])) return null;
|
|
43306
|
+
return {
|
|
43307
|
+
outputTypes: [{ kind: "boolean" }],
|
|
43308
|
+
apply: (args) => RTV.logical(isTriangularValue(args[0], upper))
|
|
43309
|
+
};
|
|
43310
|
+
}
|
|
43311
|
+
});
|
|
43312
|
+
}
|
|
43313
|
+
registerIBuiltin({
|
|
43314
|
+
name: "isbanded",
|
|
43315
|
+
help: {
|
|
43316
|
+
signatures: ["tf = isbanded(A, lower, upper)"],
|
|
43317
|
+
description: "True if A has lower bandwidth at most `lower` and upper bandwidth at most `upper`. Works for dense and sparse matrices."
|
|
43318
|
+
},
|
|
43319
|
+
resolve: (argTypes, nargout) => {
|
|
43320
|
+
if (nargout > 1 || argTypes.length !== 3) return null;
|
|
43321
|
+
if (!isNumericJitType(argTypes[0])) return null;
|
|
43322
|
+
return {
|
|
43323
|
+
outputTypes: [{ kind: "boolean" }],
|
|
43324
|
+
apply: (args) => {
|
|
43325
|
+
const lo = toNumber(args[1]);
|
|
43326
|
+
const up = toNumber(args[2]);
|
|
43327
|
+
if (lo < 0 || up < 0 || !Number.isInteger(lo) || !Number.isInteger(up))
|
|
43328
|
+
throw new RuntimeError(
|
|
43329
|
+
"isbanded: bandwidths must be nonnegative integers"
|
|
43330
|
+
);
|
|
43331
|
+
const [l, u] = computeBandwidth(args[0]);
|
|
43332
|
+
return RTV.logical(l <= lo && u <= up);
|
|
43333
|
+
}
|
|
43334
|
+
};
|
|
43335
|
+
}
|
|
43336
|
+
});
|
|
41069
43337
|
function computeATA(A_data, m, n) {
|
|
41070
43338
|
const result = allocFloat64Array(n * n);
|
|
41071
43339
|
for (let j = 0; j < n; j++)
|
|
@@ -41434,19 +43702,59 @@ function qrPivotApply(A, m, n, k, econ) {
|
|
|
41434
43702
|
registerIBuiltin({
|
|
41435
43703
|
name: "lu",
|
|
41436
43704
|
resolve: (argTypes, nargout) => {
|
|
41437
|
-
if (nargout < 0 || nargout >
|
|
41438
|
-
if (argTypes.length < 1 || argTypes.length >
|
|
43705
|
+
if (nargout < 0 || nargout > 4) return null;
|
|
43706
|
+
if (argTypes.length < 1 || argTypes.length > 3) return null;
|
|
41439
43707
|
if (!isNumericJitType(argTypes[0])) return null;
|
|
41440
|
-
const
|
|
43708
|
+
const sparse = argTypes[0].kind === "sparse_matrix";
|
|
43709
|
+
if (!sparse && (nargout > 3 || argTypes.length > 2)) return null;
|
|
43710
|
+
const t = sparse ? SPARSE_TYPE : tensorType();
|
|
41441
43711
|
const wrapped = (args, n) => withScratch(() => luApply(args, n));
|
|
41442
43712
|
if (nargout <= 1) return { outputTypes: [t], apply: wrapped };
|
|
41443
43713
|
if (nargout === 2) return { outputTypes: [t, t], apply: wrapped };
|
|
41444
|
-
return { outputTypes: [t, t, t], apply: wrapped };
|
|
43714
|
+
if (nargout === 3) return { outputTypes: [t, t, t], apply: wrapped };
|
|
43715
|
+
return { outputTypes: [t, t, t, t], apply: wrapped };
|
|
41445
43716
|
}
|
|
41446
43717
|
});
|
|
43718
|
+
function sparseLuApply(S, args, nargout) {
|
|
43719
|
+
let outputForm = "matrix";
|
|
43720
|
+
let tol = nargout >= 4 ? 0.1 : 1;
|
|
43721
|
+
for (const opt of args.slice(1)) {
|
|
43722
|
+
if (isRuntimeNumber(opt)) {
|
|
43723
|
+
if (!(opt >= 0 && opt <= 1))
|
|
43724
|
+
throw new RuntimeError("lu: pivot threshold must be in [0, 1]");
|
|
43725
|
+
tol = opt;
|
|
43726
|
+
} else {
|
|
43727
|
+
const form = parseLuOutputForm(opt);
|
|
43728
|
+
if (form === null)
|
|
43729
|
+
throw new RuntimeError("lu: outputForm must be 'matrix' or 'vector'");
|
|
43730
|
+
outputForm = form;
|
|
43731
|
+
}
|
|
43732
|
+
}
|
|
43733
|
+
const q = nargout >= 4 ? columnOrdering(S) : null;
|
|
43734
|
+
const res = sparseLu(S, q, tol);
|
|
43735
|
+
const { L, U, p: p2 } = res;
|
|
43736
|
+
if (nargout <= 1) {
|
|
43737
|
+
return mSub(mAdd(L, U), speyeSparse(Math.min(S.m, S.n)));
|
|
43738
|
+
}
|
|
43739
|
+
if (nargout === 2) {
|
|
43740
|
+
const Lperm = sparsePermute(L, invertPerm(p2), identityPerm(L.n));
|
|
43741
|
+
return [Lperm, U];
|
|
43742
|
+
}
|
|
43743
|
+
const permOut = (perm) => outputForm === "vector" ? permVectorTensor(perm) : permutationMatrix(perm);
|
|
43744
|
+
if (nargout === 3) return [L, U, permOut(p2)];
|
|
43745
|
+
const Q = outputForm === "vector" ? permVectorTensor(res.q) : sparseTranspose(permutationMatrix(res.q));
|
|
43746
|
+
return [L, U, permOut(p2), Q];
|
|
43747
|
+
}
|
|
41447
43748
|
function luApply(args, nargout) {
|
|
41448
43749
|
if (args.length < 1)
|
|
41449
43750
|
throw new RuntimeError("lu requires at least 1 argument");
|
|
43751
|
+
if (isRuntimeSparseMatrix(args[0]) && !args[0].pi)
|
|
43752
|
+
return sparseLuApply(args[0], args, nargout);
|
|
43753
|
+
if (isRuntimeSparseMatrix(args[0])) {
|
|
43754
|
+
const dense = luApply([sparseToDense(args[0]), ...args.slice(1)], nargout);
|
|
43755
|
+
const toSp = (v) => isRuntimeTensor(v) ? denseToSparse(v) : v;
|
|
43756
|
+
return Array.isArray(dense) ? dense.map(toSp) : toSp(dense);
|
|
43757
|
+
}
|
|
41450
43758
|
const outputForm = args.length >= 2 ? parseLuOutputForm(args[1]) : "matrix";
|
|
41451
43759
|
if (outputForm === null)
|
|
41452
43760
|
throw new RuntimeError("lu: outputForm must be 'matrix' or 'vector'");
|
|
@@ -41565,7 +43873,7 @@ function ipivToPermVector(ipiv, m) {
|
|
|
41565
43873
|
registerIBuiltin({
|
|
41566
43874
|
name: "eig",
|
|
41567
43875
|
resolve: (argTypes, nargout) => {
|
|
41568
|
-
if (nargout < 0 || nargout > 3 || argTypes.length < 1 || argTypes.length >
|
|
43876
|
+
if (nargout < 0 || nargout > 3 || argTypes.length < 1 || argTypes.length > 4)
|
|
41569
43877
|
return null;
|
|
41570
43878
|
if (!isNumericJitType(argTypes[0])) return null;
|
|
41571
43879
|
const c = tensorType(true);
|
|
@@ -41580,7 +43888,9 @@ function eigApply(args, nargout) {
|
|
|
41580
43888
|
if (args.length < 1)
|
|
41581
43889
|
throw new RuntimeError("eig requires at least 1 argument");
|
|
41582
43890
|
const A = args[0];
|
|
41583
|
-
const { balance, outputForm } = parseEigOptionsRuntime(args);
|
|
43891
|
+
const { B, balance, outputForm, algorithm } = parseEigOptionsRuntime(args);
|
|
43892
|
+
if (B !== void 0)
|
|
43893
|
+
return eigGeneralizedApply(A, B, nargout, outputForm, algorithm);
|
|
41584
43894
|
if (isRuntimeNumber(A)) {
|
|
41585
43895
|
const val = A;
|
|
41586
43896
|
if (nargout <= 1) return RTV.num(val);
|
|
@@ -41597,6 +43907,10 @@ function eigApply(args, nargout) {
|
|
|
41597
43907
|
const [m, n] = tensorSize2D(A);
|
|
41598
43908
|
if (m !== n) throw new RuntimeError("eig: input must be a square matrix");
|
|
41599
43909
|
const computeVL = nargout >= 3, computeVR = nargout >= 2;
|
|
43910
|
+
if (isExactlyHermitian(A, n)) {
|
|
43911
|
+
const symResult = eigSymmetricApply(A, n, nargout, outputForm);
|
|
43912
|
+
if (symResult) return symResult;
|
|
43913
|
+
}
|
|
41600
43914
|
if (A.imag) {
|
|
41601
43915
|
const bridge2 = getEffectiveBridge("eigComplex", "eigComplex");
|
|
41602
43916
|
if (!bridge2.eigComplex)
|
|
@@ -41632,19 +43946,369 @@ function eigApply(args, nargout) {
|
|
|
41632
43946
|
const Wout = computeVL && VL ? buildEigenvectorMatrix(VL, wi, n, hasComplex) : RTV.tensor(allocFloat64Array(n * n), [n, n]);
|
|
41633
43947
|
return [Vout, Dout, Wout];
|
|
41634
43948
|
}
|
|
43949
|
+
function isExactlyHermitian(A, n) {
|
|
43950
|
+
const re = A.data;
|
|
43951
|
+
const im = A.imag;
|
|
43952
|
+
for (let j = 0; j < n; j++) {
|
|
43953
|
+
if (im && im[j + j * n] !== 0) return false;
|
|
43954
|
+
const dj = re[j + j * n];
|
|
43955
|
+
if (Number.isNaN(dj)) return false;
|
|
43956
|
+
for (let i = j + 1; i < n; i++) {
|
|
43957
|
+
if (re[i + j * n] !== re[j + i * n]) return false;
|
|
43958
|
+
if (im && im[i + j * n] !== -im[j + i * n]) return false;
|
|
43959
|
+
}
|
|
43960
|
+
}
|
|
43961
|
+
return true;
|
|
43962
|
+
}
|
|
43963
|
+
function eigSymmetricApply(A, n, nargout, outputForm) {
|
|
43964
|
+
const computeV = nargout >= 2;
|
|
43965
|
+
let w;
|
|
43966
|
+
let VRe;
|
|
43967
|
+
let VIm;
|
|
43968
|
+
if (A.imag) {
|
|
43969
|
+
const bridge = getEffectiveBridge("eigHerm", "eigHerm");
|
|
43970
|
+
if (!bridge.eigHerm) return null;
|
|
43971
|
+
const r = bridge.eigHerm(toF64(A.data), toF64(A.imag), n, computeV);
|
|
43972
|
+
if (!r) return null;
|
|
43973
|
+
w = r.w;
|
|
43974
|
+
VRe = r.VRe;
|
|
43975
|
+
VIm = r.VIm;
|
|
43976
|
+
} else {
|
|
43977
|
+
const bridge = getEffectiveBridge("eigSym", "eigSym");
|
|
43978
|
+
if (!bridge.eigSym) return null;
|
|
43979
|
+
const r = bridge.eigSym(toF64(A.data), n, computeV);
|
|
43980
|
+
if (!r) return null;
|
|
43981
|
+
w = r.w;
|
|
43982
|
+
VRe = r.V;
|
|
43983
|
+
}
|
|
43984
|
+
if (nargout <= 1) return RTV.tensor(w, [n, 1]);
|
|
43985
|
+
const makeV = () => VRe ? maybeComplexTensor(
|
|
43986
|
+
allocFloat64Array(VRe),
|
|
43987
|
+
[n, n],
|
|
43988
|
+
VIm ? allocFloat64Array(VIm) : void 0
|
|
43989
|
+
) : RTV.tensor(allocFloat64Array(n * n), [n, n]);
|
|
43990
|
+
const Vout = makeV();
|
|
43991
|
+
const Dout = outputForm === "vector" ? RTV.tensor(allocFloat64Array(w), [n, 1]) : buildDiagMatrix(w, void 0, n);
|
|
43992
|
+
if (nargout === 2) return [Vout, Dout];
|
|
43993
|
+
return [Vout, Dout, makeV()];
|
|
43994
|
+
}
|
|
41635
43995
|
function parseEigOptionsRuntime(args) {
|
|
41636
|
-
let balance = true, outputForm = "matrix";
|
|
41637
|
-
|
|
43996
|
+
let balance = true, outputForm = "matrix", algorithm = "auto";
|
|
43997
|
+
let B;
|
|
43998
|
+
let first = 1;
|
|
43999
|
+
if (args.length >= 2 && !isStringLikeArg(args[1])) {
|
|
44000
|
+
B = args[1];
|
|
44001
|
+
first = 2;
|
|
44002
|
+
}
|
|
44003
|
+
for (let i = first; i < args.length; i++) {
|
|
41638
44004
|
const arg = args[i];
|
|
41639
|
-
if (
|
|
41640
|
-
|
|
41641
|
-
|
|
41642
|
-
|
|
41643
|
-
|
|
41644
|
-
|
|
44005
|
+
if (!isStringLikeArg(arg))
|
|
44006
|
+
throw new RuntimeError(
|
|
44007
|
+
"eig: option arguments must be character vectors or strings"
|
|
44008
|
+
);
|
|
44009
|
+
const val = parseStringArgLower(arg);
|
|
44010
|
+
if (val === "nobalance") balance = false;
|
|
44011
|
+
else if (val === "balance") balance = true;
|
|
44012
|
+
else if (val === "vector") outputForm = "vector";
|
|
44013
|
+
else if (val === "matrix") outputForm = "matrix";
|
|
44014
|
+
else if (val === "chol" || val === "qz") algorithm = val;
|
|
44015
|
+
else throw new RuntimeError(`eig: unknown option '${val}'`);
|
|
44016
|
+
}
|
|
44017
|
+
if (algorithm !== "auto" && B === void 0)
|
|
44018
|
+
throw new RuntimeError(
|
|
44019
|
+
`eig: the '${algorithm}' algorithm applies only to eig(A, B)`
|
|
44020
|
+
);
|
|
44021
|
+
return { B, balance, outputForm, algorithm };
|
|
44022
|
+
}
|
|
44023
|
+
function isStringLikeArg(arg) {
|
|
44024
|
+
return isRuntimeString(arg) || isRuntimeChar(arg);
|
|
44025
|
+
}
|
|
44026
|
+
function toSplitSquare(v, name) {
|
|
44027
|
+
if (isRuntimeNumber(v))
|
|
44028
|
+
return { M: { re: allocFloat64Array([v]), im: null }, n: 1 };
|
|
44029
|
+
if (isRuntimeComplexNumber(v))
|
|
44030
|
+
return {
|
|
44031
|
+
M: { re: allocFloat64Array([v.re]), im: allocFloat64Array([v.im]) },
|
|
44032
|
+
n: 1
|
|
44033
|
+
};
|
|
44034
|
+
let t = v;
|
|
44035
|
+
if (isRuntimeSparseMatrix(t))
|
|
44036
|
+
t = sparseToDense(
|
|
44037
|
+
t
|
|
44038
|
+
);
|
|
44039
|
+
if (!isRuntimeTensor(t))
|
|
44040
|
+
throw new RuntimeError(`eig: ${name} must be a numeric matrix`);
|
|
44041
|
+
const [rows, cols] = tensorSize2D(t);
|
|
44042
|
+
if (rows !== cols)
|
|
44043
|
+
throw new RuntimeError(`eig: ${name} must be a square matrix`);
|
|
44044
|
+
return {
|
|
44045
|
+
M: { re: toF64(t.data), im: t.imag ? toF64(t.imag) : null },
|
|
44046
|
+
n: rows
|
|
44047
|
+
};
|
|
44048
|
+
}
|
|
44049
|
+
function splitIsHermitian(M, n) {
|
|
44050
|
+
for (let j = 0; j < n; j++) {
|
|
44051
|
+
if (M.im && M.im[j + j * n] !== 0) return false;
|
|
44052
|
+
if (Number.isNaN(M.re[j + j * n])) return false;
|
|
44053
|
+
for (let i = j + 1; i < n; i++) {
|
|
44054
|
+
if (M.re[i + j * n] !== M.re[j + i * n]) return false;
|
|
44055
|
+
if (M.im && M.im[i + j * n] !== -M.im[j + i * n]) return false;
|
|
44056
|
+
}
|
|
44057
|
+
}
|
|
44058
|
+
return true;
|
|
44059
|
+
}
|
|
44060
|
+
function eigGeneralizedApply(Aval, Bval, nargout, outputForm, algorithm) {
|
|
44061
|
+
const { M: A, n } = toSplitSquare(Aval, "A");
|
|
44062
|
+
const { M: B, n: nB } = toSplitSquare(Bval, "B");
|
|
44063
|
+
if (n !== nB) throw new RuntimeError("eig: A and B must be the same size");
|
|
44064
|
+
if (algorithm !== "qz" && splitIsHermitian(A, n) && splitIsHermitian(B, n)) {
|
|
44065
|
+
const R = choleskyFactor(B, n);
|
|
44066
|
+
if (R) return eigSymmetricDefinite(A, R, n, nargout, outputForm);
|
|
44067
|
+
if (algorithm === "chol")
|
|
44068
|
+
throw new RuntimeError(
|
|
44069
|
+
"eig: the 'chol' algorithm requires B to be symmetric positive definite"
|
|
44070
|
+
);
|
|
44071
|
+
}
|
|
44072
|
+
return eigGeneralizedQz(A, B, n, nargout, outputForm);
|
|
44073
|
+
}
|
|
44074
|
+
function choleskyFactor(B, n) {
|
|
44075
|
+
if (B.im) {
|
|
44076
|
+
const bridge2 = getEffectiveBridge("cholComplex", "cholComplex");
|
|
44077
|
+
if (!bridge2.cholComplex) return null;
|
|
44078
|
+
const r2 = bridge2.cholComplex(B.re, B.im, n, true);
|
|
44079
|
+
if (!r2 || r2.info !== 0) return null;
|
|
44080
|
+
return { re: r2.RRe, im: r2.RIm };
|
|
44081
|
+
}
|
|
44082
|
+
const bridge = getEffectiveBridge("chol", "chol");
|
|
44083
|
+
if (!bridge.chol) return null;
|
|
44084
|
+
const r = bridge.chol(B.re, n, true);
|
|
44085
|
+
if (!r || r.info !== 0) return null;
|
|
44086
|
+
return { re: r.R, im: null };
|
|
44087
|
+
}
|
|
44088
|
+
function eigSymmetricDefinite(A, R, n, nargout, outputForm) {
|
|
44089
|
+
const complex = !!(A.im || R.im);
|
|
44090
|
+
const Y = solveLeftConjTransposeUpper(R, A, n, complex);
|
|
44091
|
+
const C = solveRightUpper(Y, R, n, complex);
|
|
44092
|
+
symmetrizeInPlace(C, n);
|
|
44093
|
+
const computeV = nargout >= 2;
|
|
44094
|
+
let w;
|
|
44095
|
+
let SRe;
|
|
44096
|
+
let SIm;
|
|
44097
|
+
if (complex) {
|
|
44098
|
+
const bridge = getEffectiveBridge("eigHerm", "eigHerm");
|
|
44099
|
+
if (!bridge.eigHerm)
|
|
44100
|
+
throw new RuntimeError("eig: Hermitian eig bridge not available");
|
|
44101
|
+
const r = bridge.eigHerm(
|
|
44102
|
+
C.re,
|
|
44103
|
+
C.im ?? allocFloat64Array(n * n),
|
|
44104
|
+
n,
|
|
44105
|
+
computeV
|
|
44106
|
+
);
|
|
44107
|
+
w = r.w;
|
|
44108
|
+
SRe = r.VRe;
|
|
44109
|
+
SIm = r.VIm;
|
|
44110
|
+
} else {
|
|
44111
|
+
const bridge = getEffectiveBridge("eigSym", "eigSym");
|
|
44112
|
+
if (!bridge.eigSym)
|
|
44113
|
+
throw new RuntimeError("eig: symmetric eig bridge not available");
|
|
44114
|
+
const r = bridge.eigSym(C.re, n, computeV);
|
|
44115
|
+
w = r.w;
|
|
44116
|
+
SRe = r.V;
|
|
44117
|
+
}
|
|
44118
|
+
if (nargout <= 1) return RTV.tensor(w, [n, 1]);
|
|
44119
|
+
const S = {
|
|
44120
|
+
re: SRe ?? allocFloat64Array(n * n),
|
|
44121
|
+
im: SIm ?? null
|
|
44122
|
+
};
|
|
44123
|
+
const V = SRe ? solveUpper(R, S, n, complex) : S;
|
|
44124
|
+
const makeV = () => maybeComplexTensor(
|
|
44125
|
+
allocFloat64Array(V.re),
|
|
44126
|
+
[n, n],
|
|
44127
|
+
V.im ? allocFloat64Array(V.im) : void 0
|
|
44128
|
+
);
|
|
44129
|
+
const Vout = makeV();
|
|
44130
|
+
const Dout = outputForm === "vector" ? RTV.tensor(allocFloat64Array(w), [n, 1]) : buildDiagMatrix(w, void 0, n);
|
|
44131
|
+
if (nargout === 2) return [Vout, Dout];
|
|
44132
|
+
return [Vout, Dout, makeV()];
|
|
44133
|
+
}
|
|
44134
|
+
function symmetrizeInPlace(M, n) {
|
|
44135
|
+
for (let j = 0; j < n; j++) {
|
|
44136
|
+
if (M.im) M.im[j + j * n] = 0;
|
|
44137
|
+
for (let i = j + 1; i < n; i++) {
|
|
44138
|
+
const a = (M.re[i + j * n] + M.re[j + i * n]) / 2;
|
|
44139
|
+
M.re[i + j * n] = a;
|
|
44140
|
+
M.re[j + i * n] = a;
|
|
44141
|
+
if (M.im) {
|
|
44142
|
+
const b = (M.im[i + j * n] - M.im[j + i * n]) / 2;
|
|
44143
|
+
M.im[i + j * n] = b;
|
|
44144
|
+
M.im[j + i * n] = -b;
|
|
44145
|
+
}
|
|
44146
|
+
}
|
|
44147
|
+
}
|
|
44148
|
+
}
|
|
44149
|
+
function solveLeftConjTransposeUpper(R, Bm, n, complex) {
|
|
44150
|
+
const X = {
|
|
44151
|
+
re: allocFloat64Array(n * n),
|
|
44152
|
+
im: complex ? allocFloat64Array(n * n) : null
|
|
44153
|
+
};
|
|
44154
|
+
for (let c = 0; c < n; c++) {
|
|
44155
|
+
for (let i = 0; i < n; i++) {
|
|
44156
|
+
let sr = Bm.re[i + c * n];
|
|
44157
|
+
let si = Bm.im ? Bm.im[i + c * n] : 0;
|
|
44158
|
+
for (let k = 0; k < i; k++) {
|
|
44159
|
+
const lr = R.re[k + i * n];
|
|
44160
|
+
const li = R.im ? -R.im[k + i * n] : 0;
|
|
44161
|
+
const xr = X.re[k + c * n];
|
|
44162
|
+
const xi = X.im ? X.im[k + c * n] : 0;
|
|
44163
|
+
sr -= lr * xr - li * xi;
|
|
44164
|
+
si -= lr * xi + li * xr;
|
|
44165
|
+
}
|
|
44166
|
+
const dr = R.re[i + i * n];
|
|
44167
|
+
const di = R.im ? -R.im[i + i * n] : 0;
|
|
44168
|
+
const [qr2, qi] = complexDivide2(sr, si, dr, di);
|
|
44169
|
+
X.re[i + c * n] = qr2;
|
|
44170
|
+
if (X.im) X.im[i + c * n] = qi;
|
|
44171
|
+
}
|
|
44172
|
+
}
|
|
44173
|
+
return X;
|
|
44174
|
+
}
|
|
44175
|
+
function solveRightUpper(Y, R, n, complex) {
|
|
44176
|
+
const C = {
|
|
44177
|
+
re: allocFloat64Array(n * n),
|
|
44178
|
+
im: complex ? allocFloat64Array(n * n) : null
|
|
44179
|
+
};
|
|
44180
|
+
for (let j = 0; j < n; j++) {
|
|
44181
|
+
for (let i = 0; i < n; i++) {
|
|
44182
|
+
let sr = Y.re[i + j * n];
|
|
44183
|
+
let si = Y.im ? Y.im[i + j * n] : 0;
|
|
44184
|
+
for (let k = 0; k < j; k++) {
|
|
44185
|
+
const cr = C.re[i + k * n];
|
|
44186
|
+
const ci = C.im ? C.im[i + k * n] : 0;
|
|
44187
|
+
const rr = R.re[k + j * n];
|
|
44188
|
+
const ri = R.im ? R.im[k + j * n] : 0;
|
|
44189
|
+
sr -= cr * rr - ci * ri;
|
|
44190
|
+
si -= cr * ri + ci * rr;
|
|
44191
|
+
}
|
|
44192
|
+
const dr = R.re[j + j * n];
|
|
44193
|
+
const di = R.im ? R.im[j + j * n] : 0;
|
|
44194
|
+
const [qr2, qi] = complexDivide2(sr, si, dr, di);
|
|
44195
|
+
C.re[i + j * n] = qr2;
|
|
44196
|
+
if (C.im) C.im[i + j * n] = qi;
|
|
44197
|
+
}
|
|
44198
|
+
}
|
|
44199
|
+
return C;
|
|
44200
|
+
}
|
|
44201
|
+
function solveUpper(R, S, n, complex) {
|
|
44202
|
+
const V = {
|
|
44203
|
+
re: allocFloat64Array(n * n),
|
|
44204
|
+
im: complex ? allocFloat64Array(n * n) : null
|
|
44205
|
+
};
|
|
44206
|
+
for (let c = 0; c < n; c++) {
|
|
44207
|
+
for (let i = n - 1; i >= 0; i--) {
|
|
44208
|
+
let sr = S.re[i + c * n];
|
|
44209
|
+
let si = S.im ? S.im[i + c * n] : 0;
|
|
44210
|
+
for (let k = i + 1; k < n; k++) {
|
|
44211
|
+
const rr = R.re[i + k * n];
|
|
44212
|
+
const ri = R.im ? R.im[i + k * n] : 0;
|
|
44213
|
+
const vr = V.re[k + c * n];
|
|
44214
|
+
const vi = V.im ? V.im[k + c * n] : 0;
|
|
44215
|
+
sr -= rr * vr - ri * vi;
|
|
44216
|
+
si -= rr * vi + ri * vr;
|
|
44217
|
+
}
|
|
44218
|
+
const dr = R.re[i + i * n];
|
|
44219
|
+
const di = R.im ? R.im[i + i * n] : 0;
|
|
44220
|
+
const [qr2, qi] = complexDivide2(sr, si, dr, di);
|
|
44221
|
+
V.re[i + c * n] = qr2;
|
|
44222
|
+
if (V.im) V.im[i + c * n] = qi;
|
|
44223
|
+
}
|
|
44224
|
+
}
|
|
44225
|
+
return V;
|
|
44226
|
+
}
|
|
44227
|
+
function complexDivide2(ar, ai, br, bi) {
|
|
44228
|
+
if (bi === 0) return [ar / br, ai / br];
|
|
44229
|
+
if (Math.abs(br) >= Math.abs(bi)) {
|
|
44230
|
+
const r2 = bi / br;
|
|
44231
|
+
const t2 = br + bi * r2;
|
|
44232
|
+
return [(ar + ai * r2) / t2, (ai - ar * r2) / t2];
|
|
44233
|
+
}
|
|
44234
|
+
const r = br / bi;
|
|
44235
|
+
const t = br * r + bi;
|
|
44236
|
+
return [(ar * r + ai) / t, (ai * r - ar) / t];
|
|
44237
|
+
}
|
|
44238
|
+
function eigGeneralizedQz(A, B, n, nargout, outputForm) {
|
|
44239
|
+
const computeEigvecs = nargout >= 2;
|
|
44240
|
+
const wr = allocFloat64Array(n);
|
|
44241
|
+
const wi = allocFloat64Array(n);
|
|
44242
|
+
let V = null;
|
|
44243
|
+
let W = null;
|
|
44244
|
+
if (A.im || B.im) {
|
|
44245
|
+
const bridge = getEffectiveBridge("qzComplex", "qzComplex");
|
|
44246
|
+
if (!bridge.qzComplex) throw generalizedUnsupported();
|
|
44247
|
+
const r = bridge.qzComplex(
|
|
44248
|
+
A.re,
|
|
44249
|
+
A.im ?? allocFloat64Array(n * n),
|
|
44250
|
+
B.re,
|
|
44251
|
+
B.im ?? allocFloat64Array(n * n),
|
|
44252
|
+
n,
|
|
44253
|
+
computeEigvecs
|
|
44254
|
+
);
|
|
44255
|
+
if (!r) throw new RuntimeError("eig: complex QZ failed");
|
|
44256
|
+
for (let i = 0; i < n; i++) {
|
|
44257
|
+
const [qr2, qi] = complexDivide2(
|
|
44258
|
+
r.alphaRe[i],
|
|
44259
|
+
r.alphaIm[i],
|
|
44260
|
+
r.betaRe[i],
|
|
44261
|
+
r.betaIm[i]
|
|
44262
|
+
);
|
|
44263
|
+
wr[i] = qr2;
|
|
44264
|
+
wi[i] = qi;
|
|
44265
|
+
}
|
|
44266
|
+
if (computeEigvecs) {
|
|
44267
|
+
if (!r.VRe || !r.VIm || !r.WRe || !r.WIm)
|
|
44268
|
+
throw new RuntimeError(
|
|
44269
|
+
"eig: failed to compute generalized eigenvectors"
|
|
44270
|
+
);
|
|
44271
|
+
V = maybeComplexTensor(
|
|
44272
|
+
allocFloat64Array(r.VRe),
|
|
44273
|
+
[n, n],
|
|
44274
|
+
allocFloat64Array(r.VIm)
|
|
44275
|
+
);
|
|
44276
|
+
W = maybeComplexTensor(
|
|
44277
|
+
allocFloat64Array(r.WRe),
|
|
44278
|
+
[n, n],
|
|
44279
|
+
allocFloat64Array(r.WIm)
|
|
44280
|
+
);
|
|
44281
|
+
}
|
|
44282
|
+
} else {
|
|
44283
|
+
const bridge = getEffectiveBridge("qz", "qz");
|
|
44284
|
+
if (!bridge.qz) throw generalizedUnsupported();
|
|
44285
|
+
const r = bridge.qz(A.re, B.re, n, computeEigvecs);
|
|
44286
|
+
if (!r) throw new RuntimeError("eig: real QZ failed");
|
|
44287
|
+
let hasComplex = false;
|
|
44288
|
+
for (let i = 0; i < n; i++) {
|
|
44289
|
+
const beta = r.beta[i];
|
|
44290
|
+
wr[i] = r.alphar[i] / beta;
|
|
44291
|
+
wi[i] = r.alphai[i] === 0 && beta === 0 ? 0 : r.alphai[i] / beta;
|
|
44292
|
+
if (r.alphai[i] !== 0) hasComplex = true;
|
|
44293
|
+
}
|
|
44294
|
+
if (computeEigvecs) {
|
|
44295
|
+
if (!r.V || !r.W)
|
|
44296
|
+
throw new RuntimeError(
|
|
44297
|
+
"eig: failed to compute generalized eigenvectors"
|
|
44298
|
+
);
|
|
44299
|
+
V = buildEigenvectorMatrix(r.V, r.alphai, n, hasComplex);
|
|
44300
|
+
W = buildEigenvectorMatrix(r.W, r.alphai, n, hasComplex);
|
|
41645
44301
|
}
|
|
41646
44302
|
}
|
|
41647
|
-
return
|
|
44303
|
+
if (nargout <= 1) return maybeComplexTensor(wr, [n, 1], wi);
|
|
44304
|
+
const Dout = outputForm === "vector" ? maybeComplexTensor(wr, [n, 1], wi) : buildDiagMatrix(wr, wi, n);
|
|
44305
|
+
if (nargout === 2) return [V, Dout];
|
|
44306
|
+
return [V, Dout, W];
|
|
44307
|
+
}
|
|
44308
|
+
function generalizedUnsupported() {
|
|
44309
|
+
return new RuntimeError(
|
|
44310
|
+
"eig: the generalized eigenvalue problem eig(A, B) with a non symmetric-definite pencil requires the native LAPACK addon"
|
|
44311
|
+
);
|
|
41648
44312
|
}
|
|
41649
44313
|
registerIBuiltin({
|
|
41650
44314
|
name: "chol",
|
|
@@ -41652,13 +44316,31 @@ registerIBuiltin({
|
|
|
41652
44316
|
if (nargout < 0 || nargout > 3 || argTypes.length < 1 || argTypes.length > 3)
|
|
41653
44317
|
return null;
|
|
41654
44318
|
if (!isNumericJitType(argTypes[0])) return null;
|
|
41655
|
-
const t = tensorType();
|
|
44319
|
+
const t = argTypes[0].kind === "sparse_matrix" ? SPARSE_TYPE : tensorType();
|
|
41656
44320
|
const wrapped = (args, n) => withScratch(() => cholApply(args, n));
|
|
41657
44321
|
if (nargout <= 1) return { outputTypes: [t], apply: wrapped };
|
|
41658
44322
|
if (nargout === 2) return { outputTypes: [t, NUM], apply: wrapped };
|
|
41659
44323
|
return { outputTypes: [t, NUM, t], apply: wrapped };
|
|
41660
44324
|
}
|
|
41661
44325
|
});
|
|
44326
|
+
function sparseCholApply(S, upper, outputForm, nargout) {
|
|
44327
|
+
if (S.m !== S.n) throw new RuntimeError("chol: Matrix must be square.");
|
|
44328
|
+
const n = S.n;
|
|
44329
|
+
const perm = nargout >= 3 ? minimumDegreeOrdering(S) : identityPerm(n);
|
|
44330
|
+
const A = nargout >= 3 ? sparsePermute(S, perm, perm) : S;
|
|
44331
|
+
const res = sparseChol(A);
|
|
44332
|
+
const R = upper ? sparseTranspose(res.L) : res.L;
|
|
44333
|
+
const permOut = () => outputForm === "vector" ? permVectorTensor(perm) : permutationMatrix(invertPerm(perm));
|
|
44334
|
+
if (!res.ok) {
|
|
44335
|
+
if (nargout < 2)
|
|
44336
|
+
throw new RuntimeError("chol: Matrix must be positive definite.");
|
|
44337
|
+
if (nargout >= 3) return [R, RTV.num(res.p), permOut()];
|
|
44338
|
+
return [R, RTV.num(res.p)];
|
|
44339
|
+
}
|
|
44340
|
+
if (nargout >= 3) return [R, RTV.num(0), permOut()];
|
|
44341
|
+
if (nargout === 2) return [R, RTV.num(0)];
|
|
44342
|
+
return R;
|
|
44343
|
+
}
|
|
41662
44344
|
function cholApply(args, nargout) {
|
|
41663
44345
|
if (args.length < 1)
|
|
41664
44346
|
throw new RuntimeError("chol requires at least 1 argument");
|
|
@@ -41666,10 +44348,9 @@ function cholApply(args, nargout) {
|
|
|
41666
44348
|
const inputIsSparse = isRuntimeSparseMatrix(A);
|
|
41667
44349
|
if (nargout >= 3 && !inputIsSparse)
|
|
41668
44350
|
throw new RuntimeError("Third output only available for sparse matrices.");
|
|
41669
|
-
|
|
41670
|
-
|
|
41671
|
-
|
|
41672
|
-
);
|
|
44351
|
+
const sparseInput = isRuntimeSparseMatrix(A) && !A.pi ? A : null;
|
|
44352
|
+
if (inputIsSparse && !sparseInput)
|
|
44353
|
+
A = sparseToDense(A);
|
|
41673
44354
|
let triangle = "upper";
|
|
41674
44355
|
let outputForm = "matrix";
|
|
41675
44356
|
if (args.length === 2) {
|
|
@@ -41688,6 +44369,8 @@ function cholApply(args, nargout) {
|
|
|
41688
44369
|
outputForm = form;
|
|
41689
44370
|
}
|
|
41690
44371
|
const upper = triangle === "upper";
|
|
44372
|
+
if (sparseInput)
|
|
44373
|
+
return sparseCholApply(sparseInput, upper, outputForm, nargout);
|
|
41691
44374
|
if (isRuntimeNumber(A)) {
|
|
41692
44375
|
const val = A;
|
|
41693
44376
|
if (val <= 0) {
|
|
@@ -42105,15 +44788,28 @@ defineBuiltin({
|
|
|
42105
44788
|
if (nargout > 1 || argTypes.length !== 2) return null;
|
|
42106
44789
|
if (!isNumericJitType(argTypes[0]) || !isNumericJitType(argTypes[1]))
|
|
42107
44790
|
return null;
|
|
44791
|
+
if (argTypes.some((t) => t.kind === "sparse_matrix"))
|
|
44792
|
+
return [
|
|
44793
|
+
{
|
|
44794
|
+
kind: "sparse_matrix",
|
|
44795
|
+
isComplex: argTypes.some(
|
|
44796
|
+
(t) => t.kind === "sparse_matrix" && t.isComplex
|
|
44797
|
+
)
|
|
44798
|
+
}
|
|
44799
|
+
];
|
|
42108
44800
|
return [tensorType()];
|
|
42109
44801
|
},
|
|
42110
44802
|
apply: (args) => {
|
|
42111
44803
|
if (args.length !== 2)
|
|
42112
44804
|
throw new RuntimeError("kron requires 2 arguments");
|
|
44805
|
+
if (isRuntimeSparseMatrix(args[0]) || isRuntimeSparseMatrix(args[1]))
|
|
44806
|
+
return sparseKron(
|
|
44807
|
+
toSparseOperand(args[0], "kron"),
|
|
44808
|
+
toSparseOperand(args[1], "kron")
|
|
44809
|
+
);
|
|
42113
44810
|
const coerce = (v) => {
|
|
42114
44811
|
if (isRuntimeNumber(v))
|
|
42115
44812
|
return RTV.tensor(allocFloat64Array([v]), [1, 1]);
|
|
42116
|
-
if (isRuntimeSparseMatrix(v)) return sparseToDense(v);
|
|
42117
44813
|
if (isRuntimeTensor(v)) return v;
|
|
42118
44814
|
throw new RuntimeError("kron: arguments must be numeric");
|
|
42119
44815
|
};
|
|
@@ -48811,8 +51507,9 @@ defineBuiltin({
|
|
|
48811
51507
|
cases: [
|
|
48812
51508
|
{
|
|
48813
51509
|
match: (argTypes) => argTypes.length === 0 ? [{ kind: "number" }] : null,
|
|
48814
|
-
apply: () => {
|
|
51510
|
+
apply: (_args, nargout) => {
|
|
48815
51511
|
ticTime = performance.now();
|
|
51512
|
+
if (nargout === 0) return void 0;
|
|
48816
51513
|
return RTV.num(ticTime / 1e3);
|
|
48817
51514
|
}
|
|
48818
51515
|
}
|
|
@@ -49875,6 +52572,585 @@ registerIBuiltin({
|
|
|
49875
52572
|
}
|
|
49876
52573
|
});
|
|
49877
52574
|
|
|
52575
|
+
// src/numbl-core/interpreter/builtins/sparse-solvers.ts
|
|
52576
|
+
function toSparseArg(v, name) {
|
|
52577
|
+
if (isRuntimeSparseMatrix(v)) return v;
|
|
52578
|
+
if (isRuntimeTensor(v)) return denseToSparse(v);
|
|
52579
|
+
if (isRuntimeNumber(v))
|
|
52580
|
+
return denseToSparse(RTV.tensor(allocFloat64Array([v]), [1, 1]));
|
|
52581
|
+
if (isRuntimeLogical(v))
|
|
52582
|
+
return denseToSparse(RTV.tensor(allocFloat64Array([v ? 1 : 0]), [1, 1]));
|
|
52583
|
+
throw new RuntimeError(`${name}: argument must be a numeric matrix`);
|
|
52584
|
+
}
|
|
52585
|
+
var ROW_VECTOR = { kind: "tensor", isComplex: false };
|
|
52586
|
+
registerIBuiltin({
|
|
52587
|
+
name: "symrcm",
|
|
52588
|
+
help: {
|
|
52589
|
+
signatures: ["p = symrcm(A)"],
|
|
52590
|
+
description: "Reverse Cuthill-McKee ordering of the pattern of A + A'. A(p,p) tends to have a smaller bandwidth than A."
|
|
52591
|
+
},
|
|
52592
|
+
resolve: (argTypes, nargout) => {
|
|
52593
|
+
if (argTypes.length !== 1 || nargout > 1) return null;
|
|
52594
|
+
return {
|
|
52595
|
+
outputTypes: [ROW_VECTOR],
|
|
52596
|
+
apply: (args) => permVectorTensor(reverseCuthillMcKee(toSparseArg(args[0], "symrcm")))
|
|
52597
|
+
};
|
|
52598
|
+
}
|
|
52599
|
+
});
|
|
52600
|
+
registerIBuiltin({
|
|
52601
|
+
name: "amd",
|
|
52602
|
+
help: {
|
|
52603
|
+
signatures: ["p = amd(A)"],
|
|
52604
|
+
description: "Minimum degree ordering of the pattern of A + A'. chol(A(p,p)) tends to be sparser than chol(A). numbl uses an exact minimum degree ordering, so p can differ from MATLAB's approximate minimum degree permutation."
|
|
52605
|
+
},
|
|
52606
|
+
resolve: (argTypes, nargout) => {
|
|
52607
|
+
if (argTypes.length < 1 || argTypes.length > 2 || nargout > 1) return null;
|
|
52608
|
+
return {
|
|
52609
|
+
outputTypes: [ROW_VECTOR],
|
|
52610
|
+
apply: (args) => permVectorTensor(minimumDegreeOrdering(toSparseArg(args[0], "amd")))
|
|
52611
|
+
};
|
|
52612
|
+
}
|
|
52613
|
+
});
|
|
52614
|
+
registerIBuiltin({
|
|
52615
|
+
name: "colamd",
|
|
52616
|
+
help: {
|
|
52617
|
+
signatures: ["p = colamd(A)"],
|
|
52618
|
+
description: "Column ordering for LU: minimum degree ordering of the pattern of A'*A. lu(A(:,p)) tends to produce sparser factors than lu(A)."
|
|
52619
|
+
},
|
|
52620
|
+
resolve: (argTypes, nargout) => {
|
|
52621
|
+
if (argTypes.length < 1 || argTypes.length > 2 || nargout > 1) return null;
|
|
52622
|
+
return {
|
|
52623
|
+
outputTypes: [ROW_VECTOR],
|
|
52624
|
+
apply: (args) => permVectorTensor(columnOrdering(toSparseArg(args[0], "colamd")))
|
|
52625
|
+
};
|
|
52626
|
+
}
|
|
52627
|
+
});
|
|
52628
|
+
function sampleDistinct(total, k) {
|
|
52629
|
+
if (k >= total) {
|
|
52630
|
+
const all2 = new Int32Array(total);
|
|
52631
|
+
for (let i = 0; i < total; i++) all2[i] = i;
|
|
52632
|
+
return all2;
|
|
52633
|
+
}
|
|
52634
|
+
let picked;
|
|
52635
|
+
if (k > total / 3) {
|
|
52636
|
+
const idx = new Int32Array(total);
|
|
52637
|
+
for (let i = 0; i < total; i++) idx[i] = i;
|
|
52638
|
+
for (let i = 0; i < k; i++) {
|
|
52639
|
+
const j = i + Math.floor(rngRandom() * (total - i));
|
|
52640
|
+
const t = idx[i];
|
|
52641
|
+
idx[i] = idx[j];
|
|
52642
|
+
idx[j] = t;
|
|
52643
|
+
}
|
|
52644
|
+
picked = idx.slice(0, k);
|
|
52645
|
+
} else {
|
|
52646
|
+
const set = /* @__PURE__ */ new Set();
|
|
52647
|
+
while (set.size < k) set.add(Math.floor(rngRandom() * total));
|
|
52648
|
+
picked = Int32Array.from(set);
|
|
52649
|
+
}
|
|
52650
|
+
return picked.sort();
|
|
52651
|
+
}
|
|
52652
|
+
function sparseFromLinearIndices(m, n, idx, gen) {
|
|
52653
|
+
const nnz = idx.length;
|
|
52654
|
+
const ir = new Int32Array(nnz);
|
|
52655
|
+
const jc = new Int32Array(n + 1);
|
|
52656
|
+
const pr = allocFloat64Array(nnz);
|
|
52657
|
+
for (let k = 0; k < nnz; k++) {
|
|
52658
|
+
const col = Math.floor(idx[k] / m);
|
|
52659
|
+
ir[k] = idx[k] - col * m;
|
|
52660
|
+
jc[col + 1]++;
|
|
52661
|
+
pr[k] = gen();
|
|
52662
|
+
}
|
|
52663
|
+
for (let c = 0; c < n; c++) jc[c + 1] += jc[c];
|
|
52664
|
+
return RTV.sparseMatrix(m, n, ir, jc, pr);
|
|
52665
|
+
}
|
|
52666
|
+
function registerSprand(name, gen) {
|
|
52667
|
+
registerIBuiltin({
|
|
52668
|
+
name,
|
|
52669
|
+
help: {
|
|
52670
|
+
signatures: [`R = ${name}(m, n, density)`, `R = ${name}(S)`],
|
|
52671
|
+
description: `Random m-by-n sparse matrix with approximately density*m*n ` + (name === "sprand" ? "uniformly" : "normally") + ` distributed nonzeros, or a matrix with the pattern of S and random values.`
|
|
52672
|
+
},
|
|
52673
|
+
resolve: (argTypes, nargout) => {
|
|
52674
|
+
if (nargout > 1) return null;
|
|
52675
|
+
if (argTypes.length !== 1 && argTypes.length < 3) return null;
|
|
52676
|
+
return {
|
|
52677
|
+
outputTypes: [{ kind: "sparse_matrix", isComplex: false }],
|
|
52678
|
+
apply: (args) => {
|
|
52679
|
+
if (args.length === 1) {
|
|
52680
|
+
const S = toSparseArg(args[0], name);
|
|
52681
|
+
const pr = allocFloat64Array(S.pr.length);
|
|
52682
|
+
for (let k2 = 0; k2 < pr.length; k2++) pr[k2] = gen();
|
|
52683
|
+
return RTV.sparseMatrix(
|
|
52684
|
+
S.m,
|
|
52685
|
+
S.n,
|
|
52686
|
+
new Int32Array(S.ir),
|
|
52687
|
+
new Int32Array(S.jc),
|
|
52688
|
+
pr
|
|
52689
|
+
);
|
|
52690
|
+
}
|
|
52691
|
+
if (args.length > 3)
|
|
52692
|
+
throw new RuntimeError(
|
|
52693
|
+
`${name}: the reciprocal-condition form ${name}(m, n, density, rc) is not supported`
|
|
52694
|
+
);
|
|
52695
|
+
const m = Math.round(toNumber(args[0]));
|
|
52696
|
+
const n = Math.round(toNumber(args[1]));
|
|
52697
|
+
const density = toNumber(args[2]);
|
|
52698
|
+
if (!(density >= 0 && density <= 1))
|
|
52699
|
+
throw new RuntimeError(`${name}: density must be in [0, 1]`);
|
|
52700
|
+
const total = m * n;
|
|
52701
|
+
const k = Math.min(total, Math.round(density * total));
|
|
52702
|
+
return sparseFromLinearIndices(m, n, sampleDistinct(total, k), gen);
|
|
52703
|
+
}
|
|
52704
|
+
};
|
|
52705
|
+
}
|
|
52706
|
+
});
|
|
52707
|
+
}
|
|
52708
|
+
registerSprand("sprand", rngRandom);
|
|
52709
|
+
registerSprand("sprandn", boxMullerRandom);
|
|
52710
|
+
registerIBuiltin({
|
|
52711
|
+
name: "sprandsym",
|
|
52712
|
+
help: {
|
|
52713
|
+
signatures: ["R = sprandsym(n, density)", "R = sprandsym(S)"],
|
|
52714
|
+
description: "Symmetric random n-by-n sparse matrix with approximately density*n*n normally distributed nonzeros, or a symmetric matrix with the pattern of the lower triangle of S."
|
|
52715
|
+
},
|
|
52716
|
+
resolve: (argTypes, nargout) => {
|
|
52717
|
+
if (nargout > 1 || argTypes.length < 1 || argTypes.length > 2) return null;
|
|
52718
|
+
return {
|
|
52719
|
+
outputTypes: [{ kind: "sparse_matrix", isComplex: false }],
|
|
52720
|
+
apply: (args) => {
|
|
52721
|
+
let n;
|
|
52722
|
+
let lowerIdx;
|
|
52723
|
+
if (args.length === 1) {
|
|
52724
|
+
const S = toSparseArg(args[0], "sprandsym");
|
|
52725
|
+
if (S.m !== S.n)
|
|
52726
|
+
throw new RuntimeError("sprandsym: S must be square");
|
|
52727
|
+
n = S.n;
|
|
52728
|
+
const idx = [];
|
|
52729
|
+
for (let j = 0; j < n; j++)
|
|
52730
|
+
for (let k = S.jc[j]; k < S.jc[j + 1]; k++)
|
|
52731
|
+
if (S.ir[k] >= j) idx.push(j * n + S.ir[k]);
|
|
52732
|
+
lowerIdx = Int32Array.from(idx);
|
|
52733
|
+
} else {
|
|
52734
|
+
n = Math.round(toNumber(args[0]));
|
|
52735
|
+
const density = toNumber(args[1]);
|
|
52736
|
+
if (!(density >= 0 && density <= 1))
|
|
52737
|
+
throw new RuntimeError("sprandsym: density must be in [0, 1]");
|
|
52738
|
+
const tri = n * (n + 1) / 2;
|
|
52739
|
+
const k = Math.min(tri, Math.round(density * n * n / 2));
|
|
52740
|
+
const triIdx = sampleDistinct(tri, k);
|
|
52741
|
+
const lin = [];
|
|
52742
|
+
for (let t = 0; t < triIdx.length; t++) {
|
|
52743
|
+
let r = triIdx[t];
|
|
52744
|
+
let col = 0;
|
|
52745
|
+
while (r >= n - col) {
|
|
52746
|
+
r -= n - col;
|
|
52747
|
+
col++;
|
|
52748
|
+
}
|
|
52749
|
+
lin.push(col * n + col + r);
|
|
52750
|
+
}
|
|
52751
|
+
lowerIdx = Int32Array.from(lin).sort();
|
|
52752
|
+
}
|
|
52753
|
+
const lower = sparseFromLinearIndices(n, n, lowerIdx, boxMullerRandom);
|
|
52754
|
+
const Lt = sparseTranspose(lower);
|
|
52755
|
+
const dense = sparseToDense(lower).data;
|
|
52756
|
+
const denseT = sparseToDense(Lt).data;
|
|
52757
|
+
for (let i = 0; i < dense.length; i++) dense[i] += denseT[i];
|
|
52758
|
+
for (let i = 0; i < n; i++) dense[i + i * n] /= 2;
|
|
52759
|
+
return denseDataToSparse(dense, n, n);
|
|
52760
|
+
}
|
|
52761
|
+
};
|
|
52762
|
+
}
|
|
52763
|
+
});
|
|
52764
|
+
var DEC_CLASS = "decomposition";
|
|
52765
|
+
function isDecomposition(v) {
|
|
52766
|
+
return isRuntimeClassInstance(v) && v.className === DEC_CLASS;
|
|
52767
|
+
}
|
|
52768
|
+
function permFromField(d, name) {
|
|
52769
|
+
const t = d.fields.get(name);
|
|
52770
|
+
if (t === void 0 || !isRuntimeTensor(t))
|
|
52771
|
+
throw new RuntimeError("decomposition: corrupt");
|
|
52772
|
+
const p2 = new Int32Array(t.data.length);
|
|
52773
|
+
for (let i = 0; i < p2.length; i++) p2[i] = t.data[i] - 1;
|
|
52774
|
+
return p2;
|
|
52775
|
+
}
|
|
52776
|
+
function sparseField(d, name) {
|
|
52777
|
+
const v = d.fields.get(name);
|
|
52778
|
+
if (v === void 0 || !isRuntimeSparseMatrix(v))
|
|
52779
|
+
throw new RuntimeError("decomposition: corrupt");
|
|
52780
|
+
return v;
|
|
52781
|
+
}
|
|
52782
|
+
function charField(d, name) {
|
|
52783
|
+
const v = d.fields.get(name);
|
|
52784
|
+
if (v === void 0) throw new RuntimeError("decomposition: corrupt");
|
|
52785
|
+
return parseStringArgLower(v);
|
|
52786
|
+
}
|
|
52787
|
+
function diagRatio(S) {
|
|
52788
|
+
let lo = Infinity;
|
|
52789
|
+
let hi = 0;
|
|
52790
|
+
for (let j = 0; j < S.n; j++) {
|
|
52791
|
+
let d = 0;
|
|
52792
|
+
for (let k = S.jc[j]; k < S.jc[j + 1]; k++)
|
|
52793
|
+
if (S.ir[k] === j) {
|
|
52794
|
+
d = Math.abs(S.pr[k]);
|
|
52795
|
+
break;
|
|
52796
|
+
}
|
|
52797
|
+
if (d < lo) lo = d;
|
|
52798
|
+
if (d > hi) hi = d;
|
|
52799
|
+
}
|
|
52800
|
+
if (S.n === 0) return 1;
|
|
52801
|
+
return hi === 0 ? 0 : lo / hi;
|
|
52802
|
+
}
|
|
52803
|
+
function denseLuFactors(data, n) {
|
|
52804
|
+
const bridge = getEffectiveBridge("lu", "lu");
|
|
52805
|
+
if (!bridge?.lu) throw new RuntimeError("decomposition: LU unavailable");
|
|
52806
|
+
const { LU, ipiv } = bridge.lu(toF64(data), n, n);
|
|
52807
|
+
const perm = new Int32Array(n);
|
|
52808
|
+
for (let i = 0; i < n; i++) perm[i] = i;
|
|
52809
|
+
for (let i = 0; i < ipiv.length; i++) {
|
|
52810
|
+
const j = ipiv[i] - 1;
|
|
52811
|
+
if (j !== i) {
|
|
52812
|
+
const t = perm[i];
|
|
52813
|
+
perm[i] = perm[j];
|
|
52814
|
+
perm[j] = t;
|
|
52815
|
+
}
|
|
52816
|
+
}
|
|
52817
|
+
const L = allocFloat64Array(n * n);
|
|
52818
|
+
const U = allocFloat64Array(n * n);
|
|
52819
|
+
let singular = false;
|
|
52820
|
+
for (let j = 0; j < n; j++) {
|
|
52821
|
+
L[j + j * n] = 1;
|
|
52822
|
+
for (let i = j + 1; i < n; i++) L[i + j * n] = LU[i + j * n];
|
|
52823
|
+
for (let i = 0; i <= j; i++) U[i + j * n] = LU[i + j * n];
|
|
52824
|
+
if (U[j + j * n] === 0) singular = true;
|
|
52825
|
+
}
|
|
52826
|
+
return {
|
|
52827
|
+
L: denseDataToSparse(L, n, n),
|
|
52828
|
+
U: denseDataToSparse(U, n, n),
|
|
52829
|
+
p: perm,
|
|
52830
|
+
q: identityPerm(n),
|
|
52831
|
+
singular
|
|
52832
|
+
};
|
|
52833
|
+
}
|
|
52834
|
+
function denseCholLower(data, n) {
|
|
52835
|
+
const bridge = getEffectiveBridge("chol", "chol");
|
|
52836
|
+
if (!bridge?.chol) throw new RuntimeError("decomposition: chol unavailable");
|
|
52837
|
+
const { R, info } = bridge.chol(toF64(data), n, false);
|
|
52838
|
+
if (info > 0) return null;
|
|
52839
|
+
return denseDataToSparse(R, n, n);
|
|
52840
|
+
}
|
|
52841
|
+
function denseIsTriangular(data, n, upper) {
|
|
52842
|
+
for (let j = 0; j < n; j++)
|
|
52843
|
+
for (let i = 0; i < n; i++) {
|
|
52844
|
+
if (upper ? i <= j : i >= j) continue;
|
|
52845
|
+
if (data[i + j * n] !== 0) return false;
|
|
52846
|
+
}
|
|
52847
|
+
return true;
|
|
52848
|
+
}
|
|
52849
|
+
registerIBuiltin({
|
|
52850
|
+
name: "decomposition",
|
|
52851
|
+
help: {
|
|
52852
|
+
signatures: [
|
|
52853
|
+
"dA = decomposition(A)",
|
|
52854
|
+
"dA = decomposition(A, type)",
|
|
52855
|
+
"dA = decomposition(A, 'triangular', 'upper' | 'lower')",
|
|
52856
|
+
"x = dA \\ b",
|
|
52857
|
+
"x = b / dA"
|
|
52858
|
+
],
|
|
52859
|
+
description: "Factor a square matrix once and reuse the factors: dA \\ b and b / dA solve with the stored factorization. type is 'auto' (default), 'chol', 'lu', or 'triangular'; other MATLAB types fall back to LU. Sparse matrices use the sparse Cholesky / LU with a fill-reducing ordering. Properties: MatrixSize, Type, Datatype, IsReal, IsConjugateTransposed, ScaleFactor, CheckCondition."
|
|
52860
|
+
},
|
|
52861
|
+
resolve: (argTypes, nargout) => {
|
|
52862
|
+
if (argTypes.length < 1 || nargout > 1) return null;
|
|
52863
|
+
return {
|
|
52864
|
+
outputTypes: [{ kind: "unknown" }],
|
|
52865
|
+
apply: (args) => buildDecomposition(args)
|
|
52866
|
+
};
|
|
52867
|
+
}
|
|
52868
|
+
});
|
|
52869
|
+
function buildDecomposition(args) {
|
|
52870
|
+
const A = args[0];
|
|
52871
|
+
let type = "auto";
|
|
52872
|
+
let triangle = null;
|
|
52873
|
+
let checkCondition = true;
|
|
52874
|
+
let luTol = 1;
|
|
52875
|
+
let i = 1;
|
|
52876
|
+
const isStr = (v) => isRuntimeChar(v) || isRuntimeString(v);
|
|
52877
|
+
while (i < args.length) {
|
|
52878
|
+
const a = args[i];
|
|
52879
|
+
if (!isStr(a))
|
|
52880
|
+
throw new RuntimeError("decomposition: options must be strings");
|
|
52881
|
+
const s = parseStringArgLower(a);
|
|
52882
|
+
if (s === "upper" || s === "lower") {
|
|
52883
|
+
triangle = s;
|
|
52884
|
+
i++;
|
|
52885
|
+
continue;
|
|
52886
|
+
}
|
|
52887
|
+
if (s === "checkcondition" || s === "ranktolerance" || s === "banddensity" || s === "ldlpivottolerance" || s === "lupivottolerance") {
|
|
52888
|
+
if (i + 1 >= args.length)
|
|
52889
|
+
throw new RuntimeError(`decomposition: missing value for '${s}'`);
|
|
52890
|
+
const v = args[i + 1];
|
|
52891
|
+
if (s === "checkcondition") checkCondition = toNumber(v) !== 0;
|
|
52892
|
+
if (s === "lupivottolerance") luTol = toNumber(v);
|
|
52893
|
+
i += 2;
|
|
52894
|
+
continue;
|
|
52895
|
+
}
|
|
52896
|
+
if (i === 1) {
|
|
52897
|
+
type = s;
|
|
52898
|
+
i++;
|
|
52899
|
+
continue;
|
|
52900
|
+
}
|
|
52901
|
+
throw new RuntimeError(`decomposition: unknown option '${s}'`);
|
|
52902
|
+
}
|
|
52903
|
+
const known = [
|
|
52904
|
+
"auto",
|
|
52905
|
+
"chol",
|
|
52906
|
+
"lu",
|
|
52907
|
+
"triangular",
|
|
52908
|
+
"ldl",
|
|
52909
|
+
"qr",
|
|
52910
|
+
"banded",
|
|
52911
|
+
"diagonal",
|
|
52912
|
+
"permutedtriangular",
|
|
52913
|
+
"hessenberg",
|
|
52914
|
+
"cod"
|
|
52915
|
+
];
|
|
52916
|
+
if (!known.includes(type))
|
|
52917
|
+
throw new RuntimeError(
|
|
52918
|
+
`decomposition: unknown decomposition type '${type}'`
|
|
52919
|
+
);
|
|
52920
|
+
let S = null;
|
|
52921
|
+
let dense = null;
|
|
52922
|
+
let n;
|
|
52923
|
+
if (isRuntimeSparseMatrix(A)) {
|
|
52924
|
+
if (A.pi)
|
|
52925
|
+
throw new RuntimeError(
|
|
52926
|
+
"decomposition: complex matrices are not supported"
|
|
52927
|
+
);
|
|
52928
|
+
if (A.m !== A.n)
|
|
52929
|
+
throw new RuntimeError(
|
|
52930
|
+
"decomposition: only square matrices are supported"
|
|
52931
|
+
);
|
|
52932
|
+
S = A;
|
|
52933
|
+
n = A.n;
|
|
52934
|
+
} else if (isRuntimeTensor(A) || isRuntimeNumber(A)) {
|
|
52935
|
+
const t = isRuntimeNumber(A) ? RTV.tensor(allocFloat64Array([A]), [1, 1]) : A;
|
|
52936
|
+
if (t.imag)
|
|
52937
|
+
throw new RuntimeError(
|
|
52938
|
+
"decomposition: complex matrices are not supported"
|
|
52939
|
+
);
|
|
52940
|
+
const [m, nn] = tensorSize2D(t);
|
|
52941
|
+
if (m !== nn)
|
|
52942
|
+
throw new RuntimeError(
|
|
52943
|
+
"decomposition: only square matrices are supported"
|
|
52944
|
+
);
|
|
52945
|
+
n = nn;
|
|
52946
|
+
dense = t.data;
|
|
52947
|
+
} else {
|
|
52948
|
+
throw new RuntimeError("decomposition: A must be a numeric matrix");
|
|
52949
|
+
}
|
|
52950
|
+
const fields = /* @__PURE__ */ new Map();
|
|
52951
|
+
const setCommon = (typeName, rc) => {
|
|
52952
|
+
fields.set("MatrixSize", RTV.tensor(allocFloat64Array([n, n]), [1, 2]));
|
|
52953
|
+
fields.set("Type", RTV.char(typeName));
|
|
52954
|
+
fields.set("Datatype", RTV.char("double"));
|
|
52955
|
+
fields.set("IsReal", RTV.logical(true));
|
|
52956
|
+
fields.set("IsConjugateTransposed", RTV.logical(false));
|
|
52957
|
+
fields.set("ScaleFactor", RTV.num(1));
|
|
52958
|
+
fields.set("CheckCondition", RTV.logical(checkCondition));
|
|
52959
|
+
fields.set("_rcond", RTV.num(rc));
|
|
52960
|
+
};
|
|
52961
|
+
const storeTriangular = (T, upper) => {
|
|
52962
|
+
fields.set("_kind", RTV.char("triangular"));
|
|
52963
|
+
fields.set("_T", T);
|
|
52964
|
+
fields.set("_upper", RTV.logical(upper));
|
|
52965
|
+
setCommon("triangular", diagRatio(T));
|
|
52966
|
+
};
|
|
52967
|
+
const storeChol = (L, p2) => {
|
|
52968
|
+
fields.set("_kind", RTV.char("chol"));
|
|
52969
|
+
fields.set("_L", L);
|
|
52970
|
+
fields.set("_Lt", sparseTranspose(L));
|
|
52971
|
+
fields.set("_p", permVectorTensor(p2));
|
|
52972
|
+
setCommon("chol", diagRatio(L) ** 2);
|
|
52973
|
+
};
|
|
52974
|
+
const storeLu = (lu3) => {
|
|
52975
|
+
fields.set("_kind", RTV.char("lu"));
|
|
52976
|
+
fields.set("_L", lu3.L);
|
|
52977
|
+
fields.set("_U", lu3.U);
|
|
52978
|
+
fields.set("_p", permVectorTensor(lu3.p));
|
|
52979
|
+
fields.set("_q", permVectorTensor(lu3.q));
|
|
52980
|
+
setCommon(type === "auto" || type === "lu" ? "lu" : type, diagRatio(lu3.U));
|
|
52981
|
+
};
|
|
52982
|
+
const upperOk = S ? sparseIsUpper(S) : denseIsTriangular(dense, n, true);
|
|
52983
|
+
const lowerOk = S ? sparseIsLower(S) : denseIsTriangular(dense, n, false);
|
|
52984
|
+
if (type === "triangular" || type === "auto" && (upperOk || lowerOk)) {
|
|
52985
|
+
let upper;
|
|
52986
|
+
if (triangle) upper = triangle === "upper";
|
|
52987
|
+
else if (upperOk) upper = true;
|
|
52988
|
+
else if (lowerOk) upper = false;
|
|
52989
|
+
else throw new RuntimeError("decomposition: matrix is not triangular");
|
|
52990
|
+
const T = S ?? denseDataToSparse(dense, n, n);
|
|
52991
|
+
storeTriangular(T, upper);
|
|
52992
|
+
return new RuntimeClassInstance(DEC_CLASS, fields, false);
|
|
52993
|
+
}
|
|
52994
|
+
const symmetric = S !== null && sparseIsSymmetric(S);
|
|
52995
|
+
if (type === "chol" || type === "auto" && symmetric) {
|
|
52996
|
+
if (S) {
|
|
52997
|
+
const perm = minimumDegreeOrdering(S);
|
|
52998
|
+
const res = sparseChol(sparsePermute(S, perm, perm));
|
|
52999
|
+
if (res.ok) {
|
|
53000
|
+
storeChol(res.L, perm);
|
|
53001
|
+
return new RuntimeClassInstance(DEC_CLASS, fields, false);
|
|
53002
|
+
}
|
|
53003
|
+
} else {
|
|
53004
|
+
const L = denseCholLower(dense, n);
|
|
53005
|
+
if (L) {
|
|
53006
|
+
storeChol(L, identityPerm(n));
|
|
53007
|
+
return new RuntimeClassInstance(DEC_CLASS, fields, false);
|
|
53008
|
+
}
|
|
53009
|
+
}
|
|
53010
|
+
if (type === "chol")
|
|
53011
|
+
throw new RuntimeError(
|
|
53012
|
+
"Cholesky decomposition requires the input matrix to be positive definite."
|
|
53013
|
+
);
|
|
53014
|
+
}
|
|
53015
|
+
const lu2 = S ? sparseLu(S, columnOrdering(S), luTol) : denseLuFactors(dense, n);
|
|
53016
|
+
if (lu2.singular) emitWarning(SINGULAR_WARNING);
|
|
53017
|
+
storeLu(lu2);
|
|
53018
|
+
return new RuntimeClassInstance(DEC_CLASS, fields, false);
|
|
53019
|
+
}
|
|
53020
|
+
function decompositionRcond(d) {
|
|
53021
|
+
const rc = d.fields.get("_rcond");
|
|
53022
|
+
return typeof rc === "number" ? rc : 1;
|
|
53023
|
+
}
|
|
53024
|
+
registerIBuiltin({
|
|
53025
|
+
name: "isIllConditioned",
|
|
53026
|
+
help: {
|
|
53027
|
+
signatures: ["tf = isIllConditioned(dA)"],
|
|
53028
|
+
description: "True if the matrix stored in a decomposition object is ill conditioned (reciprocal condition estimate below eps)."
|
|
53029
|
+
},
|
|
53030
|
+
resolve: (argTypes, nargout) => {
|
|
53031
|
+
if (argTypes.length !== 1 || nargout > 1) return null;
|
|
53032
|
+
return {
|
|
53033
|
+
outputTypes: [{ kind: "boolean" }],
|
|
53034
|
+
apply: (args) => {
|
|
53035
|
+
if (!isDecomposition(args[0]))
|
|
53036
|
+
throw new RuntimeError(
|
|
53037
|
+
"isIllConditioned: argument must be a decomposition object"
|
|
53038
|
+
);
|
|
53039
|
+
return RTV.logical(decompositionRcond(args[0]) < Number.EPSILON);
|
|
53040
|
+
}
|
|
53041
|
+
};
|
|
53042
|
+
}
|
|
53043
|
+
});
|
|
53044
|
+
function decompositionSolve(d, B, n, nrhs, transposed) {
|
|
53045
|
+
if (d.fields.get("CheckCondition") === true) {
|
|
53046
|
+
const rc = decompositionRcond(d);
|
|
53047
|
+
if (rc < Number.EPSILON)
|
|
53048
|
+
emitWarning(
|
|
53049
|
+
`Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND = ${rc.toExponential(6)}.`
|
|
53050
|
+
);
|
|
53051
|
+
}
|
|
53052
|
+
const kind = charField(d, "_kind");
|
|
53053
|
+
if (kind === "triangular") {
|
|
53054
|
+
let T = sparseField(d, "_T");
|
|
53055
|
+
let upper = d.fields.get("_upper") === true;
|
|
53056
|
+
if (transposed) {
|
|
53057
|
+
T = sparseTranspose(T);
|
|
53058
|
+
upper = !upper;
|
|
53059
|
+
}
|
|
53060
|
+
const r = upper ? sparseSolveUpper(T, B, nrhs) : sparseSolveLower(T, B, nrhs);
|
|
53061
|
+
if (r.singular) emitWarning(SINGULAR_WARNING);
|
|
53062
|
+
return r.x;
|
|
53063
|
+
}
|
|
53064
|
+
if (kind === "chol") {
|
|
53065
|
+
const L = sparseField(d, "_L");
|
|
53066
|
+
const p2 = permFromField(d, "_p");
|
|
53067
|
+
const bp = allocFloat64Array(B.length);
|
|
53068
|
+
for (let c = 0; c < nrhs; c++)
|
|
53069
|
+
for (let k = 0; k < n; k++) bp[c * n + k] = B[c * n + p2[k]];
|
|
53070
|
+
const y = sparseSolveLower(L, bp, nrhs).x;
|
|
53071
|
+
const z = sparseSolveUpper(sparseField(d, "_Lt"), y, nrhs).x;
|
|
53072
|
+
const x = allocFloat64Array(B.length);
|
|
53073
|
+
for (let c = 0; c < nrhs; c++)
|
|
53074
|
+
for (let k = 0; k < n; k++) x[c * n + p2[k]] = z[c * n + k];
|
|
53075
|
+
return x;
|
|
53076
|
+
}
|
|
53077
|
+
const lu2 = {
|
|
53078
|
+
L: sparseField(d, "_L"),
|
|
53079
|
+
U: sparseField(d, "_U"),
|
|
53080
|
+
p: permFromField(d, "_p"),
|
|
53081
|
+
q: permFromField(d, "_q"),
|
|
53082
|
+
singular: false
|
|
53083
|
+
};
|
|
53084
|
+
return transposed ? luSolveTransposed(lu2, B, nrhs) : luSolve(lu2, B, nrhs);
|
|
53085
|
+
}
|
|
53086
|
+
function rhsData(v) {
|
|
53087
|
+
if (isRuntimeSparseMatrix(v)) {
|
|
53088
|
+
if (v.pi)
|
|
53089
|
+
throw new RuntimeError(
|
|
53090
|
+
"decomposition: complex operands are not supported"
|
|
53091
|
+
);
|
|
53092
|
+
return { data: sparseToDense(v).data, m: v.m, n: v.n };
|
|
53093
|
+
}
|
|
53094
|
+
if (isRuntimeTensor(v)) {
|
|
53095
|
+
if (v.imag)
|
|
53096
|
+
throw new RuntimeError(
|
|
53097
|
+
"decomposition: complex operands are not supported"
|
|
53098
|
+
);
|
|
53099
|
+
const [m, n] = tensorSize2D(v);
|
|
53100
|
+
return { data: v.data, m, n };
|
|
53101
|
+
}
|
|
53102
|
+
if (isRuntimeNumber(v) || isRuntimeLogical(v))
|
|
53103
|
+
return { data: allocFloat64Array([toNumber(v)]), m: 1, n: 1 };
|
|
53104
|
+
throw new RuntimeError("decomposition: operand must be numeric");
|
|
53105
|
+
}
|
|
53106
|
+
function tryDecompositionDivide(name, a, b) {
|
|
53107
|
+
if (name === "mldivide") {
|
|
53108
|
+
if (!isDecomposition(a)) {
|
|
53109
|
+
if (isDecomposition(b))
|
|
53110
|
+
throw new RuntimeError(
|
|
53111
|
+
"decomposition: a decomposition object can only be the left operand of \\"
|
|
53112
|
+
);
|
|
53113
|
+
return void 0;
|
|
53114
|
+
}
|
|
53115
|
+
const n2 = toNumber(permSize(a));
|
|
53116
|
+
const rhs2 = rhsData(b);
|
|
53117
|
+
if (rhs2.m !== n2)
|
|
53118
|
+
throw new RuntimeError(
|
|
53119
|
+
`mldivide (\\): A is ${n2}\xD7${n2} but B has ${rhs2.m} rows`
|
|
53120
|
+
);
|
|
53121
|
+
const x2 = decompositionSolve(a, rhs2.data, n2, rhs2.n, false);
|
|
53122
|
+
return RTV.tensor(x2, [n2, rhs2.n]);
|
|
53123
|
+
}
|
|
53124
|
+
if (!isDecomposition(b)) {
|
|
53125
|
+
if (isDecomposition(a))
|
|
53126
|
+
throw new RuntimeError(
|
|
53127
|
+
"decomposition: a decomposition object can only be the right operand of /"
|
|
53128
|
+
);
|
|
53129
|
+
return void 0;
|
|
53130
|
+
}
|
|
53131
|
+
const n = toNumber(permSize(b));
|
|
53132
|
+
const rhs = rhsData(a);
|
|
53133
|
+
if (rhs.n !== n)
|
|
53134
|
+
throw new RuntimeError(
|
|
53135
|
+
`mrdivide (/): A is ${n}\xD7${n} but B has ${rhs.n} columns`
|
|
53136
|
+
);
|
|
53137
|
+
const nrhs = rhs.m;
|
|
53138
|
+
const Bt = allocFloat64Array(n * nrhs);
|
|
53139
|
+
for (let c = 0; c < nrhs; c++)
|
|
53140
|
+
for (let k = 0; k < n; k++) Bt[c * n + k] = rhs.data[c + k * nrhs];
|
|
53141
|
+
const xt = decompositionSolve(b, Bt, n, nrhs, true);
|
|
53142
|
+
const x = allocFloat64Array(n * nrhs);
|
|
53143
|
+
for (let c = 0; c < nrhs; c++)
|
|
53144
|
+
for (let k = 0; k < n; k++) x[c + k * nrhs] = xt[c * n + k];
|
|
53145
|
+
return RTV.tensor(x, [nrhs, n]);
|
|
53146
|
+
}
|
|
53147
|
+
function permSize(d) {
|
|
53148
|
+
const ms = d.fields.get("MatrixSize");
|
|
53149
|
+
if (ms === void 0 || !isRuntimeTensor(ms))
|
|
53150
|
+
throw new RuntimeError("decomposition: corrupt");
|
|
53151
|
+
return ms.data[0];
|
|
53152
|
+
}
|
|
53153
|
+
|
|
49878
53154
|
// src/numbl-core/interpreter/builtins/graph.ts
|
|
49879
53155
|
function isGraph(v) {
|
|
49880
53156
|
return isRuntimeClassInstance(v) && v.className === "graph";
|
|
@@ -51659,6 +54935,10 @@ for (const [name, op] of opMap) {
|
|
|
51659
54935
|
apply: (args) => {
|
|
51660
54936
|
const dt = tryDatetimeDurationBinop(name, args[0], args[1]);
|
|
51661
54937
|
if (dt !== void 0) return dt;
|
|
54938
|
+
if (name === "mldivide" || name === "mrdivide") {
|
|
54939
|
+
const dec = tryDecompositionDivide(name, args[0], args[1]);
|
|
54940
|
+
if (dec !== void 0) return dec;
|
|
54941
|
+
}
|
|
51662
54942
|
return op(args[0], args[1]);
|
|
51663
54943
|
}
|
|
51664
54944
|
};
|
|
@@ -53523,7 +56803,7 @@ var H = {
|
|
|
53523
56803
|
},
|
|
53524
56804
|
inv: {
|
|
53525
56805
|
signatures: ["B = inv(A)"],
|
|
53526
|
-
description: "Matrix inverse."
|
|
56806
|
+
description: "Matrix inverse. A sparse A gives a sparse B (computed by sparse LU); prefer A \\ b for solving systems."
|
|
53527
56807
|
},
|
|
53528
56808
|
expm: {
|
|
53529
56809
|
signatures: ["Y = expm(X)"],
|
|
@@ -53534,8 +56814,15 @@ var H = {
|
|
|
53534
56814
|
description: "Sum of diagonal elements."
|
|
53535
56815
|
},
|
|
53536
56816
|
eig: {
|
|
53537
|
-
signatures: [
|
|
53538
|
-
|
|
56817
|
+
signatures: [
|
|
56818
|
+
"E = eig(A)",
|
|
56819
|
+
"[V, D] = eig(A)",
|
|
56820
|
+
"[V, D, W] = eig(A)",
|
|
56821
|
+
"E = eig(A, B)",
|
|
56822
|
+
"[V, D] = eig(A, B)",
|
|
56823
|
+
"eig(A, ..., 'vector' | 'matrix' | 'nobalance' | 'chol' | 'qz')"
|
|
56824
|
+
],
|
|
56825
|
+
description: "Eigenvalues and eigenvectors of a square matrix. With three outputs, W contains left eigenvectors. Symmetric (Hermitian) input gives real eigenvalues in ascending order and an orthonormal eigenvector basis. eig(A, B) solves the generalized problem A*v = lambda*B*v; for a symmetric-definite pencil V is normalized so that V'*B*V = I."
|
|
53539
56826
|
},
|
|
53540
56827
|
eigs: {
|
|
53541
56828
|
signatures: [
|
|
@@ -53558,8 +56845,15 @@ var H = {
|
|
|
53558
56845
|
description: "Singular value decomposition."
|
|
53559
56846
|
},
|
|
53560
56847
|
lu: {
|
|
53561
|
-
signatures: [
|
|
53562
|
-
|
|
56848
|
+
signatures: [
|
|
56849
|
+
"Y = lu(A)",
|
|
56850
|
+
"[L, U] = lu(A)",
|
|
56851
|
+
"[L, U, P] = lu(A)",
|
|
56852
|
+
"[L, U, P] = lu(A, 'vector')",
|
|
56853
|
+
"[L, U, P, Q] = lu(S)",
|
|
56854
|
+
"[L, U, P, Q] = lu(S, thresh)"
|
|
56855
|
+
],
|
|
56856
|
+
description: "LU factorization. With 2 outputs, L includes the permutation. With 3, P is a permutation matrix (or a row vector with 'vector'). Sparse S returns sparse factors from a left-looking LU with threshold partial pivoting; with 4 outputs, Q is a fill-reducing column permutation and P*S*Q = L*U."
|
|
53563
56857
|
},
|
|
53564
56858
|
qr: {
|
|
53565
56859
|
signatures: [
|
|
@@ -53571,8 +56865,14 @@ var H = {
|
|
|
53571
56865
|
description: "QR factorization. With 3 outputs, E is a column permutation matrix (or vector in economy mode)."
|
|
53572
56866
|
},
|
|
53573
56867
|
chol: {
|
|
53574
|
-
signatures: [
|
|
53575
|
-
|
|
56868
|
+
signatures: [
|
|
56869
|
+
"R = chol(A)",
|
|
56870
|
+
"L = chol(A, 'lower')",
|
|
56871
|
+
"[R, p] = chol(A)",
|
|
56872
|
+
"[R, p, P] = chol(S)",
|
|
56873
|
+
"[R, p, q] = chol(S, 'vector')"
|
|
56874
|
+
],
|
|
56875
|
+
description: "Cholesky factorization with R'*R = A, reading only the upper triangle. A must be symmetric positive definite; with 2 outputs, p is 0 on success and otherwise the failing column (no error). Sparse S returns a sparse factor; with 3 outputs, P is a fill-reducing permutation with R'*R = P'*S*P."
|
|
53576
56876
|
},
|
|
53577
56877
|
rank: {
|
|
53578
56878
|
signatures: ["K = rank(A)", "K = rank(A, TOL)"],
|
|
@@ -53600,7 +56900,7 @@ var H = {
|
|
|
53600
56900
|
},
|
|
53601
56901
|
kron: {
|
|
53602
56902
|
signatures: ["K = kron(A, B)"],
|
|
53603
|
-
description: "Kronecker tensor product."
|
|
56903
|
+
description: "Kronecker tensor product. If either operand is sparse, K is sparse with nnz(A)*nnz(B) entries."
|
|
53604
56904
|
},
|
|
53605
56905
|
linsolve: {
|
|
53606
56906
|
signatures: ["X = linsolve(A, B)"],
|
|
@@ -56866,6 +60166,7 @@ function registerSpecialBuiltins(rt) {
|
|
|
56866
60166
|
if (na === 0) {
|
|
56867
60167
|
rt.output(`Elapsed time is ${elapsed.toFixed(6)} seconds.
|
|
56868
60168
|
`);
|
|
60169
|
+
return void 0;
|
|
56869
60170
|
}
|
|
56870
60171
|
return RTV.num(elapsed);
|
|
56871
60172
|
}
|
|
@@ -62558,6 +65859,7 @@ var Runtime = class _Runtime {
|
|
|
62558
65859
|
if (options.cancelSAB) {
|
|
62559
65860
|
this.cancelFlag = new Int32Array(options.cancelSAB);
|
|
62560
65861
|
}
|
|
65862
|
+
setWarningSink((msg) => this.output("Warning: " + msg + "\n"));
|
|
62561
65863
|
this.initBuiltins();
|
|
62562
65864
|
}
|
|
62563
65865
|
outputLines = [];
|
|
@@ -65208,9 +68510,9 @@ function analyzeLoop(stmt) {
|
|
|
65208
68510
|
};
|
|
65209
68511
|
}
|
|
65210
68512
|
function collectReadsFromSiblings(stmts, startIdx, out) {
|
|
65211
|
-
const
|
|
68513
|
+
const sink2 = /* @__PURE__ */ new Set();
|
|
65212
68514
|
for (let i = startIdx; i < stmts.length; i++) {
|
|
65213
|
-
walkStmt2(stmts[i],
|
|
68515
|
+
walkStmt2(stmts[i], sink2, out);
|
|
65214
68516
|
}
|
|
65215
68517
|
}
|
|
65216
68518
|
function walkStmts(stmts, assigned, referenced) {
|
|
@@ -65578,8 +68880,7 @@ var Registry = class {
|
|
|
65578
68880
|
const stmt = siblings[i];
|
|
65579
68881
|
const lowered = tryLower(siblings, i, ctx.interp, this.loweringCache);
|
|
65580
68882
|
if (lowered === null) {
|
|
65581
|
-
|
|
65582
|
-
return { signal: signal2 };
|
|
68883
|
+
return this.interpretFallback(ctx, stmt);
|
|
65583
68884
|
}
|
|
65584
68885
|
let bestExec = null;
|
|
65585
68886
|
let bestData = null;
|
|
@@ -65628,8 +68929,25 @@ var Registry = class {
|
|
|
65628
68929
|
}
|
|
65629
68930
|
}
|
|
65630
68931
|
}
|
|
65631
|
-
|
|
65632
|
-
|
|
68932
|
+
return this.interpretFallback(ctx, stmt);
|
|
68933
|
+
}
|
|
68934
|
+
/** Run one stmt on the AST interpreter.
|
|
68935
|
+
*
|
|
68936
|
+
* When that stmt is a loop, the interpreter is about to walk its body,
|
|
68937
|
+
* which invalidates the "an enclosing loop will capture me" assumption
|
|
68938
|
+
* behind the executors' `loopDepth` gate. `jitDeclinedLoopDepth` records
|
|
68939
|
+
* that for the duration of the body so nested loops and calls can bid for
|
|
68940
|
+
* themselves instead of running interpreted all the way down. */
|
|
68941
|
+
interpretFallback(ctx, stmt) {
|
|
68942
|
+
if (stmt.type === "For" || stmt.type === "While") {
|
|
68943
|
+
ctx.interp.jitDeclinedLoopDepth++;
|
|
68944
|
+
try {
|
|
68945
|
+
return { signal: ctx.interp.execStmt(stmt) };
|
|
68946
|
+
} finally {
|
|
68947
|
+
ctx.interp.jitDeclinedLoopDepth--;
|
|
68948
|
+
}
|
|
68949
|
+
}
|
|
68950
|
+
return { signal: ctx.interp.execStmt(stmt) };
|
|
65633
68951
|
}
|
|
65634
68952
|
runStmtCandidate(stmt, ctx, executor, data, lowered) {
|
|
65635
68953
|
const result = this.executeCandidate(ctx, executor, stmt, data, stmt);
|
|
@@ -65865,6 +69183,10 @@ __export(interpreterExec_exports, {
|
|
|
65865
69183
|
var lastDecline = null;
|
|
65866
69184
|
function recordJitDecline(d) {
|
|
65867
69185
|
lastDecline = d;
|
|
69186
|
+
if (typeof process !== "undefined" && process.env?.NUMBL_JIT_LOG) {
|
|
69187
|
+
const at = d.at ? ` [${d.at.file}@${d.at.start}]` : "";
|
|
69188
|
+
console.error(`[jit-decline] ${d.where}${at}: ${d.message}`);
|
|
69189
|
+
}
|
|
65868
69190
|
}
|
|
65869
69191
|
function getLastJitDecline() {
|
|
65870
69192
|
return lastDecline;
|
|
@@ -67853,6 +71175,7 @@ function interpretWorkspaceFunction(target, args, nargout) {
|
|
|
67853
71175
|
fn = funcDefFromStmt(stmt);
|
|
67854
71176
|
break;
|
|
67855
71177
|
}
|
|
71178
|
+
if (stmt.type !== "ClassDef" && stmt.type !== "Import") break;
|
|
67856
71179
|
}
|
|
67857
71180
|
}
|
|
67858
71181
|
}
|
|
@@ -68652,6 +71975,17 @@ var Interpreter = class {
|
|
|
68652
71975
|
* interpreter never sees them, so this gate only fires on calls
|
|
68653
71976
|
* that genuinely happen at the interpreter level inside a loop. */
|
|
68654
71977
|
loopDepth = 0;
|
|
71978
|
+
/** @internal Number of those enclosing loops that the JIT *declined*, so
|
|
71979
|
+
* the interpreter is walking their bodies statement by statement. The
|
|
71980
|
+
* `loopDepth > 0` gate above assumes an enclosing loop will be compiled
|
|
71981
|
+
* and will swallow whatever is nested inside it; when that loop was
|
|
71982
|
+
* declined instead, the assumption is false and everything below it would
|
|
71983
|
+
* run interpreted however expensive it is. The executors therefore gate on
|
|
71984
|
+
* `loopDepth > 0 && jitDeclinedLoopDepth === 0`: still no per-iteration JIT
|
|
71985
|
+
* attempts underneath a loop that is about to be compiled, but a nested
|
|
71986
|
+
* loop or call under a declined one gets its own chance. Bumped by the
|
|
71987
|
+
* registry around the interpreter fallback for a loop stmt. */
|
|
71988
|
+
jitDeclinedLoopDepth = 0;
|
|
68655
71989
|
/** @internal Number of enclosing conditional blocks (`if` / `switch` /
|
|
68656
71990
|
* `try`) whose bodies the interpreter is currently executing. Used by
|
|
68657
71991
|
* the loop classifier: when a loop is dispatched with `condBlockDepth >
|
|
@@ -70057,14 +73391,6 @@ end
|
|
|
70057
73391
|
name: "+matlab/+internal/+math/blkdiag.m",
|
|
70058
73392
|
source: "function B = blkdiag(varargin)\n B = builtin('blkdiag', varargin{:});\nend\n"
|
|
70059
73393
|
},
|
|
70060
|
-
{
|
|
70061
|
-
name: "decomposition.m",
|
|
70062
|
-
source: "classdef decomposition\n properties\n A\n checkCondition\n isIllCond\n end\n methods\n function obj = decomposition(A, varargin)\n obj.A = A;\n obj.checkCondition = true;\n for i = 1:2:length(varargin)\n if strcmpi(varargin{i}, 'CheckCondition')\n obj.checkCondition = varargin{i+1};\n end\n end\n if obj.checkCondition\n obj.isIllCond = (rcond(A) < eps);\n else\n obj.isIllCond = false;\n end\n end\n function x = mldivide(obj, b)\n x = obj.A \\ b;\n end\n end\nend\n"
|
|
70063
|
-
},
|
|
70064
|
-
{
|
|
70065
|
-
name: "isIllConditioned.m",
|
|
70066
|
-
source: "function result = isIllConditioned(dA)\n result = dA.isIllCond;\nend\n"
|
|
70067
|
-
},
|
|
70068
73394
|
{
|
|
70069
73395
|
name: "uihtml.m",
|
|
70070
73396
|
source: "classdef uihtml < handle\n %UIHTML Create an HTML UI component (numbl subset).\n % H = UIHTML('HTMLSource', HTML) renders the self-contained HTML string\n % HTML in the figure pane. An optional leading parent argument (e.g. a\n % figure) is accepted and ignored. Supported name-value options:\n % HTMLSource, Data, Position.\n %\n % H = UIHTML('HTMLSource', HTML, 'Data', X) also sends X into the page.\n % Mirroring MATLAB, X is encoded with jsonencode, parsed in the page with\n % JSON.parse, and set on the JavaScript `htmlComponent.Data` object,\n % firing any \"DataChanged\" listener registered in the page's\n % `function setup(htmlComponent)`. To update the data after construction,\n % set H.Data and call show(H) (numbl re-renders the component):\n %\n % h = uihtml('HTMLSource', html, 'Data', struct('n', 1));\n % h.Data = struct('n', 2);\n % show(h);\n %\n % numbl currently supports HTMLSource given as an HTML markup string (a\n % single self-contained document). HTML file paths and supporting files\n % are not yet supported.\n %\n % The reverse channel (page -> MATLAB) is supported for the IDE:\n % HTMLEventReceivedFcn fires when JS calls\n % htmlComponent.sendEventToMATLAB(name,data); inside the callback use\n % sendEventToHTMLSource(src,name,data) to send back to the page.\n % DataChangedFcn fires when JS sets htmlComponent.Data. Register callbacks\n % at construction (name-value) since numbl renders at construction.\n properties\n HTMLSource = ''\n Data = []\n Position = [100 100 100 100]\n HTMLEventReceivedFcn = []\n DataChangedFcn = []\n end\n methods\n function obj = uihtml(varargin)\n args = varargin;\n % Ignore an optional leading parent argument (anything that is not\n % a name-value name string).\n if numel(args) >= 1 && ~(ischar(args{1}) || isstring(args{1}))\n args = args(2:end);\n end\n for i = 1:2:numel(args) - 1\n name = args{i};\n val = args{i + 1};\n if strcmpi(name, 'HTMLSource')\n obj.HTMLSource = val;\n elseif strcmpi(name, 'Data')\n obj.Data = val;\n elseif strcmpi(name, 'Position')\n obj.Position = val;\n elseif strcmpi(name, 'HTMLEventReceivedFcn')\n obj.HTMLEventReceivedFcn = val;\n elseif strcmpi(name, 'DataChangedFcn')\n obj.DataChangedFcn = val;\n end\n end\n render(obj);\n end\n\n function show(obj)\n render(obj);\n end\n\n function render(obj)\n if isempty(obj.HTMLSource)\n return;\n end\n if isempty(obj.Data)\n id = drawuihtml(obj.HTMLSource);\n else\n id = drawuihtml(obj.HTMLSource, jsonencode(obj.Data));\n end\n if ~isempty(obj.HTMLEventReceivedFcn)\n registeruihtmlcallback(id, 'HTMLEventReceived', ...\n obj.HTMLEventReceivedFcn);\n end\n if ~isempty(obj.DataChangedFcn)\n registeruihtmlcallback(id, 'DataChanged', obj.DataChangedFcn);\n end\n end\n end\nend\n"
|
|
@@ -71837,8 +75163,12 @@ function mtoc2_cpow(a, b) {
|
|
|
71837
75163
|
}
|
|
71838
75164
|
return cexp2(mtoc2_cmul(b, clog2(a)));
|
|
71839
75165
|
}
|
|
75166
|
+
function nanOnRealAxis(z) {
|
|
75167
|
+
return z.im === 0 && Number.isNaN(z.re);
|
|
75168
|
+
}
|
|
71840
75169
|
function mtoc2_csqrt(z) {
|
|
71841
75170
|
if (z.im === 0) {
|
|
75171
|
+
if (Number.isNaN(z.re)) return { re: z.re, im: 0 };
|
|
71842
75172
|
if (z.re >= 0) return { re: Math.sqrt(z.re), im: 0 };
|
|
71843
75173
|
return { re: 0, im: Math.sqrt(-z.re) };
|
|
71844
75174
|
}
|
|
@@ -71852,14 +75182,17 @@ function mtoc2_cexp(z) {
|
|
|
71852
75182
|
return cexp2(z);
|
|
71853
75183
|
}
|
|
71854
75184
|
function mtoc2_clog(z) {
|
|
75185
|
+
if (nanOnRealAxis(z)) return { re: z.re, im: 0 };
|
|
71855
75186
|
return clog2(z);
|
|
71856
75187
|
}
|
|
71857
75188
|
function mtoc2_clog2(z) {
|
|
75189
|
+
if (nanOnRealAxis(z)) return { re: z.re, im: 0 };
|
|
71858
75190
|
const l = clog2(z);
|
|
71859
75191
|
const lg2 = Math.log(2);
|
|
71860
75192
|
return { re: l.re / lg2, im: l.im / lg2 };
|
|
71861
75193
|
}
|
|
71862
75194
|
function mtoc2_clog10(z) {
|
|
75195
|
+
if (nanOnRealAxis(z)) return { re: z.re, im: 0 };
|
|
71863
75196
|
const l = clog2(z);
|
|
71864
75197
|
const lg10 = Math.log(10);
|
|
71865
75198
|
return { re: l.re / lg10, im: l.im / lg10 };
|
|
@@ -74270,7 +77603,7 @@ var JS_SNIPPETS = {
|
|
|
74270
77603
|
"warning_fmt.js": '// JS sibling of `warning_fmt.h`. Format the message and write\n// `Warning: <msg>\\n` via `$write`. Matches numbl\n// (`runtime/specialBuiltins.ts:190` \u2014 `rt.output("Warning: " + msg + "\\n")`).\n\n\nfunction mtoc2_warning_fmt(fmt, ...args) {\n $write("Warning: " + mtoc2_sprintf_format(fmt, args) + "\\n");\n}\n\nfunction mtoc2_warning_fmt_id(_id, fmt, ...args) {\n // The id is informational \u2014 numbl threads it to lastwarn state,\n // which mtoc2 doesn\'t expose. Drop it here so the visible output\n // matches the bare form.\n $write("Warning: " + mtoc2_sprintf_format(fmt, args) + "\\n");\n}\n',
|
|
74271
77604
|
"plot_dispatch.js": '// JS sibling of `plot_dispatch.h`. Two delivery modes:\n//\n// 1. Host hook mode (numbl JIT bridge): when the host binds a\n// `$plotDispatch(name, args)` callback into the emit\'s `$h`\n// helpers, the helper forwards the raw mtoc2-shaped args to the\n// host. The host is expected to translate the args into its own\n// runtime value shape and route them into its plot pipeline\n// (numbl: `dispatchPlotBuiltin` into `rt.plotInstructions`).\n//\n// Wire-format encoding is skipped entirely in this mode \u2014 the\n// host operates in-process and consumes the same value graph the\n// emitted code already holds.\n//\n// 2. Wire-format mode (standalone AOT / viewer tee): when no host\n// hook is present, fall back to the RS-prefixed JSON record on\n// stdout that the launcher splits and forwards. Same shape the C\n// sibling emits, so a single viewer parses both backends.\n//\n// Wire shape per call (mode 2):\n// \\x1e mtoc2:plot \\t {"call":"<name>","args":[<arg>, ...]} \\n\n//\n// Arg encoding (per source-level arg):\n// number \u2192 bare numeric (non-finite \u2192 null, matching the C side\n// and JSON.stringify\'s natural behavior)\n// string \u2192 {"kind":"text","data":"<text>"}\n// char \u2192 same as string (MATLAB plot semantics don\'t distinguish)\n// tensor \u2192 {"kind":"tensor","dims":[\u2026],"data":[\u2026]} (column-major\n// flatten; non-finite as null)\n\nfunction isTensor(v) {\n return typeof v === "object" && v !== null && v.mtoc2Tag === "tensor";\n}\nfunction isChar(v) {\n return typeof v === "object" && v !== null && v.mtoc2Tag === "char";\n}\n\nfunction encodeArg(v) {\n if (typeof v === "number") {\n return Number.isFinite(v) ? v : null;\n }\n if (typeof v === "boolean") return v ? 1 : 0;\n if (typeof v === "string") return { kind: "text", data: v };\n if (isChar(v)) return { kind: "text", data: v.value };\n if (isTensor(v)) {\n const data = new Array(v.data.length);\n for (let i = 0; i < v.data.length; i++) {\n const x = v.data[i];\n data[i] = Number.isFinite(x) ? x : null;\n }\n return { kind: "tensor", dims: v.shape.slice(), data };\n }\n // Unknown shape \u2014 pass through. Type-level rejection on the\n // lowering side keeps complex/struct/class/handle out of here.\n return String(v);\n}\n\nfunction mtoc2_plot_dispatch(name, ...args) {\n if (typeof globalThis.$plotDispatch === "function") {\n globalThis.$plotDispatch(name, args);\n return;\n }\n const record = { call: name, args: args.map(encodeArg) };\n $write("\\x1emtoc2:plot\\t" + JSON.stringify(record) + "\\n");\n}\n',
|
|
74272
77605
|
"cdiv.js": "// JS sibling of `cdiv.h`. Scalar complex division matching numbl's\n// signed-Inf-on-zero-divisor behavior via Smith's algorithm. Mirrors\n// the C side so cross-runner output stays byte-for-byte.\n\nfunction mtoc2_cdiv(a, b) {\n const ar = a.re,\n ai = a.im;\n const br = b.re,\n bi = b.im;\n // Zero divisor: match the interpreter (helpers/arithmetic.ts) \u2014 0/0 is\n // NaN, a nonzero numerator yields a signed Inf per component. Smith's\n // algorithm below would otherwise produce NaN+NaNi here.\n if (br === 0 && bi === 0) {\n if (ar === 0 && ai === 0) return { re: NaN, im: 0 };\n const signedInf = x => (x > 0 ? Infinity : x < 0 ? -Infinity : 0);\n return { re: signedInf(ar), im: signedInf(ai) };\n }\n if (Math.abs(br) >= Math.abs(bi)) {\n const r = bi / br;\n const den = br + r * bi;\n return { re: (ar + ai * r) / den, im: (ai - ar * r) / den };\n }\n const r = br / bi;\n const den = bi + r * br;\n return { re: (ar * r + ai) / den, im: (ai * r - ar) / den };\n}\n",
|
|
74273
|
-
"cscalar.js": "// JS sibling of `cscalar.h`. JS has no native complex type, so each\n// helper takes and returns `{re, im}` objects. Mirrors the C\n// signatures so emitJs renders calls structurally identical to the\n// C path (just with JS objects instead of `double _Complex`).\n//\n// Division (`mtoc2_cdiv`) lives in `cdiv.js` because it needs\n// Smith's algorithm with signed-zero detection to match numbl\n// byte-for-byte.\n\nfunction mtoc2_cmake(re, im) {\n return { re, im };\n}\nfunction mtoc2_creal(z) {\n return z.re;\n}\nfunction mtoc2_cimag(z) {\n return z.im;\n}\nfunction mtoc2_cadd(a, b) {\n return { re: a.re + b.re, im: a.im + b.im };\n}\nfunction mtoc2_csub(a, b) {\n return { re: a.re - b.re, im: a.im - b.im };\n}\nfunction mtoc2_cmul(a, b) {\n return { re: a.re * b.re - a.im * b.im, im: a.re * b.im + a.im * b.re };\n}\nfunction mtoc2_cneg(z) {\n return { re: -z.re, im: -z.im };\n}\nfunction mtoc2_cconj(z) {\n return { re: z.re, im: -z.im };\n}\nfunction mtoc2_cabs(z) {\n return Math.hypot(z.re, z.im);\n}\nfunction mtoc2_cangle(z) {\n return Math.atan2(z.im, z.re);\n}\nfunction mtoc2_cnonzero(z) {\n return z.re !== 0 || z.im !== 0;\n}\nfunction mtoc2_ceq(a, b) {\n return a.re === b.re && a.im === b.im;\n}\nfunction mtoc2_cne(a, b) {\n return a.re !== b.re || a.im !== b.im;\n}\n\n// `cpow(a, b) = exp(b * log(a))`. Matches numbl / C99 `cpow` for\n// finite inputs; special zero / pole cases follow the same path\n// the C side picks (exp(NaN) = NaN, etc.).\nfunction clog(z) {\n // Normalize a -0 real part to +0 so log(-0) (a real -0) gives\n // -Inf + 0i, not -Inf + \u03C0i \u2014 MATLAB / C99 treat -0 as 0, not as an\n // approach-from-below negative. atan2's -0 second arg only changes the\n // result when the first arg is also 0, so this affects nothing else.\n const reAngle = z.re === 0 ? 0 : z.re;\n return {\n re: Math.log(Math.hypot(z.re, z.im)),\n im: Math.atan2(z.im, reAngle),\n };\n}\nfunction cexp(z) {\n const m = Math.exp(z.re);\n // Real-valued input (im === 0): the imaginary lane is m*sin(0) = 0, but\n // when m overflows to Inf that becomes Inf*0 = NaN. Return a clean 0\n // (matches the interpreter's real exp and C99 cexp).\n if (z.im === 0) return { re: m, im: 0 };\n return { re: m * Math.cos(z.im), im: m * Math.sin(z.im) };\n}\nfunction mtoc2_cpow(a, b) {\n // Zero base: match the interpreter's complexPow (helpers/arithmetic.ts)\n // \u2014 0^0 = 1, a positive real part of the exponent gives 0 (regardless\n // of the imaginary part), and anything else gives Inf+0i. The old\n // guard required b.im===0 for the zero case and otherwise returned\n // NaN+NaNi.\n if (a.re === 0 && a.im === 0) {\n if (b.re === 0 && b.im === 0) return { re: 1, im: 0 };\n if (b.re > 0) return { re: 0, im: 0 };\n return { re: Infinity, im: 0 };\n }\n return cexp(mtoc2_cmul(b, clog(a)));\n}\n\n// Unary math.\nfunction mtoc2_csqrt(z) {\n // Pure-real input: compute directly. Smith's formula below suffers\n // catastrophic cancellation/overflow when z.im === 0 \u2014 e.g.\n // sqrt(-Inf) \u2192 sqrt((Inf + -Inf)/2) = sqrt(NaN) = NaN, and\n // sqrt(-1e308) \u2192 sqrt((1e308 - -1e308)/2) overflows to Inf instead of\n // 1e154. Mirror the interpreter's complexSqrt (math.ts) and C's libm\n // csqrt, both of which special-case the real axis.\n if (z.im === 0) {\n if (z.re >= 0) return { re: Math.sqrt(z.re), im: 0 };\n return { re: 0, im: Math.sqrt(-z.re) };\n }\n // Smith's stable formula for hypot * sign.\n const r = Math.hypot(z.re, z.im);\n if (r === 0) return { re: 0, im: 0 };\n const re = Math.sqrt((r + z.re) / 2);\n const im = (z.im >= 0 ? 1 : -1) * Math.sqrt((r - z.re) / 2);\n return { re, im };\n}\nfunction mtoc2_cexp(z) {\n return cexp(z);\n}\nfunction mtoc2_clog(z) {\n return clog(z);\n}\nfunction mtoc2_clog2(z) {\n const l = clog(z);\n const lg2 = Math.log(2);\n return { re: l.re / lg2, im: l.im / lg2 };\n}\nfunction mtoc2_clog10(z) {\n const l = clog(z);\n const lg10 = Math.log(10);\n return { re: l.re / lg10, im: l.im / lg10 };\n}\nfunction mtoc2_csin(z) {\n // Guard 0*Inf=NaN on the imaginary axis: for a pure-imaginary input\n // (sin(z.re)===0), the real lane is 0 and the imaginary lane is\n // \xB1sinh(im); cosh/sinh overflow to Inf for large |im|, and 0*Inf would\n // poison the result. C99 csin special-cases this \u2014 match it.\n const sr = Math.sin(z.re);\n const cr = Math.cos(z.re);\n return {\n re: sr === 0 ? 0 : sr * Math.cosh(z.im),\n im: cr === 0 ? 0 : cr * Math.sinh(z.im),\n };\n}\nfunction mtoc2_ccos(z) {\n const cr = Math.cos(z.re);\n const sr = Math.sin(z.re);\n return {\n re: cr === 0 ? 0 : cr * Math.cosh(z.im),\n im: sr === 0 ? 0 : -sr * Math.sinh(z.im),\n };\n}\nfunction mtoc2_ctan(z) {\n // Double-angle form, matching the interpreter (interpreter/builtins/\n // math.ts) and C99 ctan. Computing sin(z)/cos(z) with a |cos|^2\n // denominator loses the (tiny but nonzero) real part and overflows\n // for large imaginary parts \u2014 e.g. tan(1+200i) collapsed to 1i.\n const denom = Math.cos(2 * z.re) + Math.cosh(2 * z.im);\n return { re: Math.sin(2 * z.re) / denom, im: Math.sinh(2 * z.im) / denom };\n}\nfunction mtoc2_catan(z) {\n // Real-valued input (im === 0): atan is a clean real function. The\n // complex formula leaves a spurious \xB11e-17i residue (and NaN+NaNi once\n // 1\xB1iz overflows, e.g. atan(1e300)). Take the real path.\n if (z.im === 0) return { re: Math.atan(z.re), im: 0 };\n // atan(z) = (i/2)\xB7log((1 \u2212 iz)/(1 + iz)) \u2014 MATLAB's branch (atan(2i) =\n // \u22121.5708 + 0.5493i). The C runtime overrides its libc catan (which\n // uses the opposite +\u03C0/2 Annex-G branch) to match this.\n const iz = { re: -z.im, im: z.re }; // i*z\n const num = { re: 1 - iz.re, im: -iz.im }; // 1 - iz\n const denom = { re: 1 + iz.re, im: iz.im }; // 1 + iz\n const dd = denom.re * denom.re + denom.im * denom.im;\n const q = {\n re: (num.re * denom.re + num.im * denom.im) / dd,\n im: (num.im * denom.re - num.re * denom.im) / dd,\n };\n const l = clog(q);\n return { re: -l.im / 2, im: l.re / 2 };\n}\n// Hyperbolic sinh/cosh/tanh \u2014 byte-for-byte with the interpreter's\n// complex formulas (interpreter/builtins/math.ts). Real-valued input\n// (im === 0) falls out cleanly: cos(0)=1, sin(0)=0, so the imaginary\n// lane is exactly 0.\nfunction mtoc2_csinh(z) {\n return {\n re: Math.sinh(z.re) * Math.cos(z.im),\n im: Math.cosh(z.re) * Math.sin(z.im),\n };\n}\nfunction mtoc2_ccosh(z) {\n return {\n re: Math.cosh(z.re) * Math.cos(z.im),\n im: Math.sinh(z.re) * Math.sin(z.im),\n };\n}\nfunction mtoc2_ctanh(z) {\n const denom = Math.cosh(2 * z.re) + Math.cos(2 * z.im);\n return { re: Math.sinh(2 * z.re) / denom, im: Math.sin(2 * z.im) / denom };\n}\nfunction mtoc2_cfloor(z) {\n return { re: Math.floor(z.re), im: Math.floor(z.im) };\n}\nfunction mtoc2_cceil(z) {\n return { re: Math.ceil(z.re), im: Math.ceil(z.im) };\n}\nfunction mtoc2_cround(z) {\n // MATLAB rounds each component half-away-from-zero.\n const half = x => Math.sign(x) * Math.round(Math.abs(x));\n return { re: half(z.re), im: half(z.im) };\n}\nfunction mtoc2_cfix(z) {\n return { re: Math.trunc(z.re), im: Math.trunc(z.im) };\n}\nfunction mtoc2_csign(z) {\n if (z.re === 0 && z.im === 0) return { re: 0, im: 0 };\n const m = Math.hypot(z.re, z.im);\n return { re: z.re / m, im: z.im / m };\n}\n",
|
|
77606
|
+
"cscalar.js": "// JS sibling of `cscalar.h`. JS has no native complex type, so each\n// helper takes and returns `{re, im}` objects. Mirrors the C\n// signatures so emitJs renders calls structurally identical to the\n// C path (just with JS objects instead of `double _Complex`).\n//\n// Division (`mtoc2_cdiv`) lives in `cdiv.js` because it needs\n// Smith's algorithm with signed-zero detection to match numbl\n// byte-for-byte.\n\nfunction mtoc2_cmake(re, im) {\n return { re, im };\n}\nfunction mtoc2_creal(z) {\n return z.re;\n}\nfunction mtoc2_cimag(z) {\n return z.im;\n}\nfunction mtoc2_cadd(a, b) {\n return { re: a.re + b.re, im: a.im + b.im };\n}\nfunction mtoc2_csub(a, b) {\n return { re: a.re - b.re, im: a.im - b.im };\n}\nfunction mtoc2_cmul(a, b) {\n return { re: a.re * b.re - a.im * b.im, im: a.re * b.im + a.im * b.re };\n}\nfunction mtoc2_cneg(z) {\n return { re: -z.re, im: -z.im };\n}\nfunction mtoc2_cconj(z) {\n return { re: z.re, im: -z.im };\n}\nfunction mtoc2_cabs(z) {\n return Math.hypot(z.re, z.im);\n}\nfunction mtoc2_cangle(z) {\n return Math.atan2(z.im, z.re);\n}\nfunction mtoc2_cnonzero(z) {\n return z.re !== 0 || z.im !== 0;\n}\nfunction mtoc2_ceq(a, b) {\n return a.re === b.re && a.im === b.im;\n}\nfunction mtoc2_cne(a, b) {\n return a.re !== b.re || a.im !== b.im;\n}\n\n// `cpow(a, b) = exp(b * log(a))`. Matches numbl / C99 `cpow` for\n// finite inputs; special zero / pole cases follow the same path\n// the C side picks (exp(NaN) = NaN, etc.).\nfunction clog(z) {\n // Normalize a -0 real part to +0 so log(-0) (a real -0) gives\n // -Inf + 0i, not -Inf + \u03C0i \u2014 MATLAB / C99 treat -0 as 0, not as an\n // approach-from-below negative. atan2's -0 second arg only changes the\n // result when the first arg is also 0, so this affects nothing else.\n const reAngle = z.re === 0 ? 0 : z.re;\n return {\n re: Math.log(Math.hypot(z.re, z.im)),\n im: Math.atan2(z.im, reAngle),\n };\n}\nfunction cexp(z) {\n const m = Math.exp(z.re);\n // Real-valued input (im === 0): the imaginary lane is m*sin(0) = 0, but\n // when m overflows to Inf that becomes Inf*0 = NaN. Return a clean 0\n // (matches the interpreter's real exp and C99 cexp).\n if (z.im === 0) return { re: m, im: 0 };\n return { re: m * Math.cos(z.im), im: m * Math.sin(z.im) };\n}\nfunction mtoc2_cpow(a, b) {\n // Zero base: match the interpreter's complexPow (helpers/arithmetic.ts)\n // \u2014 0^0 = 1, a positive real part of the exponent gives 0 (regardless\n // of the imaginary part), and anything else gives Inf+0i. The old\n // guard required b.im===0 for the zero case and otherwise returned\n // NaN+NaNi.\n if (a.re === 0 && a.im === 0) {\n if (b.re === 0 && b.im === 0) return { re: 1, im: 0 };\n if (b.re > 0) return { re: 0, im: 0 };\n return { re: Infinity, im: 0 };\n }\n return cexp(mtoc2_cmul(b, clog(a)));\n}\n\n/** True when `z` is a NaN sitting on the real axis.\n *\n * These helpers are reached both from genuinely complex arithmetic and from\n * the *lift* the JIT performs on a real argument whose sign it cannot prove\n * (`sqrt(x)`, `log(x)`). MATLAB's sqrt(NaN) and log(NaN) are a real NaN, so a\n * lifted NaN must come back as NaN + 0i and not, say, 0 + NaN i: the lift is\n * a compilation detail and must not change what `real`, `isreal`,\n * `jsonencode` or a printed value say. */\nfunction nanOnRealAxis(z) {\n return z.im === 0 && Number.isNaN(z.re);\n}\n\n// Unary math.\nfunction mtoc2_csqrt(z) {\n // Pure-real input: compute directly. Smith's formula below suffers\n // catastrophic cancellation/overflow when z.im === 0 \u2014 e.g.\n // sqrt(-Inf) \u2192 sqrt((Inf + -Inf)/2) = sqrt(NaN) = NaN, and\n // sqrt(-1e308) \u2192 sqrt((1e308 - -1e308)/2) overflows to Inf instead of\n // 1e154. Mirror the interpreter's complexSqrt (math.ts) and C's libm\n // csqrt, both of which special-case the real axis.\n if (z.im === 0) {\n if (Number.isNaN(z.re)) return { re: z.re, im: 0 };\n if (z.re >= 0) return { re: Math.sqrt(z.re), im: 0 };\n return { re: 0, im: Math.sqrt(-z.re) };\n }\n // Smith's stable formula for hypot * sign.\n const r = Math.hypot(z.re, z.im);\n if (r === 0) return { re: 0, im: 0 };\n const re = Math.sqrt((r + z.re) / 2);\n const im = (z.im >= 0 ? 1 : -1) * Math.sqrt((r - z.re) / 2);\n return { re, im };\n}\nfunction mtoc2_cexp(z) {\n return cexp(z);\n}\nfunction mtoc2_clog(z) {\n if (nanOnRealAxis(z)) return { re: z.re, im: 0 };\n return clog(z);\n}\nfunction mtoc2_clog2(z) {\n if (nanOnRealAxis(z)) return { re: z.re, im: 0 };\n const l = clog(z);\n const lg2 = Math.log(2);\n return { re: l.re / lg2, im: l.im / lg2 };\n}\nfunction mtoc2_clog10(z) {\n if (nanOnRealAxis(z)) return { re: z.re, im: 0 };\n const l = clog(z);\n const lg10 = Math.log(10);\n return { re: l.re / lg10, im: l.im / lg10 };\n}\nfunction mtoc2_csin(z) {\n // Guard 0*Inf=NaN on the imaginary axis: for a pure-imaginary input\n // (sin(z.re)===0), the real lane is 0 and the imaginary lane is\n // \xB1sinh(im); cosh/sinh overflow to Inf for large |im|, and 0*Inf would\n // poison the result. C99 csin special-cases this \u2014 match it.\n const sr = Math.sin(z.re);\n const cr = Math.cos(z.re);\n return {\n re: sr === 0 ? 0 : sr * Math.cosh(z.im),\n im: cr === 0 ? 0 : cr * Math.sinh(z.im),\n };\n}\nfunction mtoc2_ccos(z) {\n const cr = Math.cos(z.re);\n const sr = Math.sin(z.re);\n return {\n re: cr === 0 ? 0 : cr * Math.cosh(z.im),\n im: sr === 0 ? 0 : -sr * Math.sinh(z.im),\n };\n}\nfunction mtoc2_ctan(z) {\n // Double-angle form, matching the interpreter (interpreter/builtins/\n // math.ts) and C99 ctan. Computing sin(z)/cos(z) with a |cos|^2\n // denominator loses the (tiny but nonzero) real part and overflows\n // for large imaginary parts \u2014 e.g. tan(1+200i) collapsed to 1i.\n const denom = Math.cos(2 * z.re) + Math.cosh(2 * z.im);\n return { re: Math.sin(2 * z.re) / denom, im: Math.sinh(2 * z.im) / denom };\n}\nfunction mtoc2_catan(z) {\n // Real-valued input (im === 0): atan is a clean real function. The\n // complex formula leaves a spurious \xB11e-17i residue (and NaN+NaNi once\n // 1\xB1iz overflows, e.g. atan(1e300)). Take the real path.\n if (z.im === 0) return { re: Math.atan(z.re), im: 0 };\n // atan(z) = (i/2)\xB7log((1 \u2212 iz)/(1 + iz)) \u2014 MATLAB's branch (atan(2i) =\n // \u22121.5708 + 0.5493i). The C runtime overrides its libc catan (which\n // uses the opposite +\u03C0/2 Annex-G branch) to match this.\n const iz = { re: -z.im, im: z.re }; // i*z\n const num = { re: 1 - iz.re, im: -iz.im }; // 1 - iz\n const denom = { re: 1 + iz.re, im: iz.im }; // 1 + iz\n const dd = denom.re * denom.re + denom.im * denom.im;\n const q = {\n re: (num.re * denom.re + num.im * denom.im) / dd,\n im: (num.im * denom.re - num.re * denom.im) / dd,\n };\n const l = clog(q);\n return { re: -l.im / 2, im: l.re / 2 };\n}\n// Hyperbolic sinh/cosh/tanh \u2014 byte-for-byte with the interpreter's\n// complex formulas (interpreter/builtins/math.ts). Real-valued input\n// (im === 0) falls out cleanly: cos(0)=1, sin(0)=0, so the imaginary\n// lane is exactly 0.\nfunction mtoc2_csinh(z) {\n return {\n re: Math.sinh(z.re) * Math.cos(z.im),\n im: Math.cosh(z.re) * Math.sin(z.im),\n };\n}\nfunction mtoc2_ccosh(z) {\n return {\n re: Math.cosh(z.re) * Math.cos(z.im),\n im: Math.sinh(z.re) * Math.sin(z.im),\n };\n}\nfunction mtoc2_ctanh(z) {\n const denom = Math.cosh(2 * z.re) + Math.cos(2 * z.im);\n return { re: Math.sinh(2 * z.re) / denom, im: Math.sin(2 * z.im) / denom };\n}\nfunction mtoc2_cfloor(z) {\n return { re: Math.floor(z.re), im: Math.floor(z.im) };\n}\nfunction mtoc2_cceil(z) {\n return { re: Math.ceil(z.re), im: Math.ceil(z.im) };\n}\nfunction mtoc2_cround(z) {\n // MATLAB rounds each component half-away-from-zero.\n const half = x => Math.sign(x) * Math.round(Math.abs(x));\n return { re: half(z.re), im: half(z.im) };\n}\nfunction mtoc2_cfix(z) {\n return { re: Math.trunc(z.re), im: Math.trunc(z.im) };\n}\nfunction mtoc2_csign(z) {\n if (z.re === 0 && z.im === 0) return { re: 0, im: 0 };\n const m = Math.hypot(z.re, z.im);\n return { re: z.re / m, im: z.im / m };\n}\n",
|
|
74274
77607
|
"deep_clone.js": '/* Deep-clone an owned-typed runtime value so a subsequent member /\n * indexed write through one alias doesn\'t leak to others. Mirrors\n * the c-aot per-typedef `_copy` protocol: every Var-RHS Assign /\n * MemberLoad-RHS Assign / function-call arg of an owned type is\n * wrapped through this helper at emit time, so JS-side aliasing\n * stops at the assignment boundary.\n *\n * Recognises the runtime shapes the rest of mtoc2 emits:\n * - RuntimeTensor (`{mtoc2Tag:"tensor", shape, data, imag?, isLogical?}`)\n * - RuntimeChar (`{mtoc2Tag:"char", value}`)\n * - struct / class / handle / handle-capture objects \u2014 plain JS\n * objects, optionally with a non-enumerable `mtoc2Class` tag\n * (class instances) that must survive the clone for method\n * dispatch\n *\n * Primitives (numbers, booleans, strings, null/undefined) flow\n * through unchanged \u2014 they\'re already value-typed in JS.\n */\n\nfunction mtoc2_deep_clone(v) {\n if (v === null || typeof v !== "object") return v;\n if (v.mtoc2Tag === "tensor") {\n const out = {\n mtoc2Tag: "tensor",\n shape: v.shape.slice(),\n data: v.data.slice(),\n };\n if (v.imag !== undefined) out.imag = v.imag.slice();\n if (v.isLogical) out.isLogical = true;\n return out;\n }\n if (v.mtoc2Tag === "char") {\n return { mtoc2Tag: "char", value: v.value };\n }\n if (v.mtoc2Tag === "cell") {\n return {\n mtoc2Tag: "cell",\n shape: v.shape.slice(),\n data: v.data.map(mtoc2_deep_clone),\n };\n }\n if (v.mtoc2Handle === true) {\n // Function handle \u2014 captures are deep-cloned so a later write\n // through one alias doesn\'t bleed into another handle\'s frozen\n // capture snapshot.\n if (v.kind === "named") {\n return { mtoc2Handle: true, kind: "named", name: v.name };\n }\n const captures = {};\n for (const k of Object.keys(v.captures)) {\n captures[k] = mtoc2_deep_clone(v.captures[k]);\n }\n return {\n mtoc2Handle: true,\n kind: "anon",\n params: v.params,\n body: v.body,\n captures,\n };\n }\n // Plain struct / class instance: walk enumerable fields, then\n // restore the non-enumerable `mtoc2Class` tag if it was present.\n const out = {};\n for (const k of Object.keys(v)) {\n out[k] = mtoc2_deep_clone(v[k]);\n }\n const tag = Object.getOwnPropertyDescriptor(v, "mtoc2Class");\n if (tag !== undefined) {\n Object.defineProperty(out, "mtoc2Class", {\n value: tag.value,\n enumerable: false,\n writable: false,\n });\n }\n return out;\n}\n',
|
|
74275
77608
|
"isequal.js": "// JS sibling of `isequal.h`. Same real-numeric equality semantics for\n// the js-aot backend. Tensors carry `shape` / `data` (the JS analogue\n// of the C struct's `dims` / `real`).\n\nfunction mtoc2_isequal_tt(a, b) {\n if (a.shape.length !== b.shape.length) return 0;\n let n = 1;\n for (let i = 0; i < a.shape.length; i++) {\n if (a.shape[i] !== b.shape[i]) return 0;\n n *= a.shape[i];\n }\n for (let i = 0; i < n; i++) {\n if (a.data[i] !== b.data[i]) return 0;\n }\n return 1;\n}\n\nfunction mtoc2_isequal_st(s, t) {\n let n = 1;\n for (let i = 0; i < t.shape.length; i++) n *= t.shape[i];\n if (n !== 1) return 0;\n return t.data[0] === s ? 1 : 0;\n}\n",
|
|
74276
77609
|
"tictoc.js": '// JS sibling of `tictoc.h`. Same "one global timer" semantics. Uses\n// `performance.now()` to match numbl\'s wall-clock source; the output\n// format string mirrors numbl\'s `"Elapsed time is %.6f seconds.\\n"`\n// so the cross-runner\'s masking regex still treats both runtimes as\n// equivalent.\n//\n// Module-scope state for the shared `tic` slot. The codegen path\n// inlines this declaration alongside the helpers; the interpreter\n// imports them as ES exports and the same module-scope `let` is the\n// canonical slot.\n\nlet mtoc2_tic_seconds = 0;\n\nfunction mtoc2_now_seconds() {\n // `performance.now()` returns milliseconds since some monotonic\n // epoch; divide for seconds. (Node and browsers both supply it on\n // `globalThis.performance` as of recent versions.)\n return performance.now() / 1000;\n}\n\nfunction mtoc2_tic() {\n mtoc2_tic_seconds = mtoc2_now_seconds();\n return mtoc2_tic_seconds;\n}\n\nfunction mtoc2_toc() {\n return mtoc2_now_seconds() - mtoc2_tic_seconds;\n}\n\nfunction mtoc2_toc_handle(start_seconds) {\n return mtoc2_now_seconds() - start_seconds;\n}\n\nfunction mtoc2_toc_print() {\n const elapsed = mtoc2_toc();\n $write(`Elapsed time is ${elapsed.toFixed(6)} seconds.\\n`);\n}\n\nfunction mtoc2_toc_handle_print(start_seconds) {\n const elapsed = mtoc2_now_seconds() - start_seconds;\n $write(`Elapsed time is ${elapsed.toFixed(6)} seconds.\\n`);\n}\n',
|
|
@@ -79275,7 +82608,7 @@ function cCos(z) {
|
|
|
79275
82608
|
im: -Math.sin(z.re) * Math.sinh(z.im)
|
|
79276
82609
|
};
|
|
79277
82610
|
}
|
|
79278
|
-
function
|
|
82611
|
+
function cdiv3(a, b) {
|
|
79279
82612
|
if (Math.abs(b.re) >= Math.abs(b.im)) {
|
|
79280
82613
|
const r2 = b.im / b.re;
|
|
79281
82614
|
const den2 = b.re + r2 * b.im;
|
|
@@ -79286,7 +82619,7 @@ function cdiv2(a, b) {
|
|
|
79286
82619
|
return { re: (a.re * r + a.im) / den, im: (a.im * r - a.re) / den };
|
|
79287
82620
|
}
|
|
79288
82621
|
function cTan(z) {
|
|
79289
|
-
return
|
|
82622
|
+
return cdiv3(cSin(z), cCos(z));
|
|
79290
82623
|
}
|
|
79291
82624
|
function cSinh(z) {
|
|
79292
82625
|
return {
|
|
@@ -79308,7 +82641,7 @@ function cAtan(z) {
|
|
|
79308
82641
|
const iz = { re: -z.im, im: z.re };
|
|
79309
82642
|
const num = { re: 1 - iz.re, im: -iz.im };
|
|
79310
82643
|
const den = { re: 1 + iz.re, im: iz.im };
|
|
79311
|
-
const q =
|
|
82644
|
+
const q = cdiv3(num, den);
|
|
79312
82645
|
const l = cLog(q);
|
|
79313
82646
|
return { re: -l.im / 2, im: l.re / 2 };
|
|
79314
82647
|
}
|
|
@@ -87018,6 +90351,24 @@ function lowerMultiAssign(s) {
|
|
|
87018
90351
|
);
|
|
87019
90352
|
}
|
|
87020
90353
|
}
|
|
90354
|
+
if (target?.kind === "mtoc2UserFunction") {
|
|
90355
|
+
const userBuiltin = this.workspace.getUserBuiltin(target.name);
|
|
90356
|
+
if (!userBuiltin) {
|
|
90357
|
+
throw new UnsupportedConstruct(
|
|
90358
|
+
`internal: workspace resolved '${callName}' to a .mtoc2.js function but no Builtin is loaded`,
|
|
90359
|
+
s.span
|
|
90360
|
+
);
|
|
90361
|
+
}
|
|
90362
|
+
return buildBuiltinMultiAssign.call(
|
|
90363
|
+
this,
|
|
90364
|
+
callName,
|
|
90365
|
+
userBuiltin,
|
|
90366
|
+
anfArgs,
|
|
90367
|
+
argTypes,
|
|
90368
|
+
argHoists,
|
|
90369
|
+
s
|
|
90370
|
+
);
|
|
90371
|
+
}
|
|
87021
90372
|
if (target?.kind !== "userFunction") {
|
|
87022
90373
|
throw new UnsupportedConstruct(
|
|
87023
90374
|
`multi-assign of '${callName}': only user-defined functions can appear on the right of '[...] = ...' (or as a bare multi-output statement)`,
|
|
@@ -87553,23 +90904,6 @@ function lowerIndexSliceStore(lvalue, exprAst, span) {
|
|
|
87553
90904
|
}
|
|
87554
90905
|
}
|
|
87555
90906
|
}
|
|
87556
|
-
if (!isSingleSlot && r.baseTy.kind === "Numeric") {
|
|
87557
|
-
for (let i = 0; i < slots.length; i++) {
|
|
87558
|
-
const slot = slots[i];
|
|
87559
|
-
if (slot.kind !== "Scalar") continue;
|
|
87560
|
-
const dim = r.baseTy.dims[i];
|
|
87561
|
-
const t = slot.expr.ty;
|
|
87562
|
-
const dimKnown = dim !== void 0 && dim.kind === "exact";
|
|
87563
|
-
const valKnown = t.kind === "Numeric" && typeof t.exact === "number";
|
|
87564
|
-
const provablyInBounds = dimKnown && valKnown && Math.round(t.exact) >= 1 && Math.round(t.exact) <= dim.value;
|
|
87565
|
-
if (!provablyInBounds) {
|
|
87566
|
-
throw new UnsupportedConstruct(
|
|
87567
|
-
`indexed write to '${displayName}' at axis ${i + 1}: cannot statically prove the index stays within the tensor's bounds; would auto-grow / OOB in MATLAB, but auto-grow is not modeled in the JIT`,
|
|
87568
|
-
slot.span
|
|
87569
|
-
);
|
|
87570
|
-
}
|
|
87571
|
-
}
|
|
87572
|
-
}
|
|
87573
90907
|
const rawRhs = this.lowerExpr(exprAst);
|
|
87574
90908
|
if (!isNumeric2(rawRhs.ty)) {
|
|
87575
90909
|
throw new TypeError2(
|
|
@@ -87885,6 +91219,8 @@ var Lowerer = class {
|
|
|
87885
91219
|
return lowerMultiAssign.call(this, s);
|
|
87886
91220
|
case "If":
|
|
87887
91221
|
return this.lowerIf(s);
|
|
91222
|
+
case "Switch":
|
|
91223
|
+
return this.lowerSwitch(s);
|
|
87888
91224
|
case "While":
|
|
87889
91225
|
return this.lowerWhile(s);
|
|
87890
91226
|
case "For":
|
|
@@ -87976,6 +91312,23 @@ var Lowerer = class {
|
|
|
87976
91312
|
return entries;
|
|
87977
91313
|
}
|
|
87978
91314
|
lowerExprStmt(s) {
|
|
91315
|
+
if (this.env.get("tic") === void 0 && !this.workspace.isClass("tic")) {
|
|
91316
|
+
const bareTic = s.expr.type === "Ident" && s.expr.name === "tic" || s.expr.type === "FuncCall" && s.expr.name === "tic" && s.expr.args.length === 0;
|
|
91317
|
+
if (bareTic) {
|
|
91318
|
+
return {
|
|
91319
|
+
kind: "ExprStmt",
|
|
91320
|
+
expr: {
|
|
91321
|
+
kind: "Call",
|
|
91322
|
+
cName: "mtoc2_tic",
|
|
91323
|
+
name: "tic",
|
|
91324
|
+
args: [],
|
|
91325
|
+
ty: VOID,
|
|
91326
|
+
span: s.expr.span
|
|
91327
|
+
},
|
|
91328
|
+
span: s.span
|
|
91329
|
+
};
|
|
91330
|
+
}
|
|
91331
|
+
}
|
|
87979
91332
|
if (this.env.get("toc") === void 0 && !this.workspace.isClass("toc")) {
|
|
87980
91333
|
if (s.expr.type === "Ident" && s.expr.name === "toc") {
|
|
87981
91334
|
return {
|
|
@@ -88582,6 +91935,125 @@ var Lowerer = class {
|
|
|
88582
91935
|
}
|
|
88583
91936
|
];
|
|
88584
91937
|
}
|
|
91938
|
+
/** MATLAB `switch` lowered to the equivalent if/elseif chain.
|
|
91939
|
+
*
|
|
91940
|
+
* The subject is evaluated once — hoisted to a temp unless it is already a
|
|
91941
|
+
* plain variable — and each case label becomes an equality test against it:
|
|
91942
|
+
* `strcmp` for text, `==` for numbers. A `case {a, b}` list is the OR of
|
|
91943
|
+
* the individual tests. Everything after that is `lowerIf`'s problem, which
|
|
91944
|
+
* means switch inherits its branch-env merging and cond folding.
|
|
91945
|
+
*
|
|
91946
|
+
* Declined (leaving the unit to the interpreter, as before this existed):
|
|
91947
|
+
* a subject that is neither a scalar number nor text, a label whose kind
|
|
91948
|
+
* does not match the subject's, and an empty `case {}`.
|
|
91949
|
+
*/
|
|
91950
|
+
lowerSwitch(s) {
|
|
91951
|
+
const span = s.span;
|
|
91952
|
+
const pre = [];
|
|
91953
|
+
let subject = s.expr;
|
|
91954
|
+
if (!(s.expr.type === "Ident" && this.env.has(s.expr.name))) {
|
|
91955
|
+
const tmp = this.freshTempName();
|
|
91956
|
+
const assign = {
|
|
91957
|
+
type: "Assign",
|
|
91958
|
+
name: tmp,
|
|
91959
|
+
expr: s.expr,
|
|
91960
|
+
suppressed: true,
|
|
91961
|
+
span
|
|
91962
|
+
};
|
|
91963
|
+
const lowered = this.lowerStmt(assign);
|
|
91964
|
+
if (lowered !== null) {
|
|
91965
|
+
if (Array.isArray(lowered)) pre.push(...lowered);
|
|
91966
|
+
else pre.push(lowered);
|
|
91967
|
+
}
|
|
91968
|
+
subject = { type: "Ident", name: tmp, span };
|
|
91969
|
+
}
|
|
91970
|
+
const subjTy = this.env.get(subject.name)?.ty;
|
|
91971
|
+
if (subjTy === void 0) {
|
|
91972
|
+
throw new UnsupportedConstruct(
|
|
91973
|
+
"switch subject is not a value the JIT can type",
|
|
91974
|
+
span
|
|
91975
|
+
);
|
|
91976
|
+
}
|
|
91977
|
+
const subjIsText = subjTy.kind === "Char" || subjTy.kind === "String";
|
|
91978
|
+
const subjIsNum = isScalarRealNumeric(subjTy) || subjTy.kind === "Numeric";
|
|
91979
|
+
if (!subjIsText && !(subjIsNum && isScalar(subjTy))) {
|
|
91980
|
+
throw new UnsupportedConstruct(
|
|
91981
|
+
`switch on a ${typeToString(subjTy)} subject is not supported (scalar numeric or text only)`,
|
|
91982
|
+
span
|
|
91983
|
+
);
|
|
91984
|
+
}
|
|
91985
|
+
const labelIsText = (label) => {
|
|
91986
|
+
if (label.type === "Char" || label.type === "String") return true;
|
|
91987
|
+
if (label.type === "Ident") {
|
|
91988
|
+
const t = this.env.get(label.name)?.ty;
|
|
91989
|
+
return t !== void 0 && (t.kind === "Char" || t.kind === "String");
|
|
91990
|
+
}
|
|
91991
|
+
return false;
|
|
91992
|
+
};
|
|
91993
|
+
const labelCond = (label) => {
|
|
91994
|
+
if (subjIsText) {
|
|
91995
|
+
if (!labelIsText(label)) {
|
|
91996
|
+
throw new UnsupportedConstruct(
|
|
91997
|
+
"switch on text with a non-text case label is not supported",
|
|
91998
|
+
label.span
|
|
91999
|
+
);
|
|
92000
|
+
}
|
|
92001
|
+
return {
|
|
92002
|
+
type: "FuncCall",
|
|
92003
|
+
name: "strcmp",
|
|
92004
|
+
args: [subject, label],
|
|
92005
|
+
span: label.span
|
|
92006
|
+
};
|
|
92007
|
+
}
|
|
92008
|
+
if (labelIsText(label)) {
|
|
92009
|
+
throw new UnsupportedConstruct(
|
|
92010
|
+
"switch on a number with a text case label is not supported",
|
|
92011
|
+
label.span
|
|
92012
|
+
);
|
|
92013
|
+
}
|
|
92014
|
+
return {
|
|
92015
|
+
type: "Binary",
|
|
92016
|
+
left: subject,
|
|
92017
|
+
op: "Equal" /* Equal */,
|
|
92018
|
+
right: label,
|
|
92019
|
+
span: label.span
|
|
92020
|
+
};
|
|
92021
|
+
};
|
|
92022
|
+
const caseCond = (value) => {
|
|
92023
|
+
if (value.type !== "Cell") return labelCond(value);
|
|
92024
|
+
const items = value.rows.flat();
|
|
92025
|
+
if (items.length === 0) {
|
|
92026
|
+
throw new UnsupportedConstruct(
|
|
92027
|
+
"switch with an empty case list is not supported",
|
|
92028
|
+
value.span
|
|
92029
|
+
);
|
|
92030
|
+
}
|
|
92031
|
+
return items.map(labelCond).reduce((acc, c) => ({
|
|
92032
|
+
type: "Binary",
|
|
92033
|
+
left: acc,
|
|
92034
|
+
op: "OrOr" /* OrOr */,
|
|
92035
|
+
right: c,
|
|
92036
|
+
span: value.span
|
|
92037
|
+
}));
|
|
92038
|
+
};
|
|
92039
|
+
if (s.cases.length === 0) {
|
|
92040
|
+
const body = s.otherwise ? this.lowerStmts(s.otherwise) : [];
|
|
92041
|
+
return [...pre, ...body];
|
|
92042
|
+
}
|
|
92043
|
+
const chain = {
|
|
92044
|
+
type: "If",
|
|
92045
|
+
cond: caseCond(s.cases[0].value),
|
|
92046
|
+
thenBody: s.cases[0].body,
|
|
92047
|
+
elseifBlocks: s.cases.slice(1).map((c) => ({
|
|
92048
|
+
cond: caseCond(c.value),
|
|
92049
|
+
body: c.body
|
|
92050
|
+
})),
|
|
92051
|
+
elseBody: s.otherwise,
|
|
92052
|
+
span
|
|
92053
|
+
};
|
|
92054
|
+
const ir = this.lowerIf(chain);
|
|
92055
|
+
return [...pre, ...Array.isArray(ir) ? ir : [ir]];
|
|
92056
|
+
}
|
|
88585
92057
|
lowerWhile(s) {
|
|
88586
92058
|
const envBefore = new Map(this.env);
|
|
88587
92059
|
stripExactFromEnv(this.env, collectAssignedNames(s.body));
|
|
@@ -91415,30 +94887,39 @@ function compileSpec(args) {
|
|
|
91415
94887
|
const { workspace, lowerer, funcDecl, argTypes, nargout } = args;
|
|
91416
94888
|
workspace.finalize();
|
|
91417
94889
|
const widenedArgTypes = argTypes.map(withoutExact);
|
|
91418
|
-
const
|
|
91419
|
-
|
|
91420
|
-
|
|
91421
|
-
|
|
91422
|
-
|
|
91423
|
-
|
|
91424
|
-
|
|
91425
|
-
|
|
91426
|
-
|
|
91427
|
-
|
|
91428
|
-
|
|
91429
|
-
|
|
91430
|
-
|
|
91431
|
-
|
|
91432
|
-
|
|
91433
|
-
|
|
91434
|
-
|
|
91435
|
-
|
|
91436
|
-
|
|
91437
|
-
|
|
91438
|
-
|
|
91439
|
-
|
|
91440
|
-
|
|
91441
|
-
|
|
94890
|
+
const before = new Set(lowerer.specializations.keys());
|
|
94891
|
+
try {
|
|
94892
|
+
const spec = specializeUserFunction.call(
|
|
94893
|
+
lowerer,
|
|
94894
|
+
funcDecl,
|
|
94895
|
+
widenedArgTypes,
|
|
94896
|
+
void 0,
|
|
94897
|
+
void 0,
|
|
94898
|
+
void 0,
|
|
94899
|
+
nargout,
|
|
94900
|
+
void 0
|
|
94901
|
+
);
|
|
94902
|
+
assertNoNonVoidBareExprStmts(spec);
|
|
94903
|
+
const prog = {
|
|
94904
|
+
topLevelStmts: [],
|
|
94905
|
+
functions: new Map(lowerer.specializations)
|
|
94906
|
+
};
|
|
94907
|
+
const { source, activatedSnippets } = emitJsProgram(prog, {
|
|
94908
|
+
workspace,
|
|
94909
|
+
exposeSpec: spec.cName
|
|
94910
|
+
});
|
|
94911
|
+
return {
|
|
94912
|
+
cName: spec.cName,
|
|
94913
|
+
source,
|
|
94914
|
+
activatedSnippets,
|
|
94915
|
+
outputTypes: spec.outputTypes
|
|
94916
|
+
};
|
|
94917
|
+
} catch (err) {
|
|
94918
|
+
for (const key of lowerer.specializations.keys()) {
|
|
94919
|
+
if (!before.has(key)) lowerer.specializations.delete(key);
|
|
94920
|
+
}
|
|
94921
|
+
throw err;
|
|
94922
|
+
}
|
|
91442
94923
|
}
|
|
91443
94924
|
function assertNoNonVoidBareExprStmts(spec) {
|
|
91444
94925
|
const walk = (stmts) => {
|
|
@@ -92489,7 +95970,17 @@ function jitTypeToCompilerType(jt) {
|
|
|
92489
95970
|
case "char":
|
|
92490
95971
|
return { kind: "Char" };
|
|
92491
95972
|
// Kinds the JIT path doesn't accept yet — fall through to interp.
|
|
92492
|
-
case "struct":
|
|
95973
|
+
case "struct": {
|
|
95974
|
+
if (jt.fields === void 0) return null;
|
|
95975
|
+
const names = Object.keys(jt.fields).sort();
|
|
95976
|
+
const fields = [];
|
|
95977
|
+
for (const name of names) {
|
|
95978
|
+
const fty = jitTypeToCompilerType(jt.fields[name]);
|
|
95979
|
+
if (fty === null) return null;
|
|
95980
|
+
fields.push({ name, ty: fty });
|
|
95981
|
+
}
|
|
95982
|
+
return { kind: "Struct", fields };
|
|
95983
|
+
}
|
|
92493
95984
|
case "struct_array":
|
|
92494
95985
|
case "class_instance":
|
|
92495
95986
|
case "sparse_matrix":
|
|
@@ -92535,11 +96026,20 @@ function numblToJit(v, paramType) {
|
|
|
92535
96026
|
if (isRuntimeComplexNumber(v)) {
|
|
92536
96027
|
return { re: v.re, im: v.im };
|
|
92537
96028
|
}
|
|
96029
|
+
if (isRuntimeStruct(v)) {
|
|
96030
|
+
const sty = paramType?.kind === "Struct" ? paramType : void 0;
|
|
96031
|
+
const out = {};
|
|
96032
|
+
for (const [name, fv] of v.fields) {
|
|
96033
|
+
const fty = sty?.fields.find((f) => f.name === name)?.ty;
|
|
96034
|
+
out[name] = numblToJit(fv, fty);
|
|
96035
|
+
}
|
|
96036
|
+
return out;
|
|
96037
|
+
}
|
|
92538
96038
|
throw new Error(
|
|
92539
96039
|
`numblToJit: unsupported RuntimeValue (executor should have declined)`
|
|
92540
96040
|
);
|
|
92541
96041
|
}
|
|
92542
|
-
function jitToNumbl(v) {
|
|
96042
|
+
function jitToNumbl(v, retType) {
|
|
92543
96043
|
if (typeof v === "number") return v;
|
|
92544
96044
|
if (typeof v === "boolean") return v;
|
|
92545
96045
|
if (typeof v === "string") return v;
|
|
@@ -92562,6 +96062,14 @@ function jitToNumbl(v) {
|
|
|
92562
96062
|
if (typeof tagged.re === "number" && typeof tagged.im === "number") {
|
|
92563
96063
|
return new RuntimeComplexNumber(tagged.re, tagged.im);
|
|
92564
96064
|
}
|
|
96065
|
+
if (retType?.kind === "Struct") {
|
|
96066
|
+
const fields = /* @__PURE__ */ new Map();
|
|
96067
|
+
for (const f of retType.fields) {
|
|
96068
|
+
const fv = v[f.name];
|
|
96069
|
+
if (fv !== void 0) fields.set(f.name, jitToNumbl(fv, f.ty));
|
|
96070
|
+
}
|
|
96071
|
+
return new RuntimeStruct(fields);
|
|
96072
|
+
}
|
|
92565
96073
|
throw new Error(`jitToNumbl: unrecognized return shape`);
|
|
92566
96074
|
}
|
|
92567
96075
|
function isGrowBail(e) {
|
|
@@ -92635,7 +96143,8 @@ var jitCallExecutor = {
|
|
|
92635
96143
|
name: "jit-call",
|
|
92636
96144
|
propose(lowered, ctx) {
|
|
92637
96145
|
if (lowered.kind !== "call") return null;
|
|
92638
|
-
if (ctx.interp.loopDepth > 0
|
|
96146
|
+
if (ctx.interp.loopDepth > 0 && ctx.interp.jitDeclinedLoopDepth === 0)
|
|
96147
|
+
return null;
|
|
92639
96148
|
const classification = lowered.classification;
|
|
92640
96149
|
if (ctx.interp.optimization === "2" && classification.assertsCJit) {
|
|
92641
96150
|
return null;
|
|
@@ -92667,7 +96176,7 @@ var jitCallExecutor = {
|
|
|
92667
96176
|
compile(d, ctx) {
|
|
92668
96177
|
const { workspace, lowerer } = getOrCreateSession(ctx.interp);
|
|
92669
96178
|
try {
|
|
92670
|
-
const { source, cName } = compileSpec({
|
|
96179
|
+
const { source, cName, outputTypes } = compileSpec({
|
|
92671
96180
|
workspace,
|
|
92672
96181
|
lowerer,
|
|
92673
96182
|
funcDecl: synthesizeFuncStmt(d.fn),
|
|
@@ -92683,12 +96192,13 @@ var jitCallExecutor = {
|
|
|
92683
96192
|
);
|
|
92684
96193
|
const factory = new Function(source)();
|
|
92685
96194
|
const specFn = factory(buildHostHelpers(interp.rt));
|
|
92686
|
-
return { specFn };
|
|
96195
|
+
return { specFn, outputTypes };
|
|
92687
96196
|
} catch (e) {
|
|
92688
96197
|
if (e instanceof UnsupportedConstruct || e instanceof TypeError2) {
|
|
92689
96198
|
recordJitDecline({
|
|
92690
96199
|
message: e.message,
|
|
92691
96200
|
kind: e.constructor.name,
|
|
96201
|
+
at: e.span ? { file: e.span.file, start: e.span.start } : void 0,
|
|
92692
96202
|
where: "jit-call"
|
|
92693
96203
|
});
|
|
92694
96204
|
return null;
|
|
@@ -92711,9 +96221,11 @@ var jitCallExecutor = {
|
|
|
92711
96221
|
`jit-call: expected array for nargout=${d.nargout}, got ${typeof result}`
|
|
92712
96222
|
);
|
|
92713
96223
|
}
|
|
92714
|
-
return {
|
|
96224
|
+
return {
|
|
96225
|
+
result: result.map((v, i) => jitToNumbl(v, compiled.outputTypes[i]))
|
|
96226
|
+
};
|
|
92715
96227
|
}
|
|
92716
|
-
return { result: jitToNumbl(result) };
|
|
96228
|
+
return { result: jitToNumbl(result, compiled.outputTypes[0]) };
|
|
92717
96229
|
} catch (e) {
|
|
92718
96230
|
if (isGrowBail(e)) {
|
|
92719
96231
|
ctx.interp.onJitBail?.(
|
|
@@ -92757,7 +96269,8 @@ var jitLoopExecutor = {
|
|
|
92757
96269
|
name: "jit-loop",
|
|
92758
96270
|
propose(lowered, ctx) {
|
|
92759
96271
|
if (lowered.kind !== "loop") return null;
|
|
92760
|
-
if (ctx.interp.loopDepth > 0
|
|
96272
|
+
if (ctx.interp.loopDepth > 0 && ctx.interp.jitDeclinedLoopDepth === 0)
|
|
96273
|
+
return null;
|
|
92761
96274
|
const classification = lowered.classification;
|
|
92762
96275
|
if (ctx.interp.optimization === "2" && classification.assertsCJit) {
|
|
92763
96276
|
return null;
|
|
@@ -92799,7 +96312,7 @@ var jitLoopExecutor = {
|
|
|
92799
96312
|
);
|
|
92800
96313
|
const nargout = d.outputs.length;
|
|
92801
96314
|
try {
|
|
92802
|
-
const { source, cName } = compileSpec({
|
|
96315
|
+
const { source, cName, outputTypes } = compileSpec({
|
|
92803
96316
|
workspace,
|
|
92804
96317
|
lowerer,
|
|
92805
96318
|
funcDecl,
|
|
@@ -92814,12 +96327,13 @@ var jitLoopExecutor = {
|
|
|
92814
96327
|
);
|
|
92815
96328
|
const factory = new Function(source)();
|
|
92816
96329
|
const specFn = factory(buildHostHelpers(interp.rt));
|
|
92817
|
-
return { specFn };
|
|
96330
|
+
return { specFn, outputTypes };
|
|
92818
96331
|
} catch (e) {
|
|
92819
96332
|
if (e instanceof UnsupportedConstruct || e instanceof TypeError2) {
|
|
92820
96333
|
recordJitDecline({
|
|
92821
96334
|
message: e.message,
|
|
92822
96335
|
kind: e.constructor.name,
|
|
96336
|
+
at: e.span ? { file: e.span.file, start: e.span.start } : void 0,
|
|
92823
96337
|
where: "jit-loop"
|
|
92824
96338
|
});
|
|
92825
96339
|
return null;
|
|
@@ -92844,7 +96358,9 @@ var jitLoopExecutor = {
|
|
|
92844
96358
|
if (d.outputs.length === 0) {
|
|
92845
96359
|
} else if (d.outputs.length === 1) {
|
|
92846
96360
|
if (result !== void 0) {
|
|
92847
|
-
const rv = ensureRuntimeValue(
|
|
96361
|
+
const rv = ensureRuntimeValue(
|
|
96362
|
+
jitToNumbl(result, compiled.outputTypes[0])
|
|
96363
|
+
);
|
|
92848
96364
|
interp.env.set(d.outputs[0], rv);
|
|
92849
96365
|
}
|
|
92850
96366
|
} else {
|
|
@@ -92856,7 +96372,9 @@ var jitLoopExecutor = {
|
|
|
92856
96372
|
for (let i = 0; i < d.outputs.length; i++) {
|
|
92857
96373
|
const elt = result[i];
|
|
92858
96374
|
if (elt !== void 0) {
|
|
92859
|
-
const rv = ensureRuntimeValue(
|
|
96375
|
+
const rv = ensureRuntimeValue(
|
|
96376
|
+
jitToNumbl(elt, compiled.outputTypes[i])
|
|
96377
|
+
);
|
|
92860
96378
|
interp.env.set(d.outputs[i], rv);
|
|
92861
96379
|
}
|
|
92862
96380
|
}
|
|
@@ -92944,7 +96462,7 @@ var jitTopLevelExecutor = {
|
|
|
92944
96462
|
);
|
|
92945
96463
|
const nargout = d.outputs.length;
|
|
92946
96464
|
try {
|
|
92947
|
-
const { source, cName } = compileSpec({
|
|
96465
|
+
const { source, cName, outputTypes } = compileSpec({
|
|
92948
96466
|
workspace,
|
|
92949
96467
|
lowerer,
|
|
92950
96468
|
funcDecl,
|
|
@@ -92959,12 +96477,13 @@ var jitTopLevelExecutor = {
|
|
|
92959
96477
|
);
|
|
92960
96478
|
const factory = new Function(source)();
|
|
92961
96479
|
const specFn = factory(buildHostHelpers(interp.rt));
|
|
92962
|
-
return { specFn, nargout };
|
|
96480
|
+
return { specFn, nargout, outputTypes };
|
|
92963
96481
|
} catch (e) {
|
|
92964
96482
|
if (e instanceof UnsupportedConstruct || e instanceof TypeError2) {
|
|
92965
96483
|
recordJitDecline({
|
|
92966
96484
|
message: e.message,
|
|
92967
96485
|
kind: e.constructor.name,
|
|
96486
|
+
at: e.span ? { file: e.span.file, start: e.span.start } : void 0,
|
|
92968
96487
|
where: "jit-top-level"
|
|
92969
96488
|
});
|
|
92970
96489
|
return null;
|
|
@@ -92989,7 +96508,9 @@ var jitTopLevelExecutor = {
|
|
|
92989
96508
|
if (d.outputs.length === 0) {
|
|
92990
96509
|
} else if (d.outputs.length === 1) {
|
|
92991
96510
|
if (result !== void 0) {
|
|
92992
|
-
const rv = ensureRuntimeValue(
|
|
96511
|
+
const rv = ensureRuntimeValue(
|
|
96512
|
+
jitToNumbl(result, compiled.outputTypes[0])
|
|
96513
|
+
);
|
|
92993
96514
|
interp.env.set(d.outputs[0], rv);
|
|
92994
96515
|
}
|
|
92995
96516
|
} else {
|
|
@@ -93001,7 +96522,9 @@ var jitTopLevelExecutor = {
|
|
|
93001
96522
|
for (let i = 0; i < d.outputs.length; i++) {
|
|
93002
96523
|
const elt = result[i];
|
|
93003
96524
|
if (elt !== void 0) {
|
|
93004
|
-
const rv = ensureRuntimeValue(
|
|
96525
|
+
const rv = ensureRuntimeValue(
|
|
96526
|
+
jitToNumbl(elt, compiled.outputTypes[i])
|
|
96527
|
+
);
|
|
93005
96528
|
interp.env.set(d.outputs[i], rv);
|
|
93006
96529
|
}
|
|
93007
96530
|
}
|