UNPKG

rlab

Version:

Javascript scientific library like R

262 lines (241 loc) 7 kB
var R, V, A, N; module.exports = R = A = N = require("./algebra"); R.V = V = {} // ============= Array Operation ========================= V.recursiveDim = function(a,d) { // dimension by recursion if (R.isArray(a)) { d.push(a.length) V.recursiveDim(a[0],d); } } R.dim = V.dim = function(a) { var d=[]; V.recursiveDim(a,d); return d; } V.recursiveRepeat = function(dim, i, v) { if (i===dim.length) { return R.isFunction(v)?v():v; } else { var n = dim[i], a = new Array(n); for (var k=0; k<n; k++) { a[k] = V.recursiveRepeat(dim, i+1, v); } return a; } } V.repeat = function(dim, value=0) { return V.recursiveRepeat(dim, 0, value); } R.newV = V.newV = R.fill = V.fill = function(n, value=0) { return V.repeat([n], value); } V.random = function(dim, a=0, b=1) { return V.repeat(dim, ()=>R.random(a,b)); } R.randomV = V.randomV = function(n, a, b) { return V.random([n], a, b) } R.samples = V.samples = function(n, a) { return V.map1(new Array(n), ()=>R.sample(a)) } V.extend=function(a, size) { var v = a.slice(); for (var i=a.length; i<size; i++) { v.push(0); } return v; } var cadd = A.ComplexField.add, cmul=A.ComplexField.mul; R.vdot = V.vdot = function(x,y,isComplex=false) { var sum = 0, len = x.length; for (var i=0; i<len; i++) { if (!isComplex) sum += x[i]*y[i]; // 速度較快 else sum = cadd(sum, cmul(x[i], y[i])); // 速度稍慢(不使用多型,否則會很慢) } return sum; } R.vadd = V.vadd = function(a,b) { var len=a.length, r=new Array(len); for (var i=0; i<len; i++) r[i] = a[i]+b[i]; return r; } R.vsub = V.vsub = function(a,b) { var len=a.length, r=new Array(len); for (var i=0; i<len; i++) r[i] = a[i]-b[i]; return r; } R.vmul = V.vmul = function(a,b) { var len=a.length, r=new Array(len); for (var i=0; i<len; i++) r[i] = a[i]*b[i]; return r; } R.vdiv = V.vdiv = function(a,b) { var len=a.length, r=new Array(len); for (var i=0; i<len; i++) r[i] = a[i]/b[i]; return r; } // ================== Map Reduce ========================= var map1 = R.map1 = V.map1 = function(a,f) { if (a instanceof Array) { var fa = new Array(a.length); for (var i=0; i<a.length; i++) { fa[i]=map1(a[i], f); } return fa; } else { return f(a); } } var map2 = R.map2 = V.map2 = function(a,b,f) { if (a instanceof Array) { var fa = new Array(a.length); var isArrayB = (b instanceof Array); for (var i=0; i<a.length; i++) { var bi = isArrayB?b[i]:b; fa[i] = map2(a[i], bi, f); } return fa; } else { return f(a, b); } } var reduce = R.reduce = V.reduce = function(a,f,init) { var result=init; if (a instanceof Array) { for (var i in a) { result = f(result, V.reduce(a[i], f, init)); } } else { result = f(result, a); } return result; } // +-*/%^ V.add = function(a,b) { return map2(a,b,(x,y)=>x+y) } V.sub = function(a,b) { return map2(a,b,(x,y)=>x-y) } V.mul = function(a,b) { return map2(a,b,(x,y)=>x*y) } V.div = function(a,b) { return map2(a,b,(x,y)=>x/y) } V.mod = function(a,b) { return map2(a,b,(x,y)=>x%y) } V.power= function(a,b) { return map2(a,b, (x,y)=>Math.pow(x,y)) } V.neg = function(a) { return map1(a,(x)=>-x) } V.inv = function(a) { return map1(a,(x)=>1/x) } // logical V.not = function(a) { return map1(a,(x)=>!x) } V.and = function(a,b) { return map2(a,(x)=>x&&y) } V.or = function(a,b) { return map2(a,(x)=>x||y) } // V.xor=function(x,y) { return x^y } V.bnot = function(x) { return map2(a,(x)=>~x)} V.band = function(a,b) { return map2(a,(x,y)=>x&y) } V.bor = function(a,b) { return map2(a,(x,y)=>x|y) } V.bxor = function(a,b) { return map2(a,(x,y)=>x^y) } V.lshift=function(a,b) { return map2(a,b,(x)=>x << b) } V.rshift=function(a,b) { return map2(a,b,(x)=>x >> b) } // compare V.eq = function(a,b) { return map2(a,b,(x)=>x===y) } V.neq = function(a,b) { return map2(a,b,(x)=>x!==y) } V.geq = function(a,b) { return map2(a,b,(x)=>x>=y) } V.leq = function(a,b) { return map2(a,b,(x)=>x<=y) } V.gt = function(a,b) { return map2(a,b,(x)=>x>y) } V.lt = function(a,b) { return map2(a,b,(x)=>x<y) } V.near = function(a,b) { return a.sub(b).abs().sum()<0.001 } // number function V.sqrt = function(a) { return map1(a,Math.sqrt) } V.log = function(a) { return map1(a,Math.log) } V.exp = function(a) { return map1(a,Math.exp) } V.abs = function(a) { return map1(a,Math.abs) } V.sin = function(a) { return map1(a,Math.sin) } V.cos = function(a) { return map1(a,Math.cos) } V.tan = function(a) { return map1(a,Math.tan) } V.asin = function(a) { return map1(a,Math.asin) } V.acos = function(a) { return map1(a,Math.acos) } V.atan = function(a) { return map1(a,Math.atan) } V.atan2= function(a) { return map1(a,Math.atan2) } V.ceil = function(a) { return map1(a,Math.ceil) } V.floor= function(a) { return map1(a,Math.floor) } V.round= function(a) { return map1(a,Math.round) } V.sin = function(a) { return map1(a,Math.sin) } V.sqrt = function(a) { return map1(a,Math.sqrt) } V.max = (a)=>V.reduce(a,Math.max,-Number.MAX_VALUE); V.min = (a)=>V.reduce(a,Math.min,Number.MAX_VALUE); V.sum = (a)=>V.reduce(a,(x,y)=>x+y,0); V.product = (a)=>V.reduce(a,(x,y)=>x*y,1); V.mean=function(a) { return a.sum().div(a.length); } V.norm=function(a) { return a.map1((x)=>x*x).sum().sqrt(); } V.toComplex = function(a) { return map1(a, (x)=>N.Complex.toComplex(x)) } // Operation (Object version) V.oadd = function(a,b) { return map2(a,b,(x,y)=>x.add(y)) } V.osub = function(a,b) { return map2(a,b,(x,y)=>x.sub(y)) } V.omul = function(a,b) { return map2(a,b,(x,y)=>x.mul(y)) } V.odiv = function(a,b) { return map2(a,b,(x,y)=>x.div(y)) } // R.omod = function(a,b) { return map2(a,b,(x,y)=>x.mod(y)) } V.osqrt= function(a) { return map1(a, (x)=>x.sqrt()) } V.osum = function(a) { return V.reduce(a, function(x,y) { return x.add(y) } ,0) } V.oproduct = function(a) { return V.reduce(a,(x,y)=>x.mul(y),1) } R.mixThisMap(Array.prototype, V, { dim:"dim", sum:"sum", near:'near', max:"max", min:"min", sum:"sum", product:"product", norm:"norm", mean:"mean", map1:"map1", map2:"map2", // fast vector op vdot:"vdot", vadd:"vadd", vsub:"vsub", vmul:"vmul", vdiv:"vdiv", // slow map version // +-*/% add:"add", sub:"sub", mul:"mul", div:"div", mod:"mod", neg:"neg", and:"and", or:"or", xor:"xor", not:"not", // bits operation bnot:"bnot", band:"band", bor:"bor", bxor:"bxor", // function power:"power", // "dot", 和矩陣相衝 sqrt:"sqrt", log:"log", exp:"exp", abs:"abs", sin:"sin", cos:"cos", tan:"tan", asin:"asin", acos:"acos", atan:"atan", ceil:"ceil", floor:"floor", round:"round", toComplex:"toComplex", // Object version oadd:"oadd", osub:"osub", omul:"omul", odiv:"odiv", osqrt:"osqrt", osum:"osum", oproduct:"oproduct", });