j6
Version:
Javascript scientific library (like R, NumPy, Matlab)
1,889 lines (1,625 loc) • 857 kB
JavaScript
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
module.exports = function (j6) {
// module : Field & Group Theory
// 注意: 箭頭函數會自動將 this 變數綁定到其定義時所在的物件,因此以下很多地方不能用箭頭函數。
// 參考: https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Functions/Arrow_functions
var eq = j6.eq, extend=j6.extend;
// ========== Group & Field Property ================
// ref:https://en.wikipedia.org/wiki/Group_(mathematics)
// 封閉性:For all a, b in G, a • b, is also in G
j6.closability=function(set, op, a, b) { return set.has(op(a,b)) }
// 結合性:For all a, b and c in G, (a • b) • c = a • (b • c).
j6.associativity=function(set, op, a, b, c) {
return eq(op(op(a,b),c), op(a,op(b,c)))
}
// 單位元素:Identity element
j6.identity=function(set, op, e, a) { return eq(op(e,a),a) }
// 反元素:Inverse element
j6.inversability=function(e, inv, a) {
return eq(op(a,inv(a)),e);
}
// 交換性:
j6.commutative=function(op,a,b) {
return eq(op(a,b),op(b,a));
}
// 左分配律:
j6.ldistribute=function(add, mul, a,b,c) {
return eq(mul(a, add(b,c)), add(mul(a,b), mul(a,c)));
}
// 右分配律:
j6.rdistribute=function(add, mul, a,b,c) {
return j6.ldistribute(b,c,a);
}
// 封閉性
j6.isClose=function(g) {
var a=g.random(), b=g.random();
return j6.closability(g, a, b);
}
// 結合性
j6.isAssociate=function(g) {
var a=g.random(), b=g.random(), c=g.random();
return j6.associativity(g, g.op, a, b, c);
}
// 單位元素
j6.isIdentify=function(g) {
var a=g.random(), b=g.random(), c=g.random();
return j6.associativity(g, g.op, a, b, c);
}
// 反元素
j6.isInversable=function(g) {
var a=g.random(), b=g.random(), c=g.random();
return j6.associativity(g, g.op, a, b, c);
}
// 左分配律
j6.isLeftDistribute=function(f, m, add, mul) {
var a=f.random(), b=g.random(), c=g.random();
return j6.ldistribute(add, mul, a, b, c);
}
// 右分配律
j6.isRightDistribute=function(f, m, add, mul) {
var a=f.random(), b=f.random(), c=g.random();
return j6.rdistribute(add, mul, a, b, c);
}
// 原群
j6.isMagma = function(g) { return j6.isClose(g) }
// 半群
j6.isSemiGroup = function(g) { return j6.isClose(g) && j6.isAssociate(g) }
// 么半群
j6.isMonoid = function(g) { return j6.isSemiGroup(g) && j6.isIdentify(g) }
// 群
j6.isGroup = function(g) { return j6.isMonoid(g) && j6.isInversable(g) }
// 交換群
j6.isAbelGroup = function(g) { return j6.isGroup(g) && j6.isCommutable(g) }
// 擬群
j6.isQuasiGroup = function(g) { return j6.isClose(g) && j6.isInversable(g) }
// 環群
j6.isLoop = function(g) { return j6.isQuasiGroup(g) && j6.isIdentify(g) }
// 環 : 沒有乘法反元素的體。
j6.isRing = function(f) {
return isAbelGroup(f.addSet) && isSemiGroup(f.mulSet);
}
// 體 : 具有加減乘除結構的集合
j6.isField = function(f) {
return isAbelGroup(f.addSet) && isAbelGroup(f.mulSet);
}
// 模 : 向量的抽象化
j6.isModule = function(r,m) {
return j6.isRing(r)&&j6.isAbelGroup(m);
// &&j6.isLeftDistribute(r.madd, m.add);
}
// ========== Group =================
j6.SemiGroup={
power:function(x,n) {
var p=this.e;
for (var i=0;i<n;i++) {
p=this.op(p,x);
}
return p;
},
leftCoset:function(g, H) {
var set = new Set();
for (var i in H)
set.add(this.op(g,H[i]));
return set;
},
rightCoset:function(H, g) {
var set = new Set();
for (var i in H)
set.add(this.op(g,H[i]));
return set;
},
} // 半群
j6.Monoid={} // 么半群
extend(j6.Monoid, j6.SemiGroup)
j6.Group={
// inv:function(x) { return x.inv() },
}
extend(j6.Group, j6.Monoid);
j6.AbelGroup = {} // 交換群
extend(j6.AbelGroup, j6.Group);
// PermutationGroup
j6.PermutationGroup={
op:function(x,y) {
var z = [];
for (var i in x)
z[i] = y[x[i]];
return z;
},
inv:function(x) {
var nx = [];
for (var i in x) {
nx[x[i]] = i;
}
return nx;
},
}
extend(j6.PermutationGroup, j6.Group);
// 循環群 Cyclic Group : a group that is generated by a single element (g)
j6.CyclicGroup={
G:[], // g:g,
op:function(x,y) {},
inv:function(x) {},
create(g) {
var t = e;
for (var i=0; !t.eq(e); i++) {
G[i]=t;
t=op(g,G[i]);
}
}
}
extend(j6.CyclicGroup, j6.Group);
// NormalSubGroup : 正規子群
j6.isNormalSubGroup=function(G,H,g,h) {
return H.has(G.op(G.op(g,h), G.inv(g)));
}
// 商群 Quotent Group : aggregating similar elements of a larger group using an equivalence relation that preserves the group structure
j6.QuotentGroup={
eq:function(x,y) {},
op:function(x,y) {},
inv:function(x) {},
}
extend(j6.QuotentGroup, j6.Group);
// Normal SubGroup : gH = Hg
// https://en.wikipedia.org/wiki/Normal_subgroup
j6.NormalSubGroup={
op:function(x,y) {},
inv:function(x) {},
}
extend(j6.NormalSubGroup, j6.Group);
// 群同構第一定理: 給定 GG和 G ′ 兩個群,和 f : G → G ′ 群同態。則 Ker f 是一個 G 的正規子群。
// 群同構第二定理:給定群 G 、其正規子群 j6、其子群 H,則 j6 ∩ H 是 H 的正規子群,且我們有群同構如下: H / ( H ∩ j6 ) ≃ H j6 / j6
// 群同構第三定理: 給定群 G, j6 和 M,M 為 G 的正規子群,滿足 M 包含於 j6 ,則 j6 / M 是 G / M 的正規子群,且有如下的群同構: ( G / M ) / ( j6 / M ) ≃ G / j6 .
// ========== Field =================
j6.Ring = { // Ring (環) : 可能沒有乘法單位元素和反元素的 Field
neg:function(x) { return this.addSet.inv(x) },
add:function(x,y) { return this.addSet.op(x,y) },
sub:function(x,y) { return this.addSet.op(x, this.addSet.inv(y)) },
mul:function(x,y) { return this.mulSet.op(x,y) },
power:function(x,n) { return this.mulSet.power(x,n) },
init:function(addSet, mulSet) {
this.addSet = addSet;
this.mulSet = mulSet;
this.zero = addSet.e;
},
// Ideal (理想): 子環,且 i·r ∈ I (左理想), r·i ∈ I (右理想)
ideal:function(i) {}, // https://en.wikipedia.org/wiki/Ideal_(ring_theory)
}
// (F,+,*) : (F,+), (F-0,*) 均為交換群。
j6.Field = {
div:function(x,y) { return this.mulSet.op(x, this.mulSet.inv(y)) },
inv:function(x) { return this.mulSet.inv(x) },
init:function(addSet, mulSet) {
j6.Ring.init.call(this, addSet, mulSet);
this.one = mulSet.e;
},
}
extend(j6.Field, j6.Ring);
// https://zh-classical.wikipedia.org/wiki/%E6%A8%A1_(%E4%BB%A3%E6%95%B8)
j6.Module = j6.Field;// Module(模) : (j6 +) is Ring, (j6 × M → M)
// ========== Float Field =================
j6.FloatAddGroup={
e:0,
op:function(x,y) { return x+y },
inv:function(x) { return -x},
}
extend(j6.FloatAddGroup, j6.AbelGroup, j6.Float);
j6.FloatMulGroup={
e:1,
op:function(x,y) { return x*y },
inv:function(x) { return 1/x},
}
extend(j6.FloatMulGroup, j6.AbelGroup, j6.Float);
j6.FloatField=extend({}, j6.Field, j6.Float);
j6.FloatField.init(j6.FloatAddGroup, j6.FloatMulGroup);
// ========== Finite Field =================
j6.FiniteAddGroup={
e:0,
op:function(x,y) { return (x+y)%this.n },
inv:function(x) { return (this.n-x) }
}
extend(j6.FiniteAddGroup, j6.AbelGroup);
j6.FiniteMulGroup={
e:1,
op:function(x,y) { return (x*y)%this.n },
inv:function(x) { return this.invMap[x] },
setOrder:function(n) {
this.n = n;
let invMap = new Map();
for (var x=1; x<n; x++) {
var y = this.op(x,x);
invMap.set(x,y);
}
this.invMap = invMap;
}
}
extend(j6.FiniteMulGroup, j6.AbelGroup);
j6.FiniteField=extend({}, j6.Field);
j6.FiniteField.create=function(n) {
var finiteField = extend(j6.Finite(n), j6.FiniteField);
var addSet = extend(j6.Finite(n), {n:n}, j6.FiniteAddGroup);
var mulSet = extend(j6.Finite(n), {n:n}, j6.FiniteMulGroup);
finiteField.init(addSet, mulSet);
mulSet.setOrder(n);
return finiteField;
}
class MathObj {
constructor() {}
str() { return this.toString() }
}
j6.MathObj = MathObj;
// =========== Field Object ==============
class FieldObj extends MathObj {
constructor(field) {
super();
this.field = field;
var p = Object.getPrototypeOf(this);
p.zero = field.zero;
p.one = field.one;
}
add(y) { return this.field.add(this,y) }
mul(y) { return this.field.mul(this,y) }
neg() { return this.field.neg(this) }
inv() { return this.field.inv(this) }
div(y) { return this.field.div(this,y) }
sub(y) { return this.field.sub(this,y) }
power(n) { return this.field.power(this,n) }
isZero(x) { return this.field.isZero(this) }
isOne(x) { return this.field.isOne(this) }
eq(y) { return this.field.eq(this, y) }
neq(y) { return this.field.neq(this, y) }
mod(y) { return this.field.mod(this, y) }
}
j6.FieldObj = FieldObj;
// =========== Complex Field ==============
j6.ComplexField=extend({}, j6.Field);
class Complex extends FieldObj {
constructor(a,b) {
super(j6.ComplexField);
this.a = a; this.b = b;
}
conj() { return new Complex(this.a, -1*this.b); }
str() {
var op = (this.b<0)?'':'+';
return j6.nstr(this.a)+op+j6.nstr(this.b)+'i';
}
toString() { return this.str() }
toPolar() {
var a=this.a, b=this.b, r=Math.sqrt(a*a+b*b);
var theta = Math.acos(a/r);
return {r:r, theta:theta}
}
power(k) {
var p = this.toPolar();
return Complex.polarToComplex(Math.pow(p.r,k), k*p.theta);
}
sqrt() {
return this.power(1/2);
}
static toComplex(o) {
if (j6.isFloat(o))
return new Complex(o, 0);
else if (o instanceof Complex)
return o;
console.log('o=', o);
throw Error('toComplex fail');
}
static polarToComplex(r,theta) {
var a=r*Math.cos(theta), b=r*Math.sin(theta);
return new Complex(a, b);
}
static parse(s) {
var m = s.match(/^([^\+]*)(\+(.*))?$/);
var a = parseFloat(m[1]);
var b = typeof m[3]==='undefined'?1:parseFloat(m[3]);
return new Complex(a, b)
}
}
j6.Complex = Complex;
j6.polarToComplex = Complex.polarToComplex;
j6.toComplex = Complex.toComplex;
var C = (a,b)=>new Complex(a,b);
var enumComplex=[C(1,0),C(0,1),C(0,0),C(2,3),C(-5,4),C(-10,-7)];
j6.ComplexSet=new j6.create(enumComplex);
j6.ComplexSet.has = (a)=>a instanceof Complex;
j6.ComplexAddGroup={
e:new Complex(0,0),
op:function(x,y) {
x = Complex.toComplex(x), y=Complex.toComplex(y);
return new Complex(x.a+y.a, x.b+y.b)
},
inv:function(x) {
x = Complex.toComplex(x);
return new Complex(-x.a, -x.b)
}
}
extend(j6.ComplexAddGroup, j6.AbelGroup, j6.ComplexSet);
j6.ComplexMulGroup={
e:new Complex(1,0),
op:function(x,y) {
x = Complex.toComplex(x), y=Complex.toComplex(y);
return new Complex(x.a*y.a-x.b*y.b, x.a*y.b+x.b*y.a);
},
inv:function(x) {
x = Complex.toComplex(x);
var a=x.a,b=x.b, r=a*a+b*b;
return new Complex(a/r, -b/r);
}
}
extend(j6.ComplexMulGroup, j6.AbelGroup, j6.ComplexSet);
extend(j6.ComplexField, j6.ComplexSet);
j6.ComplexField.init(j6.ComplexAddGroup, j6.ComplexMulGroup);
// =========== Ratio Field ==============
j6.RatioField=extend({}, j6.Field);
class Ratio extends FieldObj {
constructor(a,b) {
super(j6.RatioField);
this.a = a; this.b = b;
}
reduce() {
var a = this.a, b=this.b;
var c = j6.gcd(a, b);
return new Ratio(a/c, b/c);
}
toString() { return this.a+'/'+this.b; }
static parse(s) {
var m = s.match(/^(\d+)(\/(\d+))?$/);
var a = parseInt(m[1]);
var b = typeof m[3]==='undefined'?1:parseInt(m[3]);
return new Ratio(a, b)
}
}
j6.Ratio = Ratio;
j6.RatioAddGroup={
e:new Ratio(0,1),
op:function(x,y) { return new Ratio(x.a*y.b+x.b*y.a, x.b*y.b) },
inv:function(x) { return new Ratio(-x.a, x.b); },
}
extend(j6.RatioAddGroup, j6.AbelGroup);
j6.RatioMulGroup={
e:new Ratio(1,1),
op:function(x,y) { return new Ratio(x.a*y.a, x.b*y.b) },
inv:function(x) { return new Ratio(x.b, x.a) },
}
extend(j6.RatioMulGroup, j6.AbelGroup);
j6.RatioField.init(j6.RatioAddGroup, j6.RatioMulGroup);
// Function
j6.isField = j6.isField=function(x) {
return j6.isBool(x) || j6.isNumber(x) || x instanceof j6.FieldObj;
}
j6.parse = j6.parse = function(s) {
if (s.indexOf(';')>=0) {
var m = split(s, ";"), matrix;
for (var i=0; i<m.length; i++) {
matrix[i] = j6.parse(m[i]);
}
return matrix;
} if (s.indexOf(',')>=0) {
var a = split(s, ","), array;
for (var i=0; i<a.length; i++) {
array[i] = j6.parse(a[i]);
}
return array;
}
else if (s.indexOf('/')>=0)
return j6.Ratio.parse(s);
else if (s.indexOf('i')>=0)
return j6.Complex.parse(s);
else {
return parseFloat(s);
}
}
j6.op = function(op,x,y) {
if (y instanceof j6.Complex) {
x = x.toComplex();
switch (op) {
case 'add':return x.add(y);
case 'sub':return x.sub(y);
case 'mul':return x.mul(y);
case 'div':return x.div(y);
case 'sqrt':return x.sqrt();
case 'power':return x.power(y);
}
} else if (y instanceof Array) {
switch (op) {
case 'add':return y.add(x);
case 'sub':return y.sub(x).neg();
case 'mul':return y.mul(x);
case 'div':return y.div(x).inv();
}
} else {
switch (op) {
case 'add':return x+y;
case 'sub':return x-y;
case 'mul':return x*y;
case 'div':return x/y;
case 'sqrt':return (x>=0)?Math.sqrt(x):x.toComplex().sqrt(x);
case 'power':return (y>=0)?Math.pow(x,y):x.toComplex().power(x,y);
}
}
throw Error('j6.op:invalid '+op);
}
j6.neg=function(x) { return -x }
j6.inv=function(x) { return 1/x }
j6.add=function(x,y) { return j6.op('add', x, y) }
j6.sub=function(x,y) { return j6.op('sub', x, y) }
j6.mul=function(x,y) { return j6.op('mul', x, y) }
j6.div=function(x,y) { return j6.op('div', x, y) }
j6.mod=function(x,y) { return x%y }
j6.sqrt=function(x) { return j6.op('sqrt', x) }
j6.power=function(x,y) { return j6.op('power', x, y) }
j6.eval=function(f,x) { return f(x) }
// =========== Function Field ==============
j6.FunctionField = extend({}, j6.Field)
j6.FunctionAddGroup = {
e: function (x) { return 0 },
op: function (x, y) { return j6.add(x, y) },
inv: function (x) { return j6.neg(x) }
}
extend(j6.FunctionAddGroup, j6.AbelGroup)
j6.FunctionMulGroup = {
e: function (x) { return f(x) },
op: function (x, y) { return j6.sub(x, y) },
inv: function (x) { return j6.inv(x) }
}
extend(j6.FunctionMulGroup, j6.AbelGroup)
j6.FunctionField.init(j6.FunctionAddGroup, j6.FunctionMulGroup)
// =========== Polynomial Ring ==============
j6.PolynomialRing = extend({}, j6.Field)
class Polynomial extends j6.FieldObj {
constructor (c) {
super(j6.PolynomialRing)
this.c = c // sum(ci x^i)
}
eval (x) {
var c = this.c
var i = c.length - 1
var sum = c[i]
for (i--; i >= 0; i--) {
sum = c[i].add(x.mul(sum))
}
return sum
}
size () { return this.c.length }
toString () {
var s = []
var c = this.c
for (var i = c.length - 1; i >= 0; i--) {
s.push(c[i] + 'x^' + i)
}
return s.join('+')
}
root () {
var p = this.normalize() // 正規化
var c = p.c.toComplex()
console.log('c=%s', c)
switch (this.size()) {
case 2:return p.c[0].neg()
case 3:return p.root2(c[1], c[0])
case 4:return p.root3(c[2], c[1], c[0])
default:throw Error('root() fail')
}
}
root2 (b, c) { // x^2 + bx + c = 0
var d = b.mul(b).sub(c.mul(j6.parse('4+0i'))).sqrt()
return [b.neg().add(d), b.neg().sub(d)]
}
root3 (a, b, c) { // x^3+ax^2+bx+c=0
var q = a.power(3).mul(2 / 27).sub(a.mul(b).div(3).add(c)).div(2) // q=((2*a*a*a/27)-(a*b/3)+c)/2;
var p = b.sub(a.power(2).div(3)).div(3) // p=(b-a*a/3)/3;
var D = p.power(3).add(q.power(2)) // D=p*p*p+q*q;
var Dsqrt = D.sqrt()
var _q = q.neg()
console.log('Dsqrt=%s _q=%s', Dsqrt, _q)
var uP = _q.add(Dsqrt).power(1 / 3) // u+ = (-q+sqrt(D))^1/3
var uM = _q.sub(Dsqrt).power(1 / 3) // u- = (-q-sqrt(D))^1/3
console.log('q=%s p=%s D=%s u+=%s u-=%s', q, p, D, u_p, u_m)
var rhoP = j6.parse('-1+3i').div(2) // rho+ = (-1+3i)/2
var rhoM = j6.parse('-1-3i').div(2) // rho- = (-1-3i)/2
console.log('rho+ = %s rho- = %s', rhoP, rhoM)
var y1 = uP.add(uM) // y1 = (u+) + (u-)
var y2 = rhoP.mul(uP).add(rhoM.mul(uM)) // y2=(rho+*u+)+(rho-*u-)
var y3 = rhoM.mul(uP).add(rhoP.mul(uM)) // y3=(rho-*u+)+(rho+*u-)
return [y1, y2, y3]
}
normalize () {
var a = this.c[this.size() - 1]
var nc = this.c.div(a)
return new Polynomial(nc)
}
}
j6.Polynomial = Polynomial
j6.PolynomialAddGroup = {
e: new Polynomial([0]), // 到底應該設幾個?
op: function (x, y) {
var size = Math.max(x.size(), y.size())
var a = j6.extend(x.c, size)
var b = j6.extend(y.c, size)
var c = a.add(b)
return new Polynomial(c)
},
inv: function (x) {
var c = x.c.neg()
return new Polynomial(c)
}
}
extend(j6.PolynomialAddGroup, j6.Group)
j6.PolynomialMulSemiGroup = {
e: new Polynomial([1]),
op: function (x, y) {
var c = []
for (var xi = 0; xi < x.c.length; xi++) {
for (var yi = 0; yi < y.c.length; yi++) {
var cxy = (typeof c[xi + yi] === 'undefined') ? 0 : c[xi + yi]
c[xi + yi] = cxy + (x.c[xi] * y.c[yi])
}
}
return new Polynomial(c)
},
inv: function (x) { throw Error('PolynomialMulSemiGroup.inv not defined') }
}
extend(j6.PolynomialMulSemiGroup, j6.Group)
j6.PolynomialRing.init(j6.PolynomialAddGroup, j6.PolynomialMulSemiGroup)
}
},{}],2:[function(require,module,exports){
module.exports = function (j6) {
/* eslint-disable no-undef */
j6.cosineSimilarity = function (v1, v2) {
return v1.vdot(v2) / (v1.norm() * v2.norm())
}
j6.euclidDistance = function (v1, v2) { // sqrt((v1-v2)*(v1-v2)T)
let dv = v1.sub(v2)
return Math.sqrt(dv * (dv.tr()))
}
j6.manhattanDistance = function (v1, v2) { // sum(|v1-v2|)
return v1.sub(v2).abs().sum()
}
j6.chebyshevDistance = function (v1, v2) { // max(|v1-v2|)
return v1.sub(v2).abs().max()
}
}
},{}],3:[function(require,module,exports){
module.exports = function (j6) {
j6.logp = function(n) {
return j6.steps(1,n,1).log().sum();
}
// 傳回多項分布的 log 值! log( (n!)/(x1!x2!...xk!) p1^x1 p2^x2 ... pk^xk )
// = [log(n)+...+log(1)]-[log(x1)...]+....+x1*log(p1)+...+xk*log(pk)
j6.xplog = function(x, p) {
var n = x.sum();
var r = j6.logp(n);
for (var i in x) r -= j6.logp(x[i]);
return r + x.dot(p.log());
}
}
},{}],4:[function(require,module,exports){
module.exports = function (j6) {
/* eslint-disable no-undef */
// =========== Function Operation ==============
j6.neg = function (fx) {
return function (v) { return -1 * fx(v) }
}
j6.inv = function (fx) {
return function (v) { return 1 / fx(v) }
}
j6.add = function (fx, fy) {
return function (v) { return fx(v).add(fy(v)) }
}
j6.sub = function (fx, fy) {
return function (v) { return fx(v).sub(fy(v)) }
}
j6.mul = function (fx, fy) {
return function (v) { return fx(v).mul(fy(v)) }
}
j6.div = function (fx, fy) {
return function (v) { return fx(v).div(fy(v)) }
}
j6.compose = function (fx, fy) {
return function (v) { return fx(fy(v)) }
}
j6.eval = function (f, x) { return f(x) }
// f=(x,y)=>x*y+x*x;
// f0=fa(f); f0([x,y]);
j6.fa = function (f) {
return function (x) { return f.apply(null, x) }
}
/*
// ================= Checking Rule =====================
j6.check = j6.assert = function (cond, msg) {
if (cond) {
if (j6.assertMessage) console.log('O:' + msg)
} else {
console.log('X:' + msg)
if (j6.throwError) throw Error('check fail!')
}
}
j6.assertMessage = true
j6.throwError = false
*/
// j6.be = function (msg, cond) { return j6.check(cond, msg) }
// j6.proto = function (o) { return Object.getPrototypeOf(o) }
// relation
j6.eq = function (a, b) {
return (typeof a === typeof b) && a.toString() === b.toString()
}
j6.neq = function (a, b) { return !j6.eq(a, b) }
j6.leq = function (a, b) { return a <= b }
j6.geq = function (a, b) { return a >= b }
j6.lt = function (a, b) { return a < b }
j6.gt = function (a, b) { return a > b }
j6.near = function (a, b) { return Math.abs(a - b) < 0.0001 }
// =========== Integer ====================
j6.isPrime = function (n) {
for (var i = 2; i <= Math.sqrt(n); i++) {
if (n % i === 0) return false
}
return n % 1 === 0
}
j6.gcd = function (a, b) {
if (!b) return a
return j6.gcd(b, a % b)
}
j6.lcm = function (a, b) {
return (a * b) / j6.gcd(a, b)
}
// ========= type checking =================
j6.yes = function (a) { return true }
j6.no = function (a) { return false }
j6.isBool = function (a) {
return typeof a === 'boolean' || a instanceof Boolean
}
j6.isFunction = function (a) {
return typeof a === 'function' || a instanceof Function
}
j6.isString = function (a) {
return typeof a === 'string' || a instanceof String
}
j6.isObject = function (a) {
return typeof a === 'object' || a instanceof Object
}
j6.isArray = function (a) { return a instanceof Array }
j6.isUndefined = function (a) { return typeof a === 'undefined' }
j6.isSet = function (a) { return a instanceof Set }
j6.isFloat = j6.isNumber = function (a) {
return typeof a === 'number' || a instanceof Number
}
j6.isInteger = function (a) { return j6.isFloat(a) && a % 1 === 0 }
j6.isZero = function (a) { return a === 0 }
j6.isPositive = function (a) { return a > 0 }
j6.isNegative = function (a) { return a < 0 }
j6.isEven = function (a) { return (j6.isInteger(a) && a % 2 === 0) }
j6.isOdd = function (a) { return (j6.isInteger(a) && a % 2 === 1) }
}
},{}],5:[function(require,module,exports){
module.exports = function (j6) {
var extend = j6.extend;
// j6 = j6.j6 = j6.Geometry = {}
// 各種 space : https://en.wikipedia.org/wiki/Space_(mathematics)#/media/File:Mathematical_implication_diagram_eng.jpg
// Space = HllbertSpace + BanachSpace + Manifold (流形)
j6.Space = extend({}, j6.Set);
// ============= Topology ====================
// https://en.wikipedia.org/wiki/Topological_space
// p : point
j6.TopologicalSpace={ // 拓撲空間 : a Space with neighbor()
neighbor:function(p1, p2) {}, // TopologicalSpace is a Space with neighbor() function.
coarser:function(T1, T2) {}, // 更粗糙的 (coarser, weaker or smaller) 的拓樸
finer:function(T1, T2) { return !courser(T2,T1) }, // 更細緻的 (finer, stronger or larger) 的拓樸
continuous:function() {}, // if for all x in X and all neighbourhoods N of f(x) there is a neighbourhood M of x such that f(M) is subset of N.
homeomorphism:function() {}, // 同胚: 同胚是拓撲空間範疇中的同構(存在 f 雙射,連續,且 f-1 也連續) (注意和代數的 Homomorphism (同態) 不同,差一個 e)
}
extend(j6.TopologicalSpace, j6.Space);
// Kolmogorov classification T0, T1, T2, ....
// https://en.wikipedia.org/wiki/Separation_axiom
j6.T0 = j6.KolmogorovSpace = {
// every pair of distinct points of X, at least one of them has a neighborhood not containing the other
}
extend(j6.T0, j6.TopologicalSpace);
j6.T1 = j6.FrechetSpace = {}
// 任兩點都可鄰域分離者,為郝斯多夫空間。
j6.T2 = j6.HausdorffSpace = {}
j6.T2Complete = {}
j6.T2p5 = j6.Urysohn = {} // T2?
j6.T3 = j6.RegularSpace = {
// every closed subset C of X and a point p not contained in C admit non-overlapping open neighborhoods
}
j6.T3p5 = j6.TychonoffSpace = {} // T3?
j6.T4 = j6.NormalHausdorff = {}
j6.T5 = j6.CompletelyNormalHausdorff = {}
j6.T6 = j6.PerfectlyNormalHausdorff = {}
// https://en.wikipedia.org/wiki/Discrete_space
j6.DiscreteSpace = {} //
extend(j6.DiscreteSpace, j6.TopologicalSpace);
// 1. d(x,y)>=0, 2. d(x,y)=0 iff x=y 3. d(x,y)=d(y,x) 4. d(x,z)<=d(x,y)+d(y,z)
j6.Metric = {
d:function(x,y) {},
test0:function() {
be(d(x,y)>=0);
be(d(x,x)==0);
be(d(x,y)==d(y,x));
},
test:function() {
test0();
be(d(x,z)<=d(x,y)+d(y,z));
},
}
j6.UltraMetric = {
test:function() {
test0();
be(d(x,z)<=max(d(x,y),d(y,z)));
},
}
extend(j6.UltraMetric, j6.Metric);
// https://en.wikipedia.org/wiki/Metric_space
j6.MetricSpace = { // distances between all members are defined
d:function(p1,p2) {},
test:function() {
be(d(x,y)>=0);
be(d(x,x)===0);
be(d(x,y)===d(y,x));
be(d(x,z)<=d(x,y)+d(y,z));
}
}
j6.CompleteMetricSpace = { // 空間中的任何柯西序列都收斂在該空間之內。
}
extend(j6.CompleteMetricSpace, j6.MetricSpace);
// https://en.wikipedia.org/wiki/Complete_metric_space
j6.CompleteMetricSpace = {
// M is called complete (or a Cauchy space) if every Cauchy sequence of points in M has a limit that is also in M or, alternatively, if every Cauchy sequence in M converges in M.
}
// https://en.wikipedia.org/wiki/Uniform_space
j6.UniformSpace = { // 帶有一致結構的集合,「x 鄰近於a 勝過y 鄰近於b」之類的概念,在均勻空間中是有意義的。
}
j6.Rn = {
} // (j6,j6,....)
// 向量空間: VectorSpace = Rn + Linearity
// V:AbelGroup(交換群), F:Field
// 1. F × V → V,(r,v)→ rv
// 2. r(x+y) = rx+ry
// 3. (r+s)x = rx+sx
// 4. (rs)x = r(sx)
// 5. 1x = x
j6.VectorSpace = j6.LinearSpace = {
add(x,y) { return x.add(y) },
mul(a,x) { return a.mul(x) },
bilinear(b) { // https://en.wikipedia.org/wiki/Bilinear_form
linear((u)=>b(u,w));
linear((w)=>b(u,w));
},
positiveDefinite(b) { }, // 正定
symmetric(b) {}, // 對稱
dualSpace() {}, // https://en.wikipedia.org/wiki/Dual_space
}
extend(j6.VectorSpace, j6.Rn);
j6.FiniteVectorSpace = {} // 有限體向量空間
extend(j6.FiniteVectorSpace, j6.VectorSpace);
j6.NormedVectorSpace={ // 賦範空間
norm:function(v) { return x.norm() },
}
extend(j6.NormedVectorSpace, j6.VectorSpace);
j6.InnerProductSpace={ // 內積空間
dot(x,y) { return x.vdot(y) },
}
extend(j6.InnerProductSpace, j6.NormedVectorSpace);
// 仿射空間:a1 v1 + ... + an vn 中 sum(ai)=1
// https://en.wikipedia.org/wiki/Affine_space
j6.AffineSpace = {
sub(x,y) { }, // 點與點的差是一向量
add(x,v) { }, // 點加向量得一點,但點與點不可作加法
}
// ============= Euclidean Geometry 歐氏幾何 ====================
j6.EuclideanSpace = {
d(x,y) { return x.sub(y).norm() }, // v= x.sub(y); v.dot(v).sqrt()
dot(x,y) { return x.vdot(y) },
}
j6.LocallyConvaxSpace={}
extend(j6.LocallyConvaxSpace, j6.VectorSpace);
j6.HilbertSpace={} // HilbertSpace => InnerProductSpace => LocallyConvaxSpace => VectorSpace (LinearSpace)
extend(j6.HilbertSpace, j6.InnerProductSpace);
// BanachSpace => NormedVectorSpace => MetricSpace => TopologicalSpace
// NormedVectorSpace that Cauchy sequence of vectors always converges to a well defined limit
j6.BanachSpace={}
extend(j6.BanachSpace, j6.NormedVectorSpace);
j6.MeasureSpace = {} // 測度空間 M(Set) => j6
j6.ProbabilitySpace = {} // 機率空間 M(Set) = 1/3
// ============= Elliptic Geometry 橢圓幾何 ====================
j6.EllipticGeometry = {} // 橢圓幾何
j6.SphericalGeometry = {} // 球面幾何
j6.SphericalTrigonometry = {} // 球面三角學
j6.Geodesy = {} // 大地測量學
j6.GreatCircleDistance = {} // 大球距離
// 圓: x^2+y^2 = 1 => (x,y)=(sin t, cos t)
// 雙曲線: x^2-y^2 = 1 => (x,y) = (sinh t, cosh t)
// sinh = (e^x-e^{-x})/2, cosh = (e^x+e^{-x})/2
// https://en.wikipedia.org/wiki/Hyperbolic_function
// sinh x = -i sin ix ; cosh x = cos ix
// sin x 泰勒展開 = x - 1/3! x^3 + 1/5! x^5 ....
// sinh x 泰勒展開 = x + 1/3! x^3 + 1/5! x^5 ....
// int sinh cx dx = 1/c cosh cx + C
// ============= Hyperbolic Geometry 雙曲幾何 ====================
j6.HyperbolicGeometry = {}
// ============= Riemannian Geometry ====================
// https://en.wikipedia.org/wiki/Riemannian_geometry
j6.RiemannianGeometry = {} // 黎曼幾何
j6.RiemannianMetrics = {} // 黎曼度規
j6.MetricTensor = {} // 度規張量
j6.GaussBonnetTheorem = {} // 高斯博內定理
// ============= Manifold : 流形 ====================
j6.Manifold={}
j6.C0 = {}
j6.Coo = {}
// https://en.wikipedia.org/wiki/Topological_vector_space
j6.TopologicalVectorSpace = {}
// https://en.wikipedia.org/wiki/Locally_convex_topological_vector_space
j6.LocallyConvexSpace = {}
extend(j6.LocallyConvexSpace, j6.TopologicalVectorSpace);
extend(j6.LocallyConvexSpace, j6.NormedVectorSpace);
// m 維拓撲流形
j6.TopologicalManifold={
// M是豪斯多夫空間,x in M 有鄰域 U 同胚於 m 維歐幾里得空間 j6^{m}的一個開集
}
j6.BanachManifold = {}
// =========== Topological Ring ==============
j6.TopologicalRing = extend({}, j6.Ring);
j6.TopologicalField = extend({}, j6.Field);
// ref : https://en.wikipedia.org/wiki/Group_homomorphism
// https://en.wikipedia.org/wiki/Fundamental_theorem_on_homomorphisms
// 同態:h(a • b) = h(a) x h(b)
j6.homomorphism=function(h, g1, g2) {
var a=g1.random(), b=g2.random();
return eq(h(group1.op(a,b)), group2.op(h(a), h(b)))
}
// ref : https://en.wikipedia.org/wiki/Isomorphism
// https://en.wikipedia.org/wiki/Isomorphism_theorem
// 同構:h(a • b) = h(a) • h(b)
j6.isomorphism=function(h1, h2, g1, g2) {
var a1=g1.random(), b1=g2.random();
var a2=g1.random(), b2=g2.random();
return homorphism(h1,g1,g2)&&homorphism(h2,g2,g1);
}
// 多邊形:Polygon
// 多面體:Polyhedron : V-E+F = 2
// 多胞形:Polytope
// ============= Spherical Geometry ====================
j6.SphericalGeometry = {}
j6.MandelbrotSet = {}
/*
For each pixel (Px, Py) on the screen, do:
{
x0 = scaled x coordinate of pixel (scaled to lie in the Mandelbrot X scale (-2.5, 1))
y0 = scaled y coordinate of pixel (scaled to lie in the Mandelbrot Y scale (-1, 1))
x = 0.0
y = 0.0
iteration = 0
max_iteration = 1000
// Here N=2^8 is chosen as a reasonable bailout radius.
while ( x*x + y*y < (1 << 16) AND iteration < max_iteration ) {
xtemp = x*x - y*y + x0
y = 2*x*y + y0
x = xtemp
iteration = iteration + 1
}
// Used to avoid floating point issues with points inside the set.
if ( iteration < max_iteration ) {
// sqrt of inner term removed using log simplification rules.
log_zn = log( x*x + y*y ) / 2
nu = log( log_zn / log(2) ) / log(2)
// Rearranging the potential function.
// Dividing log_zn by log(2) instead of log(N = 1<<8)
// because we want the entire palette to range from the
// center to radius 2, NOT our bailout radius.
iteration = iteration + 1 - nu
}
color1 = palette[floor(iteration)]
color2 = palette[floor(iteration) + 1]
// iteration % 1 = fractional part of iteration.
color = linear_interpolate(color1, color2, iteration % 1)
plot(Px, Py, color)
}
*/
// 碎形幾何 : Fractal
// http://andrew-hoyer.com/
// http://andrew-hoyer.com/experiments/fractals/
// http://flam3.com/flame.pdf
// https://en.wikipedia.org/wiki/List_of_fractals_by_Hausdorff_dimension
// http://rembound.com/articles/drawing-mandelbrot-fractals-with-html5-canvas-and-javascript
// https://github.com/rembound/Mandelbrot-Fractal-HTML5/blob/master/mandelbrot-fractal.js
// 操控繪圖
// http://fabricjs.com/ (讚!)
// https://github.com/kangax/fabric.js
// 3D 動畫
// https://threejs.org/
// http://haptic-data.com/toxiclibsjs/
// 地理資訊
// ArcGIS : https://developers.arcgis.com/javascript/3/
// 動畫
// http://paperjs.org/features/
// https://processing.org/
// 向量
// http://victorjs.org/
// 3d: https://evanw.github.io/lightgl.js/docs/vector.html
}
},{}],6:[function(require,module,exports){
/* eslint-disable no-undef */
var j6 = module.exports = {}
require('./util')(j6)
require('./function')(j6)
require('./set')(j6)
require('./algebra')(j6)
require('./tensor')(j6)
require('./vector')(j6)
require('./matrix')(j6)
require('./probability')(j6)
require('./statistics')(j6)
require('./test')(j6)
require('./entropy')(j6)
require('./geometry')(j6)
require('./distance')(j6)
// j6.Symbol = require('algebrite')
/*
require('./optimize')(j6)
require('./nn/nn')(j6)
require('./ml/ml')(j6)
// j6.NN = require('./neural')
j6.Image = require('./image')
j6.Kb = require('./kb')
*/
var J = require('jStat').jStat
j6._ = require('lodash')
j6.dot = function (a, b, isComplex = false) {
return (j6.M.isMatrix(a)) ? j6.M.dot(a, b, isComplex) : j6.V.dot(a, b, isComplex)
}
j6.mapFunctions(j6, J, {
// C: 'combination', // C(n,m)
choose: 'combination', // C(n,m)
lchoose: 'combinationln', // log C(n,m)
// P: 'permutation', // P(n,m)
sd: 'stdev',
cov: 'covariance',
cor: 'corrcoeff'
})
j6.mixThis(Array.prototype, j6, [
'samples',
'range',
'median',
'variance',
'deviation',
'sd',
'cov',
'cor',
'normalize',
'curve',
'hist',
'ihist',
'eval'
])
j6.mixThisMap(Array.prototype, j6.T, {
dim: 'dim',
sum: 'sum',
near: 'near',
max: 'max',
min: 'min',
product: 'product',
norm: 'norm',
mean: 'mean',
map1: 'map1',
map2: 'map2',
// slow map version
// logical
all: 'all',
// compare
eq: 'eq',
neq: 'neq',
geq: 'geq',
leq: 'leq',
gt: 'gt',
lt: 'lt',
// *+-/%
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'
})
j6.mixThisMap(Array.prototype, j6.V, {
// fast vector op
vdot: 'dot',
vadd: 'add',
vsub: 'sub',
vmul: 'mul',
vdiv: 'div'
})
j6.mixThisMap(Number.prototype, j6, {
add: 'add',
sub: 'sub',
mul: 'mul',
div: 'div',
sqrt: 'sqrt',
mod: 'mod',
neg: 'neg',
inv: 'inv',
power: 'power',
eval: 'eval',
toComplex: 'toComplex'
})
j6.mixThis(Number.prototype, Math, [
'log',
'exp',
'abs',
'sin',
'cos',
'tan',
'asin',
'acos',
'atan',
'ceil',
'floor',
'round'
])
j6.mixThisMap(String.prototype, j6, {str: 'sstr', print: 'print', json: 'json'})
j6.mixThisMap(Number.prototype, j6, {str: 'nstr', print: 'print', json: 'json'})
j6.mixThisMap(Array.prototype, j6, {
str: 'vstr',
print: 'print',
json: 'json'
})
j6.mixThisMap(Object.prototype, j6, {
str: 'ostr',
// print: 'print', 這兩行去掉, c3.js 才能正常繪製圖表,原因不明!
// json: 'json'
})
j6.mixThisMap(Array.prototype, j6.M, {
lu: 'lu',
luSolve: 'luSolve',
svd: 'svd',
// 'cdelsq',
// 'clone',
rows: 'rows',
cols: 'cols',
row: 'row',
col: 'col',
tr: 'tr',
inv: 'inv',
// 'all',
// 'any',
// 'same',
// 'isFinite',
// 'isNaN',
// 'mapreduce',
// 'complex',
det: 'det',
// 'norm2',
// 'norm2Squared',
// 'norm2inf',
madd: 'add',
msub: 'sub',
mmul: 'mul',
mdiv: 'div',
mdot: 'dot',
// 'dim',
eig: 'eig',
// 'sum',
rowSum: 'rowSum',
colSum: 'colSum',
rowMean: 'rowMean',
colMean: 'colMean',
// mapM: 'mmap1',
// mapMM: 'mmap2',
// flat: 'flat',
mfillv: 'fillv',
maddv: 'addv',
// fillMM: 'fillMM',
// getBlock: 'getBlock',
// setBlock: 'setBlock',
// getDiag: 'getDiag',
diag: 'diag',
// 'parseFloat',
// 'parseDate',
// 'parseCSV',
// 'toCSV',
// strM: 'strM',
mstr: 'str',
// 'sumM',
isMatrix: 'isMatrix'
})
j6.mixThisMap(Array.prototype, j6, {
dot: 'dot'
})
var N = require('numeric')
// Advance mathematics
j6.ode = N.dopri // dopri(x0,x1,y0,f,tol,maxit,event) #Ordinary Diff Eq
j6.minimize = N.uncmin // uncmin(f,x0,tol,gradient,maxit,callback,options) # Unconstrained optimization
j6.solveLP = N.solveLP // dopri(x0,x1,y0,f,tol,maxit,event) #Ordinary Diff Eq
j6.spline = N.spline
j6.linspace = N.linspace
j6.copyFunctions(j6, J, [
'sumsqrt',
'sumsqerr',
'sumrow',
'meansqerr',
'geomean',
'median',
'cumsum',
'cumprod',
'mode',
'range',
'variance',
'stdev',
'meandev',
'meddev',
'skewness',
'kurtosis',
'coeffvar',
'quartiles',
'quantiles',
'percentile',
'percentileOfScore',
'histogram',
'covariance',
'corrcoeff',
'calcRdx',
'betafn',
'betacf',
'ibetainv',
'ibeta',
'gammafn',
'gammaln',
'gammap',
'lowRegGamma',
'gammapinv',
'factorialln',
'factorial',
'combination',
'combinationln',
'permutation',
'randn',
'randg'
])
// mix Lodash
j6.mixThisMap(Array.prototype, j6._, {
_chunk: 'chunk',
_compact: 'compact',
_concat: 'concat',
_difference: 'difference',
_differenceBy: 'differenceBy',
_differenceWith: 'differenceWith',
_drop: 'drop',
_dropRight: 'dropRight',
_dropRightWhile: 'dropRightWhile',
_dropWhile: 'dropWhile',
_fill: 'fill',
_findIndex: 'findIndex',
_findLastIndex: 'findLastIndex',
_flatten: 'flatten',
_flattenDeep: 'flattenDeep',
_flattenDepth: 'flattenDepth',
_fromPairs: 'flattenPairs',
_head: 'head',
_indexOf: 'indexOf',
_initial: 'initial',
_intersection: 'intersection',
_intersectionBy: 'intersectonBy',
_intersectionWith: 'intersectionWith',
_join: 'join',
_last: 'last',
_lastIndexOf: 'lastIndexOf',
_nth: 'nth',
_pull: 'pull',
_pullAll: 'pullAll',
_pullAllBy: 'pullAllBy',
_pullAllWith: 'pullAllWith',
_pullAt: 'pullAt',
_remove: 'remove',
_reverse: 'reverse',
_slice: 'slice',
_sortedIndex: 'sortedIndex',
_sortedIndexBy: 'sortedIndexBy',
_sortedIndexOf: 'sortedIndexOf',
_sortedLastIndex: 'sortedLastIndex',
_sortedLastIndexBy: 'sortedLastIndexBy',
_sortedLastIndexOf: 'sortedLastIndexOf',
_sortedUniq: 'sortedUniq',
_sortedUniqBy: 'sortedUniqBy',
_tail: 'tail',
_take: 'take',
_takeRight: 'takeRight',
_takeRightWhile: 'takeRightWhile',
_takeWhile: 'takeWhile',
_union: 'union',
_unionBy: 'unionBy',
_unionWith: 'unionWith',
_uniq: 'uniq',
_uniqBy: 'uniqBy',
_uniqWith: 'uniqWith',
_unzip: 'unzip',
_unzipWith: 'unzipWith',
_without: 'without',
_xor: 'xor',
_xorBy: 'xorBy',
_xorWith: 'xorWith',
_zip: 'zip',
_zipObject: 'zipObject',
_zipObjectDeep: 'zipObjectDeep',
_zipWith: 'zipWith',
// Collection
_countBy: 'countBy',
// each→ forEach
// _eachRight → forEachRight
_every: 'every',
_filter: 'filter',
_find: 'find',
_findLast: 'findLast',
_flatMap: 'flatMap',
_flatMapDeep: 'flatMapDeep',
_flatMapDepth: 'flatMapDepth',
_forEach: 'forEach',
_forEachRight: 'forEachRight',
_groupBy: 'groupBy',
_includes: 'includes',
_invokeMap: 'invokeMap',
_keyBy: 'keyBy',
_map: 'map',
_orderBy: 'orderBy',
_partition: 'partition',
_reduce: 'reduce',
_reduceRight: 'reduceRight',
_reject: 'reject',
_sample: 'sample',
_sampleSize: 'sampleSize',
_shuffle: 'shuffle',
_size: 'size',
_some: 'some',
_sortBy: 'sortBy'
})
},{"./algebra":1,"./distance":2,"./entropy":3,"./function":4,"./geometry":5,"./matrix":7,"./probability":8,"./set":9,"./statistics":10,"./tensor":11,"./test":12,"./util":13,"./vector":14,"jStat":15,"lodash":16,"numeric":17}],7:[function(require,module,exports){
module.exports = function (j6) {
/* eslint-disable one-var */
var N = require('numeric')
var M = j6.M = {}
M.sparse = N.ccsSparse // Matrix => Sparse
M.sparse2full = N.ccsFull // Sparse => Matrix
// j6.complex=N.t
// matrix
M.svd = N.svd
// j6.det = N.det
// j6.inv = N.inv
M.lu = N.cLU
M.luSolve = N.cLUsolve
// j6.dot = N.dot
// j6.rep = N.rep
// j6.tr = N.transpose
// j6.diag = N.diag
// j6.sumM = N.sum
M.str = N.prettyPrint
M.rows = function (m) { return m.length }
M.cols = function (m) { return m[0].length }
M.row = function (m, i) { return m[i] }
M.col = function (m, j) {
var rows = m.length
var c = new Array(rows)
for (var i = 0; i < rows; i++) {
c[i] = m[i][j]
}
return c
}
M.new = function (rows, cols, value = 0) {
return j6.T.repeat([rows, cols], value)
}
M.random = function (rows, cols, a, b) {
return j6.T.random([rows, cols], a, b)
}
M.rowSum = function (m) {
var rows = m.length
var s = new Array(rows)
for (var i = 0; i < rows; i++) {
s[i] = j6.T.sum(m[i])
}
return s
}
M.colSum = function (m) {
var rows = m.length
if (rows === 0) return []
var s = m[0]
for (var i = 1; i < rows; i++) {
s = j6.V.add(s, m[i])
}
return s
}
M.rowMean = function (m) {
return M.rowSum(m).div(m.cols())
}
M.colMean = function (m) {
return M.colSum(m).div(m.rows())
}
M.addv = function (m, v) {
var rows = m.length
var r = new Array(rows)
for (var i = 0; i < rows; i++) {
r[i] = j6.V.add(m[i], v) // 這行比較快 (使用多型速度會變慢)
}
return r
}
M.add = function (m1, m2) {
var rows = m1.length
var r = new Array(rows)
for (var i = 0; i < rows; i++) {
r[i] = j6.V.add(m1[i], m2[i])
}
return r
}
M.sub = function (m1, m2) {
var rows = m1.length
var r = new Array(rows)
for (var i = 0; i < rows; i++) {
r[i] = j6.V.sub(m1[i], m2[i])
}
return r
}
M.mul = function (m1, m2) {
var rows = m1.length
var r = new Array(rows)
for (var i = 0; i < rows; i++) {
r[i] = j6.V.mul(m1[i], m2[i])
}
return r
}
M.div = function (m1, m2) {
var rows = m1.length
var r = new Array(rows)
for (var i = 0; i < rows; i++) {
r[i] = j6.V.div(m1[i], m2[i])
}
return r
}
M.fillv = function (v, rows, cols) {
var m = new Array(rows)
for (var r = 0; r < rows; r++) {
var mr = m[r] = new Array(cols)
for (var c = 0; c < cols; c++) {
mr[c] = v[(r * cols) + c]
}
}
return m
}
M.eig = function (m) {
var E = N.eig(m)
return {lambda: E.lambda.x, E: E.E.x}
}
M.tr = M.transpose = function (m) {
var r = []
var rows = m.length
var cols = m[0].length
for (var j = 0; j < cols; j++) {
var rj = r[j] = []
for (var i = 0; i < rows; i++) {
rj[i] = m[i][j]
}
}
return r
}
M.dot = function (a, b, isComplex = false) {
var arows = a.length
var bcols = b[0].length
var r = []
var bt = M.tr(b)
for (var i = 0; i < arows; i++) {
var ri = r[i] = []
for (var j = 0; j < bcols; j++) {
ri.push(j6.V.dot(a[i], bt[j], isComplex))
}
}
return r
}
M.isMatrix = function (m) {
return (m instanceof Array && m[0] instanceof Array)
}
M.diag = function (v) {
var rows = v.length
var r = M.new(rows, rows)
for (var i = 0; i < rows; i++) {
r[i][i] = v[i]
}
return r
}
M.identity = function (n) {
return M.diag(j6.T.repeat([n], () => 1))
}
M.inv = function (m0) {
var s = j6.T.dim(m0), abs = Math.abs, m = s[0], n = s[1]
var A = j6.clone(m0), Ai, Aj
var I = M.identity(m), Ii, Ij
var i, j, k, x
for (j = 0; j < n; ++j) {
var i0 = -1
var v0 = -1
for (i = j; i !== m; ++i) {
k = abs(A[i][j])
if (k > v0) { i0 = i; v0 = k }
}
Aj = A[i0]; A[i0] = A[j]; A[j] = Aj
Ij = I[i0]; I[i0] = I[j]; I[j] = Ij
x = Aj[j]
for (k = j; k !== n; ++k) Aj[k] /= x
for (k = n - 1; k !== -1; --k) Ij[k] /= x
for (i = m - 1; i !== -1; --i) {
if (i !== j) {
Ai = A[i]
Ii = I[i]
x = Ai[j]
for (k = j + 1; k !== n; ++k) Ai[k] -= Aj[k] * x
for (k = n - 1; k > 0; --k) { Ii[k] -= Ij[k] * x; --k; Ii[k] -= Ij[k] * x }
if (k === 0) Ii[0] -= Ij[0] * x
}
}
}
return I
}
M.det = function (x) {
var s = j6.dim(x)
if (s.length !== 2 || s[0] !== s[1]) { throw new Error('numeric: det() only works on square matrices') }
var n = s[0], ret = 1, i, j, k, A = j6.clone(x), Aj, Ai, alpha, temp, k1
for (j = 0; j < n - 1; j++) {
k = j
for (i = j + 1; i < n; i++) { if (Math.abs(A[i][j]) > Math.abs(A[k][j])) { k = i } }
if (k !== j) {
temp = A[k]; A[k] = A[j]; A[j] = temp
ret *= -1
}
Aj = A[j]
for (i = j + 1; i < n; i++) {
Ai = A[i]
alpha = Ai[j] / Aj[j]
for (k = j + 1; k < n - 1; k += 2) {
k1 = k + 1
Ai[k] -= Aj[k] * alpha
Ai[k1] -= Aj[k1] * alpha
}
if (k !== n) { Ai[k] -= Aj[k] * alpha }
}
if (Aj[j] === 0) { return 0 }
ret *= Aj[j]
}
return ret * A[j][j]
}
}
},{"numeric":17}],8:[function(require,module,exports){
module.exports = function (j6) {
/* eslint-disable no-undef */
var J = require('jStat').jStat
var ncall = j6.ncall
// ========== 離散分佈的 r, q 函數 ============
j6.qcdf = function (cdf, q, N, p) {
for (var i = 0; i <= N; i++) {
if (cdf(i, N, p) > q) return i
}
return N
}
j6.rcdf = function (cdf, n, N, p) {
var a = []
for (var i = 0; i < n; i++) {
var q = Math.random()
a.push(cdf(q, N, p))
}
return a
}
j6.EPSILON = 0.0000000001
// 均等分布 : Uniform Distribution(a,b) 1/(b-a)
j6.dunif = function (x, a = 0, b = 1) { return (x >= a && x <= b) ? 1 / (b - a) : 0 }
j6.punif = function (x, a = 0, b = 1) { return (x >= b) ? 1 : (x <= a) ? 0 : (x - a) / (b - a) }
j6.qunif = function (p, a = 0, b = 1) { return (p >= 1) ? b : (p <= 0) ? a : a + (p * (b - a)) }
j6.runif1 = function (a = 0, b = 1) { return j6.random(a, b) }
j6.runif = function (n, a = 0, b = 1) { return ncall(n, j6, 'random', a, b) }
/*
j6.dunif=(x,a=0,b=1)=>J.uniform.pdf(x,a,b);
j6.punif=(q,a=0,b=1)=>J.uniform.cdf(q,a,b);
j6.qunif=(p,a=0,b=1)=>J.uniform.inv(p,a,b);
j6.runif=(n,a=0,b=1)=>ncall(n, J.uniform, 'sample', a, b);
*/
// 常態分布 : jStat.normal( mean, sd )
j6.dnorm = (x, mean = 0, sd = 1) => J.normal.pdf(x, mean, sd)
j6.pnorm = (q, mean = 0, sd = 1) => J.normal.cdf(q, mean, sd)
j6.qnorm = (p, mean = 0, sd = 1) => J.normal.inv(p, mean, sd)
j6.rnorm1 = function () { // generate random guassian distribution number. (mean : 0, standard deviation : 1)
var v1, v2, s
do {
v1 = (2 * Math.random()) - 1 // -1.0 ~ 1.0 ??? ?
v2 = (2 * Math.random()) - 1 // -1.0 ~ 1.0 ??? ?
s = (v1 * v1) + (v2 * v2)
} while (s >= 1 || s === 0)
s = Math.sqrt((-2 * Math.log(s)) / s)
return v1 * s
}
j6.rnorm = (n, mean = 0, sd = 1) => ncall(n, J.normal, 'sample', mean, sd)
// F 分布 : jStat.centralF( df1, df2 )
j6.df = (x, df1, df2) => J.centralF.pdf(x, df1, df2)
j6.pf = (q, df1, df2) => J.centralF.cdf(q, df1, df2)
j6.qf = (p, df1, df2) => J.centralF.inv(p, df1, df2)
j6.rf = (n, df1, df2) => ncall(n, J.centralF, 'sample', df1, df2)
// T 分布 : jStat.studentt( dof )
j6.dt = (x, dof) => J.studentt.pdf(x, dof)
j6.pt = (q, dof) => J.studentt.cdf(q, dof)
j6.qt = (p, dof) => J.studentt.inv(p, dof)
j6.rt = (n, dof) => ncall(n, J.studentt, 'sample', dof)
// Beta 分布 : jStat.beta( alpha, beta )
j6.dbeta = (x, alpha, beta) => J.beta.pdf(x, alpha, beta)
j6.pbeta = (q, alpha, beta) => J.beta.cdf(q, alpha, beta)
j6.qbeta = (p, alpha, beta) => J.beta.inv(p, alpha, beta)
j6.rbeta = (n, alpha, beta) => ncalls(n, J.beta, 'sample', alpha, beta)
// 柯西分布 : jStat.cauchy( local, scale )
j6.dcauchy = (x, local, scale) => J.cauchy.pdf(x, local, scale)
j6.pcauchy = (q, local, scale) => J.cauchy.cdf(q, local, scale)
j6.qcauchy = (p, local, scale) => J.cauchy.inv(q, local, scale)
j6.rcauchy = (n, local, scale) => ncall(n, J.cauchy, 'sample', local, scale)
// chisquare 分布 : jStat.chisquare( dof )
j6.dchisq = (x, dof) => J.chisquare.pdf(x, dof)
j6.pchisq = (q, dof) => J.chisquare.cdf(q, dof)
j6.qchisq = (p, dof) => J.chisquare.inv(p, dof)
j6.rchisq = (n, dof) => ncall(n, J.chisquare, 'sample', dof)
// 指數分布 : Exponential Distribution(b) 1/b e^{-x/b}
j6.dexp = function (x, rate) { return rate * Math.exp(-rate * x) }
j6.pexp = function (x, rate) { return x < 0 ? 0 : 1 - Math.exp(-rate * x) }
j6.qexp = function (p, rate) { return -Math.log(1 - p) / rate }
j6.rexp1 = function (rate) { return j6.qexp(j6.random(0, 1), rate) }
j6.rexp = function (n, rate) { return ncall(n, j6, 'rexp1', rate) }
/*
j6.dexp=(x,rate)=>J.exponential.pdf(x,rate);
j6.pexp=(q,rate)=>J.exponential.cdf(q,rate);
j6.qexp=(p,rate)=>J.exponential.inv(p,rate);
j6.rexp=(n,rate)=>ncall(n, J.exponential, 'sample', rate);
*/
// Gamma 分布 : jStat.gamma( shape, scale )
j6.dgamma = (x, shape, scale) => J.gamma.pdf(x, shape, scale)
j6.pgamma = (q, shape, scale) => J.gamma.cdf(q, shape, scale)
j6.qgamma = (p, shape, scale) => J.gamma.inv(p, shape, scale)
j6.rgamma = (n, shape, scale) => ncall(n, J.gamma, 'sample', shape, scale)
// 反 Gamma 分布 : jStat.invgamma( shape, scale )
j6.rinvgamma = (n, shape, scale) => ncall(n, J.invgamma, 'sample', shape, scale)
j6.dinvgamma = (x, shape, scale) => J.invgamma.pdf(x, shape, scale)
j6.pinvgamma = (q, shape, scale) => J.invgamma.cdf(q, shape, scale)
j6.qinvgamma = (p, shape, scale) => J.invgamma.inv(p, shape, scale)
// 對數常態分布 : jStat.lognormal( mu, sigma )
j6.dlognormal = (n, mu, sigma) => J.lognormal.pdf(x, sigma)
j6.plognormal = (n, mu, sigma) => J.lognormal.cdf(q, sigma)
j6.qlognormal = (n, mu, sigma) => J.lognormal.inv(p, sigma)
j6.rlognormal = (n, mu, sigma) => ncall(n, J.dlognormal, 'sample', mu, sigma)
// Pareto 分布 : jStat.pareto( scale, shape )
j6.dpareto = (n, scale, shape) => J.pareto.pdf(x, scale, shape)
j6.ppareto = (n, scale, shape) => J.pareto.cdf(q, scale, shape)
j6.qpareto = (n, scale, shape) => J.pareto.inv(p, scale, shape)
j6.rpareto = (n, scale, shape) => ncall(n, J.pareto, 'sample', scale, shape)
// Weibull 分布 jStat.weibull(scale, shape)
j6.dweibull = (n, scale, shape) => J.weibull.pdf(x, scale, shape)
j6.pweibull =