output = {
var Dualgebra = (x)=>Algebra({
basis : [...Array(x+1)].map((a,i)=>i?'e0'+i:'1'), metric : [1,...Array(x)],
Cayley : [...Array(x+1)].map((a,i)=>[...Array(x+1)].map((y,j)=>i*j==0?((i+j)?'e0'+(i+j):'1'):'0'))
});
var D3 = Dualgebra(3), R3 = Algebra(3);
var d3 = (a,b,c,d)=>(a instanceof Array)?a.map(x=>d3(x)):(a instanceof D3)?a:new D3([a||0,b||0,c||0,d||0]);
var translate = (x)=>{ var F=D3.inline(R3.prototype[x]); return (a,b)=>F.call(a,b); },
[GP,ADD,SUB,SCALE] = ["Mul","Add","Sub","Scale"].map(x=>translate(x));
var EXP = (X)=>{
var R=d3([1,...Array(X.length-1)]), M, y=1, i=1;
while (i<25) { R=ADD(R, SCALE(M||X, 1/y)); M=GP(M||X,X); y=y*(++i); }
return R;
};
var r = (x)=>(Math.random()*2-1)*(x||1),
VLEN = R=>R[1].Mul(R[1]).Add(R[2].Mul(R[2])).Add(R[3].Mul(R[3])),
ROT = (R,x)=>GP(GP(EXP(SCALE(R,-0.5)),x),EXP(SCALE(R,0.5))),
COST = (G,Pa,Pb)=>Pa.reduce((C,Pa,x)=>C.Add(VLEN(SUB(ROT(G,Pa),Pb[x]))),d3()).Scale(1/Pa.length);
var points_a = [...Array(30)].map(x=>[0,r(),r(),r(),0,0,0,0]),
bv = d3([0,0,0,0,r(),r(),r(),0]),
points_b = points_a.map(x=>ADD(ROT(bv,x),[0,r(.01),r(.01),r(.01),0,0,0,0]).map(x=>x[0])),
guess = d3([0,0,0,0,d3(0,1),d3(0,0,1),d3(0,0,0,1),0]);
var start = performance.now();
for (var alpha=1,i=0; i<100; i++) {
var c = COST(guess,points_a,points_b); if (c[0]<5E-4) break;
guess = ADD(guess,[0,0,0,0,-c[1]*alpha,-c[2]*alpha,-c[3]*alpha,0])
}
var stop = performance.now();
var graph = Algebra(3,0,1).inline((pa,pb,i,guess)=>{
var conv = x=>x.map(x=>!(x[1][0]*1e1+(x[2][0])*1e2+x[3][0]*1e3+1e0));
var trail = (bv,x,n=12)=>[...Array(n).keys()].map(i=>Math.E**(bv*(i/(n-1)))>>>x).map((x,i,a)=>[x,a[i-1]||x]).slice(1);
pa = conv(pa);
var trails = []; pa.forEach(pa=>trails.push(...trail(guess*[-.5e12,-.5e13,-.5e23], pa)));
var camera = Math.E**1e23,f=0, items=[...pa,0x88FF0000,...conv(pb),0x880000FF];
return this.graph(()=>{
camera.set(Math.E**(2e03)*Math.E**(Math.sin(performance.now()/5000)*1e13));
var anim = Math.E**((Math.sin(performance.now()/234)*0.5+.5)*( guess*[-.5e12,-.5e13,-.5e23] ));
return [0xAAAAFF,...trails,0x0000FF,guess*[1e12,1e13,1e23],0,...items,...anim>>>pa] ;
},{grid:1,camera,animate:1,gl:1,width:'100%',height:'400px'});
})(d3(points_a),d3(points_b),i,guess.map(x=>x[0]).slice(4,7));
var text = md`
* Nr of iterations : ${i}
* Nr of points : ${points_a.length}
* Time : ${(stop-start)/1000}
* Final Error : ${c[0]}
* Initial guess : 0.0,0.0,0.0
* Final estimate : ${guess[4][0].toFixed(4)},${guess[5][0].toFixed(4)},${guess[6][0].toFixed(4)}
* Ground truth : ${bv[4][0].toFixed(4)},${bv[5][0].toFixed(4)},${bv[6][0].toFixed(4)}
* GT Error (noise) : ${COST(bv,points_a,points_b)[0]}`;
return {graph,text}
}