AssemblyScript is a great target in notebooks, it can increase code performance, run in WebWorkers and remove the slow start Javascript has when first loaded. Its compiler size is ok (2.5MB) if you are building something that needs high performance and your readers are willing to wait a little for it.
import {toochain} from "@tomlarkworthy/assembly-script"
...
toolchain.asc("<program>")
Binaryen compiler was shrunk from 3.5MB to 2MB by exluding optimizations and programs AssemblyScript does not use. ActionScript frontend itself is quite small, Binaryen is the bit that does the clever performance improving bit (optimizing compiler)
const N = 48, W = N * 2;
const m = new Float64Array(N * W);
const at = (i, j) => m[i * W + j];
const put = (i, j, v) => { m[i * W + j] = v; };
function fill(seed) {
let z = seed >>> 0;
for (let i = 0; i < N; i++) {
for (let j = 0; j < N; j++) {
z = (Math.imul(z, 1664525) + 1013904223) >>> 0;
put(i, j, (z >>> 8) / 8388608.0 - 1.0);
put(i, N + j, i === j ? 1.0 : 0.0);
}
put(i, i, at(i, i) + N);
}
}
return function invert(rounds) {
let acc = 0;
for (let r = 0; r < rounds; r++) {
fill(r + 1);
for (let c = 0; c < N; c++) {
let piv = c;
for (let i = c + 1; i < N; i++) {
if (Math.abs(at(i, c)) > Math.abs(at(piv, c))) piv = i;
}
if (piv !== c) {
for (let j = 0; j < W; j++) {
const t = at(c, j); put(c, j, at(piv, j)); put(piv, j, t);
}
}
const d = at(c, c);
for (let j = 0; j < W; j++) put(c, j, at(c, j) / d);
for (let i = 0; i < N; i++) {
if (i === c) continue;
const f = at(i, c);
if (f === 0.0) continue;
for (let j = 0; j < W; j++) put(i, j, at(i, j) - f * at(c, j));
}
}
for (let i = 0; i < N; i++) acc += at(i, N + i);
}
return acc;
};
(module
(type $0 (func))
(type $1 (func (param i32) (result f64)))
(global $main/m (mut i32) (i32.const 0))
(memory $0 1)
(data $0 (i32.const 1036) ",")
(data $0.1 (i32.const 1048) "\02\00\00\00\1c\00\00\00I\00n\00v\00a\00l\00i\00d\00 \00l\00e\00n\00g\00t\00h")
(data $1 (i32.const 1084) "<")
(data $1.1 (i32.const 1096) "\02\00\00\00&\00\00\00~\00l\00i\00b\00/\00s\00t\00a\00t\00i\00c\00a\00r\00r\00a\00y\00.\00t\00s")
(data $2 (i32.const 1148) "<")
(data $2.1 (i32.const 1160) "\02\00\00\00(\00\00\00A\00l\00l\00o\00c\00a\00t\00i\00o\00n\00 \00t\00o\00o\00 \00l\00a\00r\00g\00e")
(data $3 (i32.const 1212) "<")
(data $3.1 (i32.const 1224) "\02\00\00\00\1e\00\00\00~\00l\00i\00b\00/\00r\00t\00/\00s\00t\00u\00b\00.\00t\00s")
(export "invert" (func $main/invert))
(export "memory" (memory $0))
(start $~start)
(func $~start
(local $0 i32)
(local $1 i32)
memory.size
local.tee $0
i32.const 16
i32.shl
i32.const 15
i32.add
i32.const -16
i32.and
local.tee $1
i32.const 38172
i32.lt_u
if
local.get $0
i32.const 103707
local.get $1
i32.sub
i32.const -65536
i32.and
i32.const 16
i32.shr_u
local.tee $1
local.get $0
local.get $1
i32.gt_s
select
memory.grow
i32.const 0
i32.lt_s
if
local.get $1
memory.grow
i32.const 0
i32.lt_s
if
unreachable
end
end
end
i32.const 1276
i32.const 36892
i32.store
i32.const 1280
i32.const 0
i32.store
i32.const 1284
i32.const 0
i32.store
i32.const 1288
i32.const 4
i32.store
i32.const 1292
i32.const 36864
i32.store
i32.const 1296
i32.const 0
i32.const 36864
memory.fill
i32.const 1296
global.set $main/m
)
(func $main/invert (param $0 i32) (result f64)
(local $1 i32)
(local $2 i32)
(local $3 i32)
(local $4 f64)
(local $5 i32)
(local $6 i32)
(local $7 f64)
loop $for-loop|0
local.get $0
local.get $6
i32.gt_s
if
local.get $6
i32.const 1
i32.add
local.set $5
i32.const 0
local.set $1
loop $for-loop|00
local.get $1
i32.const 48
i32.lt_s
if
i32.const 0
local.set $2
loop $for-loop|1
local.get $2
i32.const 48
i32.lt_s
if
global.get $main/m
local.get $1
i32.const 96
i32.mul
local.tee $3
local.get $2
i32.add
i32.const 3
i32.shl
i32.add
local.get $5
i32.const 1664525
i32.mul
i32.const 1013904223
i32.add
local.tee $5
i32.const 8
i32.shr_u
f64.convert_i32_u
f64.const 1.1920928955078125e-07
f64.mul
f64.const -1
f64.add
f64.store
global.get $main/m
local.get $2
i32.const 48
i32.add
local.get $3
i32.add
i32.const 3
i32.shl
i32.add
f64.const 1
f64.const 0
local.get $1
local.get $2
i32.eq
select
f64.store
local.get $2
i32.const 1
i32.add
local.set $2
br $for-loop|1
end
end
global.get $main/m
local.get $1
i32.const 96
i32.mul
local.get $1
i32.add
i32.const 3
i32.shl
i32.add
local.tee $2
local.get $2
f64.load
f64.const 48
f64.add
f64.store
local.get $1
i32.const 1
i32.add
local.set $1
br $for-loop|00
end
end
i32.const 0
local.set $2
loop $for-loop|11
local.get $2
i32.const 48
i32.lt_s
if
local.get $2
local.tee $1
i32.const 1
i32.add
local.set $5
loop $for-loop|2
local.get $5
i32.const 48
i32.lt_s
if
local.get $5
local.get $1
global.get $main/m
local.get $5
i32.const 96
i32.mul
local.get $2
i32.add
i32.const 3
i32.shl
i32.add
f64.load
f64.abs
global.get $main/m
local.get $1
i32.const 96
i32.mul
local.get $2
i32.add
i32.const 3
i32.shl
i32.add
f64.load
f64.abs
f64.gt
select
local.set $1
local.get $5
i32.const 1
i32.add
local.set $5
br $for-loop|2
end
end
local.get $1
local.get $2
i32.ne
if
i32.const 0
local.set $5
loop $for-loop|3
local.get $5
i32.const 96
i32.lt_s
if
global.get $main/m
local.get $2
i32.const 96
i32.mul
local.get $5
i32.add
i32.const 3
i32.shl
i32.add
local.tee $3
f64.load
local.set $4
local.get $3
global.get $main/m
local.get $1
i32.const 96
i32.mul
local.get $5
i32.add
i32.const 3
i32.shl
i32.add
local.tee $3
f64.load
f64.store
local.get $3
local.get $4
f64.store
local.get $5
i32.const 1
i32.add
local.set $5
br $for-loop|3
end
end
end
global.get $main/m
local.get $2
i32.const 96
i32.mul
local.get $2
i32.add
i32.const 3
i32.shl
i32.add
f64.load
local.set $4
i32.const 0
local.set $1
loop $for-loop|4
local.get $1
i32.const 96
i32.lt_s
if
global.get $main/m
local.get $2
i32.const 96
i32.mul
local.get $1
i32.add
i32.const 3
i32.shl
i32.add
local.tee $3
local.get $3
f64.load
local.get $4
f64.div
f64.store
local.get $1
i32.const 1
i32.add
local.set $1
br $for-loop|4
end
end
i32.const 0
local.set $1
loop $for-loop|5
local.get $1
i32.const 48
i32.lt_s
if
block $for-continue|5
local.get $1
local.get $2
i32.eq
br_if $for-continue|5
global.get $main/m
local.get $1
i32.const 96
i32.mul
local.get $2
i32.add
i32.const 3
i32.shl
i32.add
f64.load
local.tee $4
f64.const 0
f64.eq
br_if $for-continue|5
i32.const 0
local.set $5
loop $for-loop|6
local.get $5
i32.const 96
i32.lt_s
if
global.get $main/m
local.get $1
i32.const 96
i32.mul
local.get $5
i32.add
i32.const 3
i32.shl
i32.add
local.tee $3
local.get $3
f64.load
local.get $4
global.get $main/m
local.get $2
i32.const 96
i32.mul
local.get $5
i32.add
i32.const 3
i32.shl
i32.add
f64.load
f64.mul
f64.sub
f64.store
local.get $5
i32.const 1
i32.add
local.set $5
br $for-loop|6
end
end
end
local.get $1
i32.const 1
i32.add
local.set $1
br $for-loop|5
end
end
local.get $2
i32.const 1
i32.add
local.set $2
br $for-loop|11
end
end
i32.const 0
local.set $1
loop $for-loop|7
local.get $1
i32.const 48
i32.lt_s
if
local.get $7
global.get $main/m
local.get $1
i32.const 48
i32.add
local.get $1
i32.const 96
i32.mul
i32.add
i32.const 3
i32.shl
i32.add
f64.load
f64.add
local.set $7
local.get $1
i32.const 1
i32.add
local.set $1
br $for-loop|7
end
end
local.get $6
i32.const 1
i32.add
local.set $6
br $for-loop|0
end
end
local.get $7
)
)