From 32daa373fb57aacd5275197ed904e291336db486 Mon Sep 17 00:00:00 2001 From: Daniel Holden Date: Sat, 20 Sep 2014 23:48:46 +0900 Subject: [PATCH 01/22] Initial commit for broadcasting experiment --- documentation.html | 14 ++++ src/documentation.html | 14 ++++ src/numeric.js | 157 +++++++++++++++++++++++++++++------------ 3 files changed, 140 insertions(+), 45 deletions(-) diff --git a/documentation.html b/documentation.html index 9767498..b34f9c0 100644 --- a/documentation.html +++ b/documentation.html @@ -123,6 +123,7 @@ powPointwise Math.pow(x) precisionNumber of digits to prettyPrint prettyPrintPretty-prints x +prodTake the product all the entries of x randomCreate an Array of random numbers repCreate an Array by duplicating values @@ -473,6 +474,19 @@

Arithmetic operations

--> +

Broadcasting

+ +When performing pointwise operations between two arrays, having a dimension of size 1 +in one of the arrays will result in that value being broadcast against every +element in the other array. + +
+IN> numeric.mul([[1,2],[3,4],[5,6]], [[10], [11], [22]])
+OUT> [[10,20],[33,44],[110,132]]
+IN> numeric.mul([[1,2],[3,4],[5,6]], [[10, 11]])
+OUT> [[10,22],[30,44],[50,66]]
+
+

Linear algebra

diff --git a/src/documentation.html b/src/documentation.html index 9767498..06b89b9 100644 --- a/src/documentation.html +++ b/src/documentation.html @@ -123,6 +123,7 @@ powPointwise Math.pow(x) precisionNumber of digits to prettyPrint prettyPrintPretty-prints x +prodTake the product all the entries of x randomCreate an Array of random numbers repCreate an Array by duplicating values @@ -473,6 +474,19 @@

Arithmetic operations

--> +

Broadcasting

+ +When performing pointwise operations between two arrays, having a dimension of size 1 +in one of the arrays will result in that value being broadcast, meaning it +will be used for the calculation against every element in the other array. + +
+IN> numeric.mul([[1,2],[3,4],[5,6]], [[10], [11], [22]])
+OUT> [[10,20],[33,44],[110,132]]
+IN> numeric.mul([[1,2],[3,4],[5,6]], [[10, 11]])
+OUT> [[10,22],[30,44],[50,66]]
+
+

Linear algebra

diff --git a/src/numeric.js b/src/numeric.js index 537b68f..9c464c1 100644 --- a/src/numeric.js +++ b/src/numeric.js @@ -526,6 +526,8 @@ numeric.getDiag = function(A) { } numeric.identity = function identity(n) { return numeric.diag(numeric.rep([n],1)); } + +/* TODO: Implement broadcasting for this function */ numeric.pointwise = function pointwise(params,body,setup) { if(typeof setup === "undefined") { setup = ""; } var fun = []; @@ -559,59 +561,124 @@ numeric.pointwise = function pointwise(params,body,setup) { ); return Function.apply(null,fun); } -numeric.pointwise2 = function pointwise2(params,body,setup) { + +numeric.pointwiseVS = function pointwiseVS(params,body,setup,ret) { if(typeof setup === "undefined") { setup = ""; } var fun = []; - var k; - var avec = /\[i\]$/,p,thevec = ''; - var haveret = false; - for(k=0;k=0;i--) { _biforeacheqV(x[i],y[0],sx,sy,k+1,f); }} + else { for(i=n-1;i>=0;i--) { _biforeacheqV(x[i],y[i],sx,sy,k+1,f); }} +}); + +numeric._biforeacheqS = (function _biforeacheqS(x,y,s,k,f) { if(k === s.length-1) { f(x,y); return; } var i,n=s[k]; - for(i=n-1;i>=0;i--) { _biforeach(typeof x==="object"?x[i]:x,typeof y==="object"?y[i]:y,s,k+1,f); } + for(i=n-1;i>=0;i--) { _biforeacheqS(x[i],y,s,k+1,f); } }); -numeric._biforeach2 = (function _biforeach2(x,y,s,k,f) { + +numeric._biforeachVS = (function _biforeachVS(x,y,s,k,f) { if(k === s.length-1) { return f(x,y); } - var i,n=s[k],ret = Array(n); - for(i=n-1;i>=0;--i) { ret[i] = _biforeach2(typeof x==="object"?x[i]:x,typeof y==="object"?y[i]:y,s,k+1,f); } + var i,n=s[k],ret=Array(n); + for(i=n-1;i>=0;--i) { ret[i] = _biforeachVS(x[i],y,s,k+1,f); } return ret; }); -numeric._foreach = (function _foreach(x,s,k,f) { + +numeric._biforeachSV = (function _biforeachSV(x,y,s,k,f) { + if(k === s.length-1) { return f(x,y); } + var i,n=s[k],ret=Array(n); + for(i=n-1;i>=0;--i) { ret[i] = _biforeachSV(x,y[i],s,k+1,f); } + return ret; +}); + +numeric._biforeacheqVV = (function _biforeacheqVV(x,y,sx,sy,k,f) { + if(k === sx.length-1) { f(x,y); return; } + var i,n=sx[k],m=sy[k]; + if (m === 1) { for(i=n-1;i>=0;i--) { _biforeacheqVV(x[i],y[0],sx,sy,k+1,f); }} + else { for(i=n-1;i>=0;i--) { _biforeacheqVV(x[i],y[i],sx,sy,k+1,f); }} +}); + +numeric._biforeachVV = (function _biforeachVV(x,y,sx,sy,k,f) { + if(k === sx.length-1) { return f(x,y); } + var i,n=sx[k],m=sy[k],ret=(n===1)?Array(m):Array(n); + if (n === 1) { for(i=m-1;i>=0;--i) { ret[i] = _biforeachVV(x[0],y[i],sx,sy,k+1,f); }} + else if (m === 1) { for(i=n-1;i>=0;--i) { ret[i] = _biforeachVV(x[i],y[0],sx,sy,k+1,f); }} + else { for(i=n-1;i>=0;--i) { ret[i] = _biforeachVV(x[i],y[i],sx,sy,k+1,f); }} + return ret; +}); + +numeric._foreacheq = (function _foreacheq(x,s,k,f) { if(k === s.length-1) { f(x); return; } var i,n=s[k]; - for(i=n-1;i>=0;i--) { _foreach(x[i],s,k+1,f); } + for(i=n-1;i>=0;i--) { _foreacheq(x[i],s,k+1,f); } }); -numeric._foreach2 = (function _foreach2(x,s,k,f) { + +numeric._foreach = (function _foreach(x,s,k,f) { if(k === s.length-1) { return f(x); } - var i,n=s[k], ret = Array(n); - for(i=n-1;i>=0;i--) { ret[i] = _foreach2(x[i],s,k+1,f); } + var i,n=s[k],ret=Array(n); + for(i=n-1;i>=0;i--) { ret[i] = _foreach(x[i],s,k+1,f); } return ret; }); -/*numeric.anyV = numeric.mapreduce('if(xi) return true;','false'); -numeric.allV = numeric.mapreduce('if(!xi) return false;','true'); -numeric.any = function(x) { if(typeof x.length === "undefined") return x; return numeric.anyV(x); } -numeric.all = function(x) { if(typeof x.length === "undefined") return x; return numeric.allV(x); }*/ - numeric.ops2 = { add: '+', sub: '-', @@ -690,9 +757,9 @@ numeric.mapreducers = { codeeq = function(x,y) { return x+' = '+x+' '+o+' '+y; }; } } - numeric[i+'VV'] = numeric.pointwise2(['x[i]','y[i]'],code('ret[i]','x[i]','y[i]'),setup); - numeric[i+'SV'] = numeric.pointwise2(['x','y[i]'],code('ret[i]','x','y[i]'),setup); - numeric[i+'VS'] = numeric.pointwise2(['x[i]','y'],code('ret[i]','x[i]','y'),setup); + numeric[i+'VV'] = numeric.pointwiseVV(['x[i]','y[j]'],code('ret[i]','x[i]','y[j]'),setup,false); + numeric[i+'SV'] = numeric.pointwiseSV(['x', 'y[i]'],code('ret[i]','x', 'y[i]'),setup,false); + numeric[i+'VS'] = numeric.pointwiseVS(['x[i]','y' ],code('ret[i]','x[i]','y' ),setup,false); numeric[i] = Function( 'var n = arguments.length, i, x = arguments[0], y;\n'+ 'var VV = numeric.'+i+'VV, VS = numeric.'+i+'VS, SV = numeric.'+i+'SV;\n'+ @@ -700,22 +767,22 @@ numeric.mapreducers = { 'for(i=1;i!==n;++i) { \n'+ ' y = arguments[i];\n'+ ' if(typeof x === "object") {\n'+ - ' if(typeof y === "object") x = numeric._biforeach2(x,y,dim(x),0,VV);\n'+ - ' else x = numeric._biforeach2(x,y,dim(x),0,VS);\n'+ - ' } else if(typeof y === "object") x = numeric._biforeach2(x,y,dim(y),0,SV);\n'+ + ' if(typeof y === "object") x = numeric._biforeachVV(x,y,dim(x),dim(y),0,VV);\n'+ + ' else x = numeric._biforeachVS(x,y,dim(x),0,VS);\n'+ + ' } else if(typeof y === "object") x = numeric._biforeachSV(x,y,dim(y),0,SV);\n'+ ' else '+codeeq('x','y')+'\n'+ '}\nreturn x;\n'); numeric[o] = numeric[i]; - numeric[i+'eqV'] = numeric.pointwise2(['ret[i]','x[i]'], codeeq('ret[i]','x[i]'),setup); - numeric[i+'eqS'] = numeric.pointwise2(['ret[i]','x'], codeeq('ret[i]','x'),setup); + numeric[i+'eqV'] = numeric.pointwiseVV(['ret[i]','x[j]'], codeeq('ret[i]','x[j]'),setup,true); + numeric[i+'eqS'] = numeric.pointwiseVS(['ret[i]','x' ], codeeq('ret[i]','x' ),setup,true); numeric[i+'eq'] = Function( 'var n = arguments.length, i, x = arguments[0], y;\n'+ 'var V = numeric.'+i+'eqV, S = numeric.'+i+'eqS\n'+ - 'var s = numeric.dim(x);\n'+ + 'var dim = numeric.dim;\n'+ 'for(i=1;i!==n;++i) { \n'+ ' y = arguments[i];\n'+ - ' if(typeof y === "object") numeric._biforeach(x,y,s,0,V);\n'+ - ' else numeric._biforeach(x,y,s,0,S);\n'+ + ' if(typeof y === "object") numeric._biforeacheqV(x,y,dim(x),dim(y),0,V);\n'+ + ' else numeric._biforeacheqS(x,y,dim(x),0,S);\n'+ '}\nreturn x;\n'); } } @@ -734,21 +801,21 @@ numeric.mapreducers = { if(numeric.myIndexOf.call(numeric.mathfuns,i)!==-1) { if(Math.hasOwnProperty(o)) setup = 'var '+o+' = Math.'+o+';\n'; } - numeric[i+'eqV'] = numeric.pointwise2(['ret[i]'],'ret[i] = '+o+'(ret[i]);',setup); + numeric[i+'eqV'] = numeric.pointwiseSV(['ret[i]'],'ret[i] = '+o+'(ret[i]);',setup,true); numeric[i+'eq'] = Function('x', 'if(typeof x !== "object") return '+o+'x\n'+ 'var i;\n'+ 'var V = numeric.'+i+'eqV;\n'+ 'var s = numeric.dim(x);\n'+ - 'numeric._foreach(x,s,0,V);\n'+ + 'numeric._foreacheq(x,s,0,V);\n'+ 'return x;\n'); - numeric[i+'V'] = numeric.pointwise2(['x[i]'],'ret[i] = '+o+'(x[i]);',setup); + numeric[i+'V'] = numeric.pointwiseSV(['x[i]'],'ret[i] = '+o+'(x[i]);',setup,false); numeric[i] = Function('x', 'if(typeof x !== "object") return '+o+'(x)\n'+ 'var i;\n'+ 'var V = numeric.'+i+'V;\n'+ 'var s = numeric.dim(x);\n'+ - 'return numeric._foreach2(x,s,0,V);\n'); + 'return numeric._foreach(x,s,0,V);\n'); } } for(i=0;i Date: Sun, 21 Sep 2014 11:45:36 +0900 Subject: [PATCH 02/22] Added slicing. Fixed bug in broadcasting and neatened up code. --- src/documentation.html | 109 ++++++++++++++++++++++++++++-- src/numeric.js | 147 +++++++++++++++++++++++++---------------- 2 files changed, 194 insertions(+), 62 deletions(-) diff --git a/src/documentation.html b/src/documentation.html index 06b89b9..1cb9f00 100644 --- a/src/documentation.html +++ b/src/documentation.html @@ -474,17 +474,114 @@

Arithmetic operations

--> + + +

Slicing

+ +The slice command allows for accessing numeric arrays in more advanced ways. +In its most basic functionality you can pass in a list of indices to access on +each dimension. + +
+IN> numeric.slice([[1,2],[3,4],[5,6]], [2,0])
+OUT> 5
+IN> numeric.slice([[1,2],[3,4],[5,6]], [1])
+OUT> [3,4]
+
+ +But rather than an integer you can also pass in it a slice string. This is +a string consisting of three number separated by colons start:stop:step +which tell the command to access the array starting from some element index, stopping +at some element index, and performing some incrementing step size. + +
+IN> numeric.slice([0,1,2,3,4,5,6,7,8,9], [1+':'+7+':'+2])
+OUT> [1,3,5]
+IN> numeric.slice([1,5,1,7,26], [0+':'+5+':'+2])
+OUT> [1,1,26]
+
+ +The slice string is flexible. You can leave out the step section, or +omit actual numbers for the starting and stopping values, and defaults using the +start or end of the array are assumed. + +
+IN> numeric.slice([1,5,1,7,26], [1+':'+3])
+OUT> [5,1]
+IN> numeric.slice([1,5,1,7,26], [':'+3])
+OUT> [1,5,1]
+IN> numeric.slice([1,5,1,7,26], [3+':'])
+OUT> [7,26]
+IN> numeric.slice([1,5,1,7,26], [':'])
+OUT> [1,5,1,7,26]
+IN> numeric.slice([[1,2],[3,4],[5,6]], [':',1])
+OUT> [2,4,6]
+
+ +Negative numbers can also be used as indices. These are assumed to be offsets from +the final element in the array. So -1 can be used to mean the final element, +-2 the second to last, etc. + +
+IN> numeric.slice([0,1,2,3,4,5,6,7,8,9], [-1])
+OUT> 9
+IN> numeric.slice([0,1,2,3,4,5,6,7,8,9], [-2+':'+10])
+OUT> [8,9]
+IN> numeric.slice([0,1,2,3,4,5,6,7,8,9], [-3+':'+3+':'+-1])
+OUT> [7,6,5,4]
+
+ +The string '|' can be used to insert a new axis of a single element into +an array. This is particularly useful when used in conjunction with broadcasting. + +
+IN> numeric.slice([0,1,2,3,4,5,6,7,8,9], ['|'])
+OUT> [[0,1,2,3,4,5,6,7,8,9]]
+IN> numeric.slice([0,1,2,3,4,5,6,7,8,9], [':','|'])
+OUT> [[0],[1],[2],[3],[4],[5],[6],[7],[8],[9]]
+IN> numeric.dim([0,1,2,3,4,5,6,7,8,9])
+OUT> [10]
+IN> numeric.dim(numeric.slice([0,1,2,3,4,5,6,7,8,9], ['|',':']))
+OUT> [1,10]
+IN> numeric.dim(numeric.slice([0,1,2,3,4,5,6,7,8,9], [':','|']))
+OUT> [10,1]
+
+

Broadcasting

-When performing pointwise operations between two arrays, having a dimension of size 1 -in one of the arrays will result in that value being broadcast, meaning it -will be used for the calculation against every element in the other array. +When performing pointwise operations between two arrays it is sometimes possible +to calculate a result when the dimensions don't exactly match. This behaviour is +called broadcast. It works as follows. Given an array with a dimension +of size 1, the single value in this dimension will be used as the operand for all +calculations for that axis. You can think of this value being stretched +or repeated so that it is matched against every element in the other array.
-IN> numeric.mul([[1,2],[3,4],[5,6]], [[10], [11], [22]])
-OUT> [[10,20],[33,44],[110,132]]
-IN> numeric.mul([[1,2],[3,4],[5,6]], [[10, 11]])
+IN> numeric.mul([[1,2],[3,4],[5,6]], [[10,11]])
 OUT> [[10,22],[30,44],[50,66]]
+IN> numeric.mul([[1,2],[3,4],[5,6]], [[10],[11],[22]])
+OUT> [[10,20],[33,44],[110,132]]
+IN> numeric.add(numeric.identity(3), [[1,1,1]])
+OUT> [[2,1,1],
+      [1,2,1],
+      [1,1,2]]
+IN> numeric.add(numeric.rep([3,5], 0), [[1,2,3,4,5]])
+OUT> [[1,2,3,4,5],
+      [1,2,3,4,5],
+      [1,2,3,4,5]]
+IN> numeric.add(numeric.rep([2,2,2], 0), [[[1],[2]]])
+OUT> [[[1,1],[2,2]],
+      [[1,1],[2,2]]]
+
+ +This can be very useful. For example we can use the new axis '|' slice +object to efficiently compute a pairwise multiplication between two vectors. + +
+IN> numeric.mul(numeric.slice([1,2,3],[':','|']), numeric.slice([4,5,6],['|',':']))
+OUT> [[4,  5, 6],
+      [8, 10,12],
+      [12,15,18]]
 
diff --git a/src/numeric.js b/src/numeric.js index 9c464c1..a5cb741 100644 --- a/src/numeric.js +++ b/src/numeric.js @@ -563,63 +563,38 @@ numeric.pointwise = function pointwise(params,body,setup) { } numeric.pointwiseVS = function pointwiseVS(params,body,setup,ret) { - if(typeof setup === "undefined") { setup = ""; } - var fun = []; - var avec = /\[[ij]\]$/; - for(var k=0;kr.stop):(i=0) && (ir.stop):(i=0) && (i Date: Sun, 21 Sep 2014 11:47:25 +0900 Subject: [PATCH 03/22] removed unneeded parenthesis --- src/numeric.js | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/numeric.js b/src/numeric.js index a5cb741..5461ffb 100644 --- a/src/numeric.js +++ b/src/numeric.js @@ -598,61 +598,61 @@ numeric.pointwiseVV = function pointwiseVV(params,body,setup,ret) { return Function.apply(null,fun); } -numeric._biforeacheqV = (function _biforeacheqV(x,y,sx,sy,k,f) { +numeric._biforeacheqV = function _biforeacheqV(x,y,sx,sy,k,f) { if(k === sx.length-1) { f(x,y); return; } var i,n=sx[k],m=sy[k]; if (m === 1) { for(i=n-1;i>=0;i--) { _biforeacheqV(x[i],y[0],sx,sy,k+1,f); }} else { for(i=n-1;i>=0;i--) { _biforeacheqV(x[i],y[i],sx,sy,k+1,f); }} -}); +}; -numeric._biforeacheqS = (function _biforeacheqS(x,y,s,k,f) { +numeric._biforeacheqS = function _biforeacheqS(x,y,s,k,f) { if(k === s.length-1) { f(x,y); return; } var i,n=s[k]; for(i=n-1;i>=0;i--) { _biforeacheqS(x[i],y,s,k+1,f); } -}); +}; -numeric._biforeachVS = (function _biforeachVS(x,y,s,k,f) { +numeric._biforeachVS = function _biforeachVS(x,y,s,k,f) { if(k === s.length-1) { return f(x,y); } var i,n=s[k],ret=Array(n); for(i=n-1;i>=0;--i) { ret[i] = _biforeachVS(x[i],y,s,k+1,f); } return ret; -}); +}; -numeric._biforeachSV = (function _biforeachSV(x,y,s,k,f) { +numeric._biforeachSV = function _biforeachSV(x,y,s,k,f) { if(k === s.length-1) { return f(x,y); } var i,n=s[k],ret=Array(n); for(i=n-1;i>=0;--i) { ret[i] = _biforeachSV(x,y[i],s,k+1,f); } return ret; -}); +}; -numeric._biforeacheqVV = (function _biforeacheqVV(x,y,sx,sy,k,f) { +numeric._biforeacheqVV = function _biforeacheqVV(x,y,sx,sy,k,f) { if(k === sx.length-1) { f(x,y); return; } var i,n=sx[k],m=sy[k]; if (m === 1) { for(i=n-1;i>=0;i--) { _biforeacheqVV(x[i],y[0],sx,sy,k+1,f); }} else { for(i=n-1;i>=0;i--) { _biforeacheqVV(x[i],y[i],sx,sy,k+1,f); }} -}); +}; -numeric._biforeachVV = (function _biforeachVV(x,y,sx,sy,k,f) { +numeric._biforeachVV = function _biforeachVV(x,y,sx,sy,k,f) { if(k === sx.length-1) { return f(x,y); } var i,n=sx[k],m=sy[k],ret=(n===1)?Array(m):Array(n); if (n === 1) { for(i=m-1;i>=0;--i) { ret[i] = _biforeachVV(x[0],y[i],sx,sy,k+1,f); }} else if (m === 1) { for(i=n-1;i>=0;--i) { ret[i] = _biforeachVV(x[i],y[0],sx,sy,k+1,f); }} else { for(i=n-1;i>=0;--i) { ret[i] = _biforeachVV(x[i],y[i],sx,sy,k+1,f); }} return ret; -}); +}; -numeric._foreacheq = (function _foreacheq(x,s,k,f) { +numeric._foreacheq = function _foreacheq(x,s,k,f) { if(k === s.length-1) { f(x); return; } var i,n=s[k]; for(i=n-1;i>=0;i--) { _foreacheq(x[i],s,k+1,f); } -}); +}; -numeric._foreach = (function _foreach(x,s,k,f) { +numeric._foreach = function _foreach(x,s,k,f) { if(k === s.length-1) { return f(x); } var i,n=s[k],ret=Array(n); for(i=n-1;i>=0;i--) { ret[i] = _foreach(x[i],s,k+1,f); } return ret; -}); +}; numeric.ops2 = { add: '+', From dc949ca09e02706aba1a23a3509bc48d166b8e86 Mon Sep 17 00:00:00 2001 From: Daniel Holden Date: Sun, 21 Sep 2014 14:16:45 +0900 Subject: [PATCH 04/22] added sliceeq and reshape function. Fixed flatten function --- documentation.html | 145 +++++++++++++++++++++++++++++++++++++++-- src/documentation.html | 58 +++++++++++++---- src/numeric.js | 57 +++++++++++++--- 3 files changed, 233 insertions(+), 27 deletions(-) diff --git a/documentation.html b/documentation.html index b34f9c0..f2ba0ee 100644 --- a/documentation.html +++ b/documentation.html @@ -85,6 +85,7 @@ epsilon2.220446049250313e-16 eqPointwise comparison x === y expPointwise Math.exp(x) +flattenFlatten an Array into a single dimension floorPoinwise Math.floor(x) geqPointwise x>=y getBlockExtract a block from a matrix @@ -126,6 +127,7 @@ prodTake the product all the entries of x randomCreate an Array of random numbers repCreate an Array by duplicating values +reshapeReshape an Array to given dimensions @@ -140,6 +142,8 @@
seedrandomThe seedrandom module
setBlockSet a block of a matrix
sinPointwise Math.sin(x) +
sliceReturn some range or indices of an Array +
sliceeqAssign values into some range or indices of an Array
solveSolve Ax=b
solveLPSolve a linear programming problem
solveQPSolve a quadratic programming problem @@ -474,19 +478,148 @@

Arithmetic operations

--> +

Slicing

+ +The slice command allows for accessing numeric Arrays in more advanced ways. +In its most basic functionality you can pass in a list of indices to access on +each dimension. + +
+IN> numeric.slice([[1,2],[3,4],[5,6]], [2,0])
+OUT> 5
+IN> numeric.slice([[1,2],[3,4],[5,6]], [1])
+OUT> [3,4]
+
+ +But rather than an integer you can also pass in it a slice string. This is +a string consisting of three number separated by colons start:stop:step +which tell the command to access the Array starting from some element index, stopping +at some element index, and performing some incrementing step size. + +
+IN> numeric.slice([0,1,2,3,4,5,6,7,8,9], [1+':'+7+':'+2])
+OUT> [1,3,5]
+IN> numeric.slice([1,5,1,7,26], [0+':'+5+':'+2])
+OUT> [1,1,26]
+
+ +The slice string is flexible. You can leave out the step section, or +omit actual numbers for the starting and stopping values, and defaults using the +start or end of the Array are assumed. + +
+IN> numeric.slice([1,5,1,7,26], [1+':'+3])
+OUT> [5,1]
+IN> numeric.slice([1,5,1,7,26], [':'+3])
+OUT> [1,5,1]
+IN> numeric.slice([1,5,1,7,26], [3+':'])
+OUT> [7,26]
+IN> numeric.slice([1,5,1,7,26], [':'])
+OUT> [1,5,1,7,26]
+IN> numeric.slice([[1,2],[3,4],[5,6]], [':',1])
+OUT> [2,4,6]
+
+ +Negative numbers can also be used as indices. These are assumed to be offsets from +the final element in the Array. So -1 can be used to mean the final element, +-2 the second to last, etc. + +
+IN> numeric.slice([0,1,2,3,4,5,6,7,8,9], [-1])
+OUT> 9
+IN> numeric.slice([0,1,2,3,4,5,6,7,8,9], [-2+':'+10])
+OUT> [8,9]
+IN> numeric.slice([0,1,2,3,4,5,6,7,8,9], [-3+':'+3+':'+-1])
+OUT> [7,6,5,4]
+
+ +The string '|' can be used to insert a new axis of a single element into +an Array. This is particularly useful when used in conjunction with broadcasting. + +
+IN> numeric.slice([0,1,2,3,4,5,6,7,8,9], ['|'])
+OUT> [[0,1,2,3,4,5,6,7,8,9]]
+IN> numeric.slice([0,1,2,3,4,5,6,7,8,9], [':','|'])
+OUT> [[0],[1],[2],[3],[4],[5],[6],[7],[8],[9]]
+IN> numeric.dim([0,1,2,3,4,5,6,7,8,9])
+OUT> [10]
+IN> numeric.dim(numeric.slice([0,1,2,3,4,5,6,7,8,9], ['|',':']))
+OUT> [1,10]
+IN> numeric.dim(numeric.slice([0,1,2,3,4,5,6,7,8,9], [':','|']))
+OUT> [10,1]
+
+ +As well as extracting data you can also set data using the sliceeq function. +If you have previously extracted some data using a slice this can be useful for inserting +it back into an Array. + +
+IN> v = [1,2,3,4]; numeric.sliceeq(v,[0,0],[':'+2]); v
+OUT> [0,0,3,4]
+IN> v = [[1,2],[3,4]]; numeric.sliceeq(v,10,[':',1]); v
+OUT> [[1,10],[3,10]]
+
+ +

Broadcasting

-When performing pointwise operations between two arrays, having a dimension of size 1 -in one of the arrays will result in that value being broadcast against every -element in the other array. +When performing pointwise operations between two Arrays it is sometimes possible +to calculate a result when the dimensions don't exactly match. This behaviour is +called broadcast. It works as follows. Given an Array with a dimension +of size 1, the single value in this dimension will be used as the operand for all +calculations along that axis. You can think of this value being stretched +or repeated so that it is matched against every element in the other Array.
-IN> numeric.mul([[1,2],[3,4],[5,6]], [[10], [11], [22]])
-OUT> [[10,20],[33,44],[110,132]]
-IN> numeric.mul([[1,2],[3,4],[5,6]], [[10, 11]])
+IN> numeric.mul([[1,2],[3,4],[5,6]], [[10,11]])
 OUT> [[10,22],[30,44],[50,66]]
+IN> numeric.mul([[1,2],[3,4],[5,6]], [[10],[11],[22]])
+OUT> [[10,20],[33,44],[110,132]]
+IN> numeric.add(numeric.identity(3), [[1,1,1]])
+OUT> [[2,1,1],
+      [1,2,1],
+      [1,1,2]]
+IN> numeric.add(numeric.rep([3,5], 0), [[1,2,3,4,5]])
+OUT> [[1,2,3,4,5],
+      [1,2,3,4,5],
+      [1,2,3,4,5]]
+IN> numeric.add(numeric.rep([2,2,2], 0), [[[1],[2]]])
+OUT> [[[1,1],[2,2]],
+      [[1,1],[2,2]]]
+
+ +This can be very useful. For example we can use the new axis '|' slice +object to efficiently compute a pairwise multiplication between two vectors. + +
+IN> numeric.mul(numeric.slice([1,2,3],[':','|']), numeric.slice([4,5,6],['|',':']))
+OUT> [[4,  5, 6],
+      [8, 10,12],
+      [12,15,18]]
 
+Unlike Numpy's +broadcasting mechanics for performance, unless a scalar is used, numeric does not +automatically align shapes on the right hand side. It is the user's responsibility to add +all the new axis which are required before broadcasting can work. + +

Reshaping

+ +Arrays can be reshaped to different dimensions using the reshape function, +or they can be flattened into a single Array using the flatten function. + +
+IN> numeric.flatten([[1,2],[3,4],[5,6]])
+OUT> [1,2,3,4,5,6]
+IN> numeric.reshape([1,2,3,4],[2,2])
+OUT> [[1,2],[3,4]]
+IN> numeric.dim([[1,2],[3,4],[5,6]])
+OUT> [3,2]
+IN> numeric.reshape([[1,2],[3,4],[5,6]],[2,3])
+OUT> [[1,2,3],[4,5,6]]
+IN> numeric.dim([[1,2,3],[4,5,6]])
+OUT> [2,3]
+

Linear algebra

diff --git a/src/documentation.html b/src/documentation.html index 1cb9f00..f2ba0ee 100644 --- a/src/documentation.html +++ b/src/documentation.html @@ -85,6 +85,7 @@
epsilon2.220446049250313e-16
eqPointwise comparison x === y
expPointwise Math.exp(x) +
flattenFlatten an Array into a single dimension
floorPoinwise Math.floor(x)
geqPointwise x>=y
getBlockExtract a block from a matrix @@ -126,6 +127,7 @@
prodTake the product all the entries of x
randomCreate an Array of random numbers
repCreate an Array by duplicating values +
reshapeReshape an Array to given dimensions
@@ -140,6 +142,8 @@ Join two Arrays together on a given axis Join a list of Arrays together on their third innermost axis Join a list of Arrays together on their innermost axis Join a list of Arrays together on a given axis Join a list of Arrays together on their second innermost axis +Given three Arrays take elements from either the second, or third array, given the boolean value of the elements of the first.
seedrandomThe seedrandom module
setBlockSet a block of a matrix
sinPointwise Math.sin(x) +
sliceReturn some range or indices of an Array +
sliceeqAssign values into some range or indices of an Array
solveSolve Ax=b
solveLPSolve a linear programming problem
solveQPSolve a quadratic programming problem @@ -474,11 +478,9 @@

Arithmetic operations

--> - -

Slicing

-The slice command allows for accessing numeric arrays in more advanced ways. +The slice command allows for accessing numeric Arrays in more advanced ways. In its most basic functionality you can pass in a list of indices to access on each dimension. @@ -491,7 +493,7 @@

Slicing

But rather than an integer you can also pass in it a slice string. This is a string consisting of three number separated by colons start:stop:step -which tell the command to access the array starting from some element index, stopping +which tell the command to access the Array starting from some element index, stopping at some element index, and performing some incrementing step size.
@@ -503,7 +505,7 @@ 

Slicing

The slice string is flexible. You can leave out the step section, or omit actual numbers for the starting and stopping values, and defaults using the -start or end of the array are assumed. +start or end of the Array are assumed.
 IN> numeric.slice([1,5,1,7,26], [1+':'+3])
@@ -519,7 +521,7 @@ 

Slicing

Negative numbers can also be used as indices. These are assumed to be offsets from -the final element in the array. So -1 can be used to mean the final element, +the final element in the Array. So -1 can be used to mean the final element, -2 the second to last, etc.
@@ -532,7 +534,7 @@ 

Slicing

The string '|' can be used to insert a new axis of a single element into -an array. This is particularly useful when used in conjunction with broadcasting. +an Array. This is particularly useful when used in conjunction with broadcasting.
 IN> numeric.slice([0,1,2,3,4,5,6,7,8,9], ['|'])
@@ -547,14 +549,26 @@ 

Slicing

OUT> [10,1]
+As well as extracting data you can also set data using the sliceeq function. +If you have previously extracted some data using a slice this can be useful for inserting +it back into an Array. + +
+IN> v = [1,2,3,4]; numeric.sliceeq(v,[0,0],[':'+2]); v
+OUT> [0,0,3,4]
+IN> v = [[1,2],[3,4]]; numeric.sliceeq(v,10,[':',1]); v
+OUT> [[1,10],[3,10]]
+
+ +

Broadcasting

-When performing pointwise operations between two arrays it is sometimes possible +When performing pointwise operations between two Arrays it is sometimes possible to calculate a result when the dimensions don't exactly match. This behaviour is -called broadcast. It works as follows. Given an array with a dimension +called broadcast. It works as follows. Given an Array with a dimension of size 1, the single value in this dimension will be used as the operand for all -calculations for that axis. You can think of this value being stretched -or repeated so that it is matched against every element in the other array. +calculations along that axis. You can think of this value being stretched +or repeated so that it is matched against every element in the other Array.
 IN> numeric.mul([[1,2],[3,4],[5,6]], [[10,11]])
@@ -584,6 +598,28 @@ 

Broadcasting

[12,15,18]]
+Unlike Numpy's +broadcasting mechanics for performance, unless a scalar is used, numeric does not +automatically align shapes on the right hand side. It is the user's responsibility to add +all the new axis which are required before broadcasting can work. + +

Reshaping

+ +Arrays can be reshaped to different dimensions using the reshape function, +or they can be flattened into a single Array using the flatten function. + +
+IN> numeric.flatten([[1,2],[3,4],[5,6]])
+OUT> [1,2,3,4,5,6]
+IN> numeric.reshape([1,2,3,4],[2,2])
+OUT> [[1,2],[3,4]]
+IN> numeric.dim([[1,2],[3,4],[5,6]])
+OUT> [3,2]
+IN> numeric.reshape([[1,2],[3,4],[5,6]],[2,3])
+OUT> [[1,2,3],[4,5,6]]
+IN> numeric.dim([[1,2,3],[4,5,6]])
+OUT> [2,3]
+

Linear algebra

diff --git a/src/numeric.js b/src/numeric.js index 5461ffb..f0013dd 100644 --- a/src/numeric.js +++ b/src/numeric.js @@ -568,8 +568,7 @@ numeric.pointwiseVS = function pointwiseVS(params,body,setup,ret) { 'var _n='+params[0]+'.length;\n'+ 'var i'+(ret?'':', ret = Array(_n)')+';\n'+setup+';\n'+ 'for(i=_n-1;i!==-1;--i) {'+body+'}\n'+ - 'return ret;' - ]); + 'return ret;']); return Function.apply(null,fun); } @@ -579,8 +578,7 @@ numeric.pointwiseSV = function pointwiseSV(params,body,setup,ret) { 'var _n='+params[1]+'.length;\n'+ 'var i'+(ret?'':', ret = Array(_n)')+';\n'+setup+';\n'+ 'for(i=_n-1;i!==-1;--i) {'+body+'}\n'+ - 'return ret;' - ]); + 'return ret;']); return Function.apply(null,fun); } @@ -593,8 +591,7 @@ numeric.pointwiseVV = function pointwiseVV(params,body,setup,ret) { (ret?'':('if(_n === 1) { for(j=_m-1;j!==-1;--j) {i=0;k=j;'+body+'} } else \n'))+ 'if(_m === 1) { for(i=_n-1;i!==-1;--i) {j=0;k=i;'+body+'} }\n'+ 'else { for(i=_n-1;i!==-1;--i) {j=i;k=i;'+body+'} }\n'+ - 'return ret;' - ]); + 'return ret;']); return Function.apply(null,fun); } @@ -748,8 +745,8 @@ numeric.mapreducers = { ' else '+codeeq('x','y')+'\n'+ '}\nreturn x;\n'); numeric[o] = numeric[i]; - numeric[i+'eqV'] = numeric.pointwiseVV(['ret','x'], codeeq('ret[i]','x[j]'),setup,true); - numeric[i+'eqS'] = numeric.pointwiseVS(['ret','x'], codeeq('ret[i]','x' ),setup,true); + numeric[i+'eqV'] = numeric.pointwiseVV(['ret','x'],codeeq('ret[i]','x[j]'),setup,true); + numeric[i+'eqS'] = numeric.pointwiseVS(['ret','x'],codeeq('ret[i]','x' ),setup,true); numeric[i+'eq'] = Function( 'var n = arguments.length, i, x = arguments[0], y;\n'+ 'var V = numeric.'+i+'eqV, S = numeric.'+i+'eqS\n'+ @@ -852,7 +849,6 @@ numeric._slice = function _slice(x,s) { } numeric.slice = function slice(x,s,k) { - if(typeof k === 'undefined') { k=0; } if(typeof s !== 'object') { return numeric.slice(x,[s],0); } if(k === s.length-1) { return numeric._slice(x,s[k]); } @@ -872,16 +868,57 @@ numeric.slice = function slice(x,s,k) { } } +numeric._sliceeq = function _sliceeq(x,y,s) { + if(typeof s === 'number') { x[s<0?x.length+s:s] = y; } + if(typeof s === 'string') { + var i,j,n=x.length,r=numeric.parseSlice(x, s); + for(i=r.start,j=0; ((r.step<0)?(i>r.stop):(i=0) && (ir.stop):(i=0) && (i Date: Mon, 22 Sep 2014 22:26:53 +0900 Subject: [PATCH 05/22] Updated user mapreduce and pointwise functions. Added various other new functions. --- documentation.html | 112 ++++++++++- src/documentation.html | 114 ++++++++++- src/numeric.js | 436 +++++++++++++++++++++-------------------- 3 files changed, 445 insertions(+), 217 deletions(-) diff --git a/documentation.html b/documentation.html index f2ba0ee..609d411 100644 --- a/documentation.html +++ b/documentation.html @@ -41,12 +41,15 @@
andPointwise x && y
andeqPointwise x &= y
anyOne or more of the components of x are true +
argminReturn the index of the minimum value in an Array +
argmaxReturn the index of the maximum value in an Array
asinArc-sine
atanArc-tangeant
atan2Arc-tangeant (two parameters)
bandPointwise x & y
benchBenchmarking routine
bnotBinary negation ~x +
boolConvert Array to boolean values
borBinary or x|y
bxorBinary xor x^y
ccsDimDimensions of sparse matrix @@ -60,6 +63,7 @@
ccsSparseConvert from full to sparse
ccsTSolveSolve upper/lower triangular system
ccs<op>Supported ops include: add/div/mul/geq/etc... +
clipClip an Arrays values to within some minimum and maximum
cLUCoordinate matrix LU decomposition
cLUsolveCoordinate matrix LU solve
cdelsqCoordinate matrix Laplacian @@ -67,6 +71,7 @@
ceilPointwise Math.ceil(x)
cgridCoordinate grid for cdelsq
cloneDeep copy of Array +
concat
cosPointwise Math.cos(x)
detDeterminant
diagCreate diagonal matrix @@ -81,6 +86,7 @@
FunctionDescription

dotMatrix-Matrix, Matrix-Vector and Vector-Matrix product +
dstack
eigEigenvalues and eigenvectors
epsilon2.220446049250313e-16
eqPointwise comparison x === y @@ -91,6 +97,7 @@
getBlockExtract a block from a matrix
getDiagGet the diagonal of a matrix
gtPointwise x>y +
hstack
identityIdentity matrix
imageURLEncode a matrix as an image URL
invMatrix inverse @@ -106,6 +113,9 @@
LUDense LU decomposition
LUsolveDense LU solve
mapreduceMake a pointwise map-reduce function +
meanThe mean value of an Array +
varianceThe variance of an Array +
stdThe standard deviation of an Array
modPointwise x%y
modeqPointwise x%=y
mulPointwise x*y @@ -152,9 +162,12 @@
Spline.diffDifferentiate the Spline
Spline.rootsFind all the roots of the Spline
sqrtPointwise Math.sqrt(x) +
stack
subPointwise x-y
subeqPointwise x-=y
sumSum all the entries of x +
supReturn the largest value in an Array +
infReturn the smallest value in an Array
svdSingular value decomposition
tCreate a tensor type T (may be complex-valued)
T.<numericfun>Supported <numericfun> are: abs, add, cos, diag, div, dot, exp, getBlock, getDiag, inv, log, mul, neg, norm2, setBlock, sin, sub, transpose @@ -175,6 +188,8 @@
transposeMatrix transpose
uncminUnconstrained optimization
versionVersion string for the numeric library +
vstack
when
xorPointwise x^y
xoreqPointwise x^=y
@@ -270,6 +285,7 @@

Numerical analysis in Javascript

Math Object functions

The Math object functions have also been adapted to work on Arrays as follows: +
 IN> numeric.exp([1,2]);
 OUT> [2.718,7.389]
@@ -302,6 +318,8 @@ 

Math Object functions

OUT> [1,1.414] IN> numeric.tan([1,2]) OUT> [1.557,-2.185] +IN> numeric.bool([1,4,0,-2]) +OUT> [true,true,false,true]
@@ -317,6 +335,7 @@

Utility functions

You can perform a deep comparison of Arrays using numeric.same(): +
 IN> numeric.same([1,2],[1,2])
 OUT> true
@@ -333,6 +352,7 @@ 

Utility functions

You can create a multidimensional Array from a given value using numeric.rep() +
 IN> numeric.rep([3],5)
 OUT> [5,5,5]
@@ -341,6 +361,15 @@ 

Utility functions

[0,0,0]]
+You can use the conditional ternary operator in a pointwise way with the numeric.when() function. + +
+IN> a = [5,2,3]; b = [1,7,3];
+    c = [1,1,1]; d = [2,2,2];
+    numeric.when(numeric.lt(a,b),c,d);
+OUT> [2,1,2]
+
+ You can loop over Arrays as you normally would. However, in order to quickly generate optimized loops, the numeric library provides a few efficient loop-generation mechanisms. For example, the numeric.mapreduce() function can be used to make a function that computes the sum of all the @@ -355,6 +384,7 @@

Utility functions

The functions numeric.any() and numeric.all() allow you to check whether any or all entries of an Array are boolean true values. +
 IN> numeric.any([false,true])
 OUT> true
@@ -370,7 +400,38 @@ 

Utility functions

OUT> false
+The functions numeric.inf() and numeric.sup() allow you to get the smallest and largest values +in an Array. You can also use the numeric.argmax() and numeric.argmin() functions to get the +indices of these values. + +
+IN> numeric.inf([5.2,6.1,2.8,1.3])
+OUT> 1.3
+IN> numeric.sup([5.2,6.1,2.8,1.3])
+OUT> 6.1
+IN> numeric.argmax([5.2,6.1,2.8,1.3])
+OUT> 1
+IN> numeric.argmin([5.2,6.1,2.8,1.3])
+OUT> 3
+
+ +These mapreduce functions can all be given an optional argument specifying the axis upon which to do the reduction. +If a negative index is given it will be used as an offset from the innermost axis. + +
+IN> numeric.sum([[1,2],[3,4],[5,6]], 0)
+OUT> [9,12]
+IN> numeric.sum([[1,2],[3,4],[5,6]], 1)
+OUT> [3,7,11]
+IN> numeric.sum(
+  [[[1,2],[3,4]],
+   [[5,6],[7,8]]], -1)
+OUT> [[ 3, 7],
+      [11,15]]
+
+ You can create a diagonal matrix using numeric.diag() +
 IN> numeric.diag([1,2,3])
 OUT> [[1,0,0],
@@ -402,6 +463,17 @@ 

Utility functions

OUT> [1,1.5,2,2.5,3]
+Or via some range specifier: + +
+IN> numeric.range(0, 5);
+OUT> [0,1,2,3,4]
+IN> numeric.range(1, 3);
+OUT> [1,2]
+IN> numeric.range(-1, 6, 2);
+OUT> [-1, 1, 3, 5]
+
+ @@ -582,7 +632,8 @@

Arithmetic operations

Slicing

The slice command allows for accessing parts of numeric Arrays in more advanced ways. -In its most basic functionality you can pass in a list of indices for each dimension. + +It can be passed an Array of indices for each dimension.
 IN> numeric.slice([[1,2],[3,4],[5,6]], [2,0])
@@ -591,10 +642,10 @@ 

Slicing

OUT> [3,4]
-But rather than an integer you can also pass in it a slice string. This is -a string consisting of three number separated by colons start:stop:step -which tell the command to access the Array starting from some element index, stopping -at some element index, and performing some incrementing step size. +But inside this Array you can also pass in it a slice. This is +a string consisting of three numbers separated by colons start:stop:step +which tell the command to access the Array starting at some index, stopping +at some index, and performing some step size.
 IN> numeric.slice([0,1,2,3,4,5,6,7,8,9], [1+':'+7+':'+2])
@@ -603,10 +654,10 @@ 

Slicing

OUT> [1,1,26]
-The slice string is flexible. You can leave out the step section, or -omit actual numbers for the starting and stopping values, and defaults using the -start or end of the Array are assumed. Typically the string ':' is used -to specify that every element the axis be retrieved. +The string is flexible. You can leave out the step section, or +omit the starting and stopping values. In this case the slice starts at the +first element of the Array, and stops at the last. Therefore the string ':' +can be used to specify that every element on some axis be used.
 IN> numeric.slice([1,5,1,7,26], [1+':'+3])
@@ -621,9 +672,9 @@ 

Slicing

OUT> [2,4,6]
-Negative numbers can also be used as indices. These are assumed to be offsets from +Negative numbers can also be used. These are assumed to be offsets from the final element in the Array. So -1 can be used to mean the final element, --2 the second to last, etc. +-2 the second to last, and so on.
 IN> numeric.slice([0,1,2,3,4,5,6,7,8,9], [-1])
@@ -635,7 +686,8 @@ 

Slicing

The string '|' can be used to insert a new axis of a single element into -an Array. This is particularly useful when used in conjunction with broadcasting. +an Array. This is particularly useful when used in conjunction with broadcasting +(see below).
 IN> numeric.slice([0,1,2,3,4,5,6,7,8,9], ['|'])
@@ -650,9 +702,9 @@ 

Slicing

OUT> [10,1]
-The string '...' can be used as an argument for the first axis to specify -an access pattern from the right hand side. It corresponds to specifying ':' -for all axes such that the pattern has the same dimensions as the data. +The string '...' can be used in the position of the first axis to specify +an access pattern from the right hand side. It corresponds to using ':' +for all axes up until those specified.
 IN> numeric.slice([[0,1,2],[3,4,5],[6,7,8]], ['...',1])
@@ -663,28 +715,31 @@ 

Slicing

OUT> [[[1,2],[4,5],[7,8]]]
-As well as extracting data you can also set data using the sliceeq function. +As well as getting data you can also set data using the sliceeq function. It takes +as input an Array, a slice Array, and the new values to set. It then sets the values of the +Array in-place. + If you have previously extracted some data using a slice this can be useful for inserting it back into an Array.
-IN> v = [1,2,3,4]; numeric.sliceeq(v,[0,0],[':'+2]); v
+IN> v = [1,2,3,4]; numeric.sliceeq(v,[':'+2],[0,0]); v
 OUT> [0,0,3,4]
-IN> v = [[1,2],[3,4]]; numeric.sliceeq(v,10,[':',1]); v
+IN> v = [[1,2],[3,4]]; numeric.sliceeq(v,[':',1],10); v
 OUT> [[1,10],[3,10]]
 

Broadcasting

-When performing pointwise operations between two Arrays it is sometimes possible +When performing pointwise operations between Arrays it is sometimes possible to calculate a result when the dimensions don't exactly match. This behaviour is -called broadcast. It works as follows. First each Array is wrapped in -new Arrays of a single element until both are the same size. Then on any dimension -with just a single element, the single element in this dimension will be used as the -operand for all calculations along that axis. You can think of this value being -stretched or repeated so that it is matched against every element -in the other Array. +called broadcast. First each Array is wrapped in single element Arrays +until both have the same number of dimensions. Then when performing the operation, +on any dimension with just a single element, the single element in this dimension +will be used as the operand for all calculations along that axis. You can think of +this value as being stretched or repeated, such that it is matched +against every element in the other Array.
 IN> numeric.mul([[1,2],[3,4],[5,6]], [10,11])
@@ -704,8 +759,9 @@ 

Broadcasting

[[1,1],[2,2]]]
-This can be very useful. For example we can use the new axis '|' slice -object to efficiently compute a pairwise multiplication between two vectors. +This can be very useful when used with the new axis '|' slice +string. For example here we can efficiently compute a pairwise multiplication +between two vectors by inserting new single element axis.
 IN> numeric.mul(numeric.slice([1,2,3],[':','|']), numeric.slice([4,5,6],['|',':']))
@@ -714,13 +770,13 @@ 

Broadcasting

[12,15,18]]
-For more info see Numpy's +For more information about broadcasting see Numpy's broadcasting mechanics which numeric attempts to emulate.

Joining & Reshaping

-Arrays can be joined together using the numeric.concat() function. It takes as input -two arrays and the axis upon which to join them. +Arrays can be joined together using the numeric.concat() function. This +takes as input the two arrays to concatenate and the axis upon which to concatenate them.
 IN> numeric.concat([1,2],[3,4], 0)
@@ -731,10 +787,12 @@ 

Joining & Reshaping

OUT> [[1,2,5,6],[3,4,7,8]]
-If you want to join multiple Arrays you can use the numeric.stack() function which -takes a list of Arrays as input. Because concatenating on the innermost, second innermost -and third innermost axes are such common operations functions for these are provided as -numeric.hstack(), numeric.vstack() and numeric.dstack(). +If you want to concatenate multiple Arrays you can use the numeric.stack() function which +takes as input an Array of Arrays. + +Concatenating on the innermost, second innermost, and third innermost axes, is a very common operation, +so functions for these are provided as numeric.hstack(), numeric.vstack() and +numeric.dstack().
 IN> numeric.stack([[1,2],[3,4],[5,6]], 0)
@@ -754,7 +812,7 @@ 

Joining & Reshaping

Arrays can be reshaped to different dimensions using the numeric.reshape() function, -or they can be flattened into a single Array using the numeric.flatten() function. +and can be flattened into a single dimension Array using the numeric.flatten() function.
 IN> numeric.flatten([[1,2],[3,4],[5,6]])
@@ -771,11 +829,10 @@ 

Joining & Reshaping

Masking & Indexing

-Boolean Arrays can be used to mask off certain values in an Array. This is done -with the numeric.mask() and numeric.maskeq() functions. These masked -off values can either be returned using numeric.mask() or set using numeric.maskeq(). -Because masking doesn't ensure the shape of the Array will remain valid, the values are always -returned or set via a flattened array. +Boolean Arrays can be used to mask off certain values in an Array. This is done with the +numeric.mask() function. The first Array is matched against the second boolean Array and those +elements which are true in the boolean Array are returned. Because masking doesn't ensure the dimensions +of the Array will remain valid, the values are returned flattened.
 IN> a = [[1,5,3,4],[5,9,2,3]];
@@ -788,9 +845,9 @@ 

Masking & Indexing

You can set the values in an Array with a mask using numeric.maskeq(). This is useful in conjunction with numeric.mask() function because it allows -different operations to be performed for different parts of an Array given some -condition. For example we can use it to multiply by 10 all the numbers in an Array -that are less than 5. +different operations to be performed on different parts of an Array given some +condition. For example we can use it to multiply by 10 only when the numbers in the +Array are less than 5.
 IN> a = [[1,5,3,4],[5,9,2,3]];
@@ -801,8 +858,8 @@ 

Masking & Indexing

Arrays can also be used as indices to other Arrays. This is similar to specifying -multiple indices at once. It allows you to take or filter out specific elements -from an Array. To do this use the numeric.index() function. +multiple indices at once. It allows you to get specific elements from an Array at once. +To do this the numeric.index() function is used.
 IN> numeric.index([[1,2],[3,4],[5,6]],[0,2])
@@ -812,7 +869,7 @@ 

Masking & Indexing

To set values at specific indices you can use the numeric.indexeq() function. -This takes as input an Array, an Array of indices, and an Array of values, and sets +This takes as input an Array, an Array of indices, an Array of values, and sets the contents of the Array in-place.
diff --git a/src/numeric.js b/src/numeric.js
index 9b4b07e..b8bc0dd 100644
--- a/src/numeric.js
+++ b/src/numeric.js
@@ -886,7 +886,7 @@ numeric.slice = function slice(x,s,k) {
     }   
 }
 
-numeric._sliceeq = function _sliceeq(x,y,s) {
+numeric._sliceeq = function _sliceeq(x,s,y) {
     if(typeof s === 'number') { x[s<0?x.length+s:s] = y; }
     if(typeof s === 'string') {
         var i,j,n=x.length,r=numeric.parseSlice(x, s);
@@ -897,13 +897,13 @@ numeric._sliceeq = function _sliceeq(x,y,s) {
     }
 }
 
-numeric.sliceeq = function sliceeq(x,y,s,k) {
+numeric.sliceeq = function sliceeq(x,s,y,k) {
     if(typeof k === 'undefined') { k=0; }
-    if(typeof s !== 'object') { numeric.sliceeq(x,y,[s],0); }
-    if(k === s.length-1) { numeric._sliceeq(x,y,s[k]); }
+    if(typeof s !== 'object') { numeric.sliceeq(x,[s],y,0); }
+    if(k === s.length-1) { numeric._sliceeq(x,s[k],y); }
     
     if(typeof s[k] === 'number') {
-        numeric.sliceeq(x[s[k]<0?x.length+s[k]:s[k]],y,s,k+1);
+        numeric.sliceeq(x[s[k]<0?x.length+s[k]:s[k]],s,y,k+1);
     }
     
     if(typeof s[k] === 'string') {
@@ -911,14 +911,14 @@ numeric.sliceeq = function sliceeq(x,y,s,k) {
         if(s[k] === '...') {
             var i,n=numeric.dim(x).length-s.length+1; s=s.splice(1)
             for(var i=0;ir.stop):(i=0) && (i
Date: Fri, 3 Oct 2014 17:41:07 +0900
Subject: [PATCH 11/22] Updated documentation to be organized into sections

---
 src/documentation.html | 185 +++++++++++++++++++++--------------------
 1 file changed, 93 insertions(+), 92 deletions(-)

diff --git a/src/documentation.html b/src/documentation.html
index 73980ee..3b248db 100644
--- a/src/documentation.html
+++ b/src/documentation.html
@@ -34,84 +34,69 @@
 FunctionDescription
 
 
-addPointwise sum x+y -addeqPointwise sum x+=y -subPointwise x-y -subeqPointwise x-=y -mulPointwise x*y -muleqPointwise x*=y -divPointwise x/y -diveqPointwise x/=y -modPointwise x%y -modeqPointwise x%=y -lshiftPointwise x<<y -lshifteqPointwise x<<=y -rshiftPointwise x>>y -rshifteqPointwise x>>=y -rrshiftPointwise x>>>y -rrshifteqPointwise x>>>=y -powPointwise Math.pow(x, y) -negPointwise -x -absPointwise Math.abs(x) -expPointwise Math.exp(x) -logPointwise Math.log(x) -roundPointwise Math.round(x) -sqrtPointwise Math.sqrt(x) -ceilPointwise Math.ceil(x) -floorPoinwise Math.floor(x) -isFinitePointwise isFinite(x) -isNaNPointwise isNaN(x) -sinPointwise Math.sin(x) -cosPointwise Math.cos(x) -tanPointwise Math.tan(x) -asinPointwise Math.asin(x) -acosPointwise Math.acos(x) -atanPointwise Math.atan(x) -atan2Pointwise Math.atan2(x, y) -eqPointwise x===y -neqPointwise x!==y -ltPointwise x<y -leqPointwise x<=y -gtPointwise x>y -geqPointwise x>=y -boolPointwise !!x -notPointwise logical negation !x -andPointwise x&&y -andeqPointwise x&=y -orPointwise logical or x||y -oreqPointwise x|=y -xorPointwise x^y -xoreqPointwise x^=y -bandPointwise x & y -bnotPointwise binary negation ~x -borPointwise binary or x|y -bxorPointwise binary xor x^y -whenPointwise conditional operator x?y:z +addPointwise x+y +addeqPointwise x+=y +subPointwise x-y +subeqPointwise x-=y +mulPointwise x*y +muleqPointwise x*=y +divPointwise x/y +diveqPointwise x/=y +modPointwise x%y +modeqPointwise x%=y +lshiftPointwise x<<y +lshifteqPointwise x<<=y +rshiftPointwise x>>y +rshifteqPointwise x>>=y +rrshiftPointwise x>>>y +rrshifteqPointwise x>>>=y +powPointwise Math.pow(x,y) +negPointwise -x +absPointwise Math.abs(x) +expPointwise Math.exp(x) +logPointwise Math.log(x) +roundPointwise Math.round(x) +sqrtPointwise Math.sqrt(x) +ceilPointwise Math.ceil(x) +floorPoinwise Math.floor(x) +isFinitePointwise isFinite(x) +isNaNPointwise isNaN(x) +sinPointwise Math.sin(x) +cosPointwise Math.cos(x) +tanPointwise Math.tan(x) +asinPointwise Math.asin(x) +acosPointwise Math.acos(x) +atanPointwise Math.atan(x) +atan2Pointwise Math.atan2(x,y) +eqPointwise x===y +neqPointwise x!==y +ltPointwise x<y +leqPointwise x<=y +gtPointwise x>y +geqPointwise x>=y +boolPointwise !!x +notPointwise logical negation !x +andPointwise x&&y +andeqPointwise x&=y +orPointwise logical or x||y +oreqPointwise x|=y +xorPointwise x^y +xoreqPointwise x^=y +bandPointwise x&y +bnotPointwise binary negation ~x +borPointwise binary or x|y +bxorPointwise binary xor x^y +whenPointwise conditional operator x?y:z clipPointwise clip to some range -samex and y are entrywise identical +sameDeep comparison of x and y cloneDeep copy of Array -pointwiseCreate a new pointwise function +pointwiseConstruct a new pointwise function
FunctionDescription -

-
dimGet Array dimensions -
repCreate an Array by duplicating values -
zerosCreate an Array of zeros in a given shape -
onesCreate an Array of ones in a given shape -
rangeCreate an Array from a range -
linspaceGenerate evenly spaced values -
flattenFlatten Array to a single dimension -
reshapeReshape an Array to given dimensions -
concatConcatenate two Arrays together on a given axis -
stackConcatenate multiple Arrays together on a given axis -
hstackConcatenate multiple Arrays on their innermost axis -
vstackConcatenate multiple Arrays on their second innermost axis -
dstackConcatenate multiple Arrays on their third innermost axis -

sumThe sum of an Array
prodThe product of an Array @@ -119,19 +104,34 @@
supThe largest value of an Array
argminThe index of the smallest value of an Array
argmaxThe index of the largest value of an Array -
allAll the components of an Array are true -
anyAny of the components of an Array are true -
meanThe mean value of an Array +
allWhen all the components of an Array are true +
anyWhen any of the components of an Array are true +
meanThe mean of an Array
varianceThe variance of an Array
stdThe standard deviation of an Array
norm2Square root of the sum of the square of the entries of an Array
norm2SquaredSum of squares of entries of an Array
norminfLargest modulus entry of an Array -
mapreduceCreate a new map-reduce function +
mapreduceConstruct a new map-reduce function

-
sliceGet some slice of an Array -
sliceeqSet the values of some slice of an Array +
dimGet Array dimensions +
repCreate an Array by duplicating values +
zerosCreate an Array of zeros +
onesCreate an Array of ones +
rangeCreate an Array from a range +
linspaceGenerate evenly spaced values +
flattenFlatten Array to a single dimension +
reshapeReshape an Array to given dimensions +
concatConcatenate x and y together on a given axis +
stackConcatenate Arrays together on a given axis +
hstackConcatenate Arrays on their innermost axis +
vstackConcatenate Arrays on their second innermost axis +
dstackConcatenate Arrays on their third innermost axis + +

+
sliceGet a slice of an Array +
sliceeqSet the values of a slice of an Array
indexGet the values of an Array at a given Array of integer indices
indexeqSet the values of an Array at a given Array of integer indices
maskGet the values in an Array where a boolean Array is true @@ -146,52 +146,53 @@
diagCreate diagonal matrix
identityIdentity matrix
transposeMatrix transpose -
tensorTensor product z[i][j] = x[i]*y[j] -
solveSolve Ax=b +
tensorTensor product z[i][j] = x[i]*y[j] +
solveSolve Ax=b
solveLPSolve a linear programming problem
solveQPSolve a quadratic programming problem
LUDense LU decomposition
LUsolveDense LU solve
getDiagGet the diagonal of a matrix
setDiagSet the diagonal of a matrix -
getBlockExtract a block from a matrix +
getBlockGet a block from a matrix
setBlockSet a block of a matrix
FunctionDescription -

- -
randomCreate an Array of random numbers -
seedrandomThe seedrandom module

-
parseFloatPointwise parseFloat(x) -
parseDatePointwise parseDate(x) +
parseFloatPointwise parseFloat(x) +
parseDatePointwise parseDate(x)
parseCSVParse a CSV file into an Array
toCSVMake a CSV file
imageURLEncode a matrix as an image URL

+ +
randomCreate an Array of random numbers +
seedrandomThe seedrandom module + +

+
ccsSparseConvert from full to sparse +
ccsFullConvert sparse to full
ccsDimDimensions of sparse matrix
ccsDotSparse matrix-matrix product -
ccsFullConvert sparse to full
ccsGatherGather entries of sparse matrix -
ccsGetBlockGet rows/columns of sparse matrix -
ccsLUPCompute LUP decomposition of sparse matrix -
ccsLUPSolveSolve Ax=b using LUP decomp
ccsScatterScatter entries of sparse matrix -
ccsSparseConvert from full to sparse +
ccsLUPCompute LUP decomposition of sparse matrix +
ccsLUPSolveSolve Ax=b using LUP decomp
ccsTSolveSolve upper/lower triangular system +
ccsGetBlockGet rows/columns of sparse matrix
ccs<op>Supported ops include: add/div/mul/geq/etc...

+
cdotMVCoordinate matrix-vector product
cLUCoordinate matrix LU decomposition
cLUsolveCoordinate matrix LU solve -
cdelsqCoordinate matrix Laplacian -
cdotMVCoordinate matrix-vector product
cgridCoordinate grid for cdelsq +
cdelsqCoordinate matrix Laplacian

dopriNumerical integration of ODE using Dormand-Prince RK method. Returns an object Dopri. From 5a06c915aa666cfdfcab45dcb011bdc731172714 Mon Sep 17 00:00:00 2001 From: Daniel Holden Date: Fri, 3 Oct 2014 17:45:02 +0900 Subject: [PATCH 12/22] renamed argmin and argmax --- src/documentation.html | 11 ++++++----- src/numeric.js | 26 +++++++++++++------------- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/documentation.html b/src/documentation.html index 3b248db..d62c68f 100644 --- a/src/documentation.html +++ b/src/documentation.html @@ -102,13 +102,14 @@
prodThe product of an Array
infThe smallest value of an Array
supThe largest value of an Array -
argminThe index of the smallest value of an Array -
argmaxThe index of the largest value of an Array +
arginfThe index of the smallest value of an Array +
argsupThe index of the largest value of an Array
allWhen all the components of an Array are true
anyWhen any of the components of an Array are true
meanThe mean of an Array
varianceThe variance of an Array
stdThe standard deviation of an Array +
norm1Sum of the magnitudes of the entries of an Array
norm2Square root of the sum of the square of the entries of an Array
norm2SquaredSum of squares of entries of an Array
norminfLargest modulus entry of an Array @@ -433,7 +434,7 @@

Utility functions

The functions numeric.inf() and numeric.sup() allow you to get the smallest and largest values -in an Array. You can also use the numeric.argmax() and numeric.argmin() functions to get the +in an Array. You can also use the numeric.argsup() and numeric.arginf() functions to get the indices of these values.
@@ -441,9 +442,9 @@ 

Utility functions

OUT> 1.3 IN> numeric.sup([5.2,6.1,2.8,1.3]) OUT> 6.1 -IN> numeric.argmax([5.2,6.1,2.8,1.3]) +IN> numeric.argsup([5.2,6.1,2.8,1.3]) OUT> 1 -IN> numeric.argmin([5.2,6.1,2.8,1.3]) +IN> numeric.arginf([5.2,6.1,2.8,1.3]) OUT> 3
diff --git a/src/numeric.js b/src/numeric.js index b8bc0dd..65f20d8 100644 --- a/src/numeric.js +++ b/src/numeric.js @@ -792,22 +792,22 @@ numeric.reducers = { 'var z=numeric.zeros(s), add=numeric.add;'], prod: ['z=mul(z,x[i]);', 'var z=numeric.ones(s); mul=numeric.mul;'], - norm2Squared: ['z=add(z,pow(x[i],2));', - 'var z=numeric.zeros(s), add=numeric.add, pow=numeric.pow;'], - norminf: ['z=max(z,abs(x[i]));', - 'var z=numeric.zeros(s), max=numeric.max, abs=numeric.abs;'], + mean: ['z=add(z,div(x[i],n));', + 'var z=numeric.zeros(s), add=numeric.add, div=numeric.div;'], norm1: ['z=add(z,abs(x[i]))', 'var z=numeric.zeros(s), add=numeric.add, abs=numeric.abs;'], + norminf: ['z=max(z,abs(x[i]));', + 'var z=numeric.zeros(s), max=numeric.max, abs=numeric.abs;'], + norm2Squared: ['z=add(z,pow(x[i],2));', + 'var z=numeric.zeros(s), add=numeric.add, pow=numeric.pow;'], sup: ['z=max(z,x[i]);', 'var z=numeric.rep(s,-Infinity), max=numeric.max;'], inf: ['z=min(z,x[i]);', 'var z=numeric.rep(s,Infinity), min=numeric.min;'], - mean: ['z=add(z,div(x[i],n));', - 'var z=numeric.zeros(s), add=numeric.add, div=numeric.div;'], - argmin: ['z=when(lt(x[i],v),i,z),v=min(x[i],v);', + arginf: ['z=when(lt(x[i],v),i,z),v=min(x[i],v);', 'var z=numeric.zeros(s), v=numeric.rep(s,Infinity),'+ 'lt=numeric.lt, when=numeric.when, min=numeric.min'], - argmax: ['z=when(gt(x[i],v),i,z),v=max(x[i],v);', + argsup: ['z=when(gt(x[i],v),i,z),v=max(x[i],v);', 'var z=numeric.zeros(s), v=numeric.rep(s,-Infinity),'+ 'gt=numeric.gt, when=numeric.when, max=numeric.max'] }; @@ -832,7 +832,7 @@ numeric.std = function std(x, a) { return numeric.sqrt(numeric.variance(x, a)); } -numeric.parseSlice = function parseSlice(x,s) { +numeric._parseSlice = function _parseSlice(x,s) { var m= /^(-?\d+)?:(-?\d+)?(:(-?\d+))?$/.exec(s) var sp=(typeof m[4] !== 'undefined')?parseInt(m[4]):1; var r = { @@ -850,7 +850,7 @@ numeric._slice = function _slice(x,s) { if(s === ':') { return x; } if(typeof s === 'number') { return x[s<0?x.length+s:s]; } if(typeof s === 'string') { - var i,r=numeric.parseSlice(x, s),z=[]; + var i,r=numeric._parseSlice(x, s),z=[]; for(i=r.start; ((r.step<0)?(i>r.stop):(i=0) && (ir.stop):(i=0) && (ir.stop):(i=0) && (ir.stop):(i=0) && (i Date: Fri, 3 Oct 2014 17:47:35 +0900 Subject: [PATCH 13/22] Fixed bug with mean --- src/numeric.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/numeric.js b/src/numeric.js index 65f20d8..9dd5593 100644 --- a/src/numeric.js +++ b/src/numeric.js @@ -792,7 +792,7 @@ numeric.reducers = { 'var z=numeric.zeros(s), add=numeric.add;'], prod: ['z=mul(z,x[i]);', 'var z=numeric.ones(s); mul=numeric.mul;'], - mean: ['z=add(z,div(x[i],n));', + mean: ['z=add(z,div(x[i],_n));', 'var z=numeric.zeros(s), add=numeric.add, div=numeric.div;'], norm1: ['z=add(z,abs(x[i]))', 'var z=numeric.zeros(s), add=numeric.add, abs=numeric.abs;'], From d5aa2679c391f79f1588014a389ac1c8bdc9af51 Mon Sep 17 00:00:00 2001 From: Daniel Holden Date: Sat, 4 Oct 2014 12:39:52 +0100 Subject: [PATCH 14/22] More documentation updates and tweaks --- documentation.html | 536 ++++++++++++++++++++++++----------------- src/documentation.html | 4 +- src/numeric.js | 64 ++--- 3 files changed, 354 insertions(+), 250 deletions(-) diff --git a/documentation.html b/documentation.html index 19b97f1..c3e2c89 100644 --- a/documentation.html +++ b/documentation.html @@ -32,145 +32,183 @@
Join two Arrays together on a given axis -
FunctionDescription +

-
absAbsolute value -
acosArc-cosine -
addPointwise sum x+y -
addeqPointwise sum x+=y -
allAll the components of x are true -
andPointwise x && y -
andeqPointwise x &= y -
anyOne or more of the components of x are true -
argminReturn the index of the minimum value in an Array -
argmaxReturn the index of the maximum value in an Array -
asinArc-sine -
atanArc-tangeant -
atan2Arc-tangeant (two parameters) -
bandPointwise x & y -
benchBenchmarking routine -
bnotBinary negation ~x -
boolConvert Array to boolean values -
borBinary or x|y -
bxorBinary xor x^y -
ccsDimDimensions of sparse matrix -
ccsDotSparse matrix-matrix product -
ccsFullConvert sparse to full -
ccsGatherGather entries of sparse matrix -
ccsGetBlockGet rows/columns of sparse matrix -
ccsLUPCompute LUP decomposition of sparse matrix -
ccsLUPSolveSolve Ax=b using LUP decomp -
ccsScatterScatter entries of sparse matrix -
ccsSparseConvert from full to sparse -
ccsTSolveSolve upper/lower triangular system -
ccs<op>Supported ops include: add/div/mul/geq/etc... -
clipClip an Arrays values to within some minimum and maximum -
cLUCoordinate matrix LU decomposition -
cLUsolveCoordinate matrix LU solve -
cdelsqCoordinate matrix Laplacian -
cdotMVCoordinate matrix-vector product -
ceilPointwise Math.ceil(x) -
cgridCoordinate grid for cdelsq +
addPointwise x+y +
addeqPointwise x+=y +
subPointwise x-y +
subeqPointwise x-=y +
mulPointwise x*y +
muleqPointwise x*=y +
divPointwise x/y +
diveqPointwise x/=y +
modPointwise x%y +
modeqPointwise x%=y +
lshiftPointwise x<<y +
lshifteqPointwise x<<=y +
rshiftPointwise x>>y +
rshifteqPointwise x>>=y +
rrshiftPointwise x>>>y +
rrshifteqPointwise x>>>=y +
powPointwise Math.pow(x,y) +
negPointwise -x +
absPointwise Math.abs(x) +
expPointwise Math.exp(x) +
logPointwise Math.log(x) +
roundPointwise Math.round(x) +
sqrtPointwise Math.sqrt(x) +
ceilPointwise Math.ceil(x) +
floorPoinwise Math.floor(x) +
isFinitePointwise isFinite(x) +
isNaNPointwise isNaN(x) +
sinPointwise Math.sin(x) +
cosPointwise Math.cos(x) +
tanPointwise Math.tan(x) +
asinPointwise Math.asin(x) +
acosPointwise Math.acos(x) +
atanPointwise Math.atan(x) +
atan2Pointwise Math.atan2(x,y) +
eqPointwise x===y +
neqPointwise x!==y +
ltPointwise x<y +
leqPointwise x<=y +
gtPointwise x>y +
geqPointwise x>=y +
boolPointwise !!x +
notPointwise logical negation !x +
andPointwise x&&y +
andeqPointwise x&=y +
orPointwise logical or x||y +
oreqPointwise x|=y +
xorPointwise x^y +
xoreqPointwise x^=y +
bandPointwise x&y +
bnotPointwise binary negation ~x +
borPointwise binary or x|y +
bxorPointwise binary xor x^y +
whenPointwise conditional operator x?y:z +
clipPointwise clip to some range +
sameDeep comparison of x and y
cloneDeep copy of Array -
concat
cosPointwise Math.cos(x) -
detDeterminant -
diagCreate diagonal matrix -
dimGet Array dimensions -
divPointwise x/y -
diveqPointwise x/=y -
dopriNumerical integration of ODE using Dormand-Prince RK method. Returns an object Dopri. -
Dopri.atEvaluate the ODE solution at a point +
pointwiseConstruct a new pointwise function +
Join a list of Arrays together on their third innermost axis +Join a list of Arrays together on their innermost axis -
FunctionDescription + +

+
sumThe sum of an Array +
prodThe product of an Array +
infThe smallest value of an Array +
supThe largest value of an Array +
arginfThe index of the smallest value of an Array +
argsupThe index of the largest value of an Array +
allWhen all the components of an Array are true +
anyWhen any of the components of an Array are true +
meanThe mean of an Array +
varianceThe variance of an Array +
stdThe standard deviation of an Array +
norm1Sum of the magnitudes of an Array +
norm2Square root of the sum of the squares of an Array +
norm2SquaredSum of squares of entries of an Array +
norminfLargest modulus entry of an Array +
mapreduceConstruct a new map-reduce function + +

+
dimGet Array dimensions +
repCreate an Array by duplicating values +
zerosCreate an Array of zeros +
onesCreate an Array of ones +
rangeCreate an Array from a range +
linspaceGenerate evenly spaced values +
flattenFlatten Array to a single dimension +
reshapeReshape an Array to given dimensions +
concatConcatenate x and y together on a given axis +
stackConcatenate Arrays together on a given axis +
hstackConcatenate Arrays on their innermost axis +
vstackConcatenate Arrays on their second innermost axis +
dstackConcatenate Arrays on their third innermost axis + +

+
sliceGet a slice of an Array +
sliceeqSet the values of a slice of an Array +
indexGet the values of an Array at a given Array of integer indices +
indexeqSet the values of an Array at a given Array of integer indices +
maskGet the values in an Array where a boolean Array is true +
maskeqSet the values in an Array where a boolean Array is true +

dotMatrix-Matrix, Matrix-Vector and Vector-Matrix product -
dstack
detDeterminant
eigEigenvalues and eigenvectors -
epsilon2.220446049250313e-16 -
eqPointwise comparison x === y -
expPointwise Math.exp(x) -
flattenFlatten an Array into a single dimension -
floorPoinwise Math.floor(x) -
geqPointwise x>=y -
getBlockExtract a block from a matrix -
getDiagGet the diagonal of a matrix -
gtPointwise x>y -
hstack
identityIdentity matrix -
imageURLEncode a matrix as an image URL
invMatrix inverse -
isFinitePointwise isFinite(x) -
isNaNPointwise isNaN(x) -
largeArrayDon't prettyPrint Arrays larger than this -
leqPointwise x<=y -
linspaceGenerate evenly spaced values -
logPointwise Math.log(x) -
lshiftPointwise x<<y -
lshifteqPointwise x<<=y -
ltPointwise x<y +
svdSingular value decomposition +
diagCreate diagonal matrix +
identityIdentity matrix +
transposeMatrix transpose +
tensorTensor product z[i][j] = x[i]*y[j] +
solveSolve Ax=b +
solveLPSolve a linear programming problem +
solveQPSolve a quadratic programming problem
LUDense LU decomposition
LUsolveDense LU solve -
mapreduceMake a pointwise map-reduce function -
meanThe mean value of an Array -
varianceThe variance of an Array -
stdThe standard deviation of an Array -
modPointwise x%y -
modeqPointwise x%=y -
mulPointwise x*y -
negPointwise -x -
neqPointwise x!==y -
norm2Square root of the sum of the square of the entries of x -
norm2SquaredSum of squares of entries of x -
norminfLargest modulus entry of x -
notPointwise logical negation !x -
orPointwise logical or x||y -
oreqPointwise x|=y -
parseCSVParse a CSV file into an Array -
parseDatePointwise parseDate(x) -
parseFloatPointwise parseFloat(x) -
pointwiseCreate a pointwise function -
powPointwise Math.pow(x) -
precisionNumber of digits to prettyPrint -
prettyPrintPretty-prints x -
prodTake the product all the entries of x -
randomCreate an Array of random numbers -
rangeCreate an Array from a range -
repCreate an Array by duplicating values -
reshapeReshape an Array to given dimensions +
getDiagGet the diagonal of a matrix +
setDiagSet the diagonal of a matrix +
getBlockGet a block from a matrix +
setBlockSet a block of a matrix +
Join a list of Arrays together on a given axis -Join a list of Arrays together on their second innermost axis -Given three Arrays take elements from either the second, or third array, given the boolean value of the elements of the first. -
FunctionDescription + +

+
parseFloatPointwise parseFloat(x) +
parseDatePointwise parseDate(x) +
parseCSVParse a CSV file into an Array +
toCSVMake a CSV file +
imageURLEncode a matrix as an image URL +

-
roundPointwise Math.round(x) -
rrshiftPointwise x>>>y -
rrshifteqPointwise x>>>=y -
rshiftPointwise x>>y -
rshifteqPointwise x>>=y -
samex and y are entrywise identical + +
randomCreate an Array of random numbers
seedrandomThe seedrandom module -
setDiagSet the diagonal of a matrix -
setBlockSet a block of a matrix -
sinPointwise Math.sin(x) -
sliceReturn some range or indices of an Array -
sliceeqAssign values into some range or indices of an Array -
solveSolve Ax=b -
solveLPSolve a linear programming problem -
solveQPSolve a quadratic programming problem + +

+
ccsSparseConvert from full to sparse +
ccsFullConvert sparse to full +
ccsDimDimensions of sparse matrix +
ccsDotSparse matrix-matrix product +
ccsGatherGather entries of sparse matrix +
ccsScatterScatter entries of sparse matrix +
ccsLUPCompute LUP decomposition of sparse matrix +
ccsLUPSolveSolve Ax=b using LUP decomp +
ccsTSolveSolve upper/lower triangular system +
ccsGetBlockGet rows/columns of sparse matrix +
ccs<op>Supported ops include: add/div/mul/geq/etc... + +

+
cdotMVCoordinate matrix-vector product +
cLUCoordinate matrix LU decomposition +
cLUsolveCoordinate matrix LU solve +
cgridCoordinate grid for cdelsq +
cdelsqCoordinate matrix Laplacian + +

+
dopriNumerical integration of ODE using Dormand-Prince RK method. Returns an object Dopri. +
Dopri.atEvaluate the ODE solution at a point + +

+
uncminUnconstrained optimization + +

splineCreate a Spline object
Spline.atEvaluate the Spline at a point
Spline.diffDifferentiate the Spline
Spline.rootsFind all the roots of the Spline -
sqrtPointwise Math.sqrt(x) -
stack
subPointwise x-y -
subeqPointwise x-=y -
sumSum all the entries of x -
supReturn the largest value in an Array -
infReturn the smallest value in an Array -
svdSingular value decomposition + +

tCreate a tensor type T (may be complex-valued)
T.<numericfun>Supported <numericfun> are: abs, add, cos, diag, div, dot, exp, getBlock, getDiag, inv, log, mul, neg, norm2, setBlock, sin, sub, transpose
T.conjPointwise complex conjugate @@ -184,16 +222,15 @@
T.setRowSet a row
T.setRowsSet a range of rows
T.transjugateThe conjugate-transpose of a matrix -
tanPointwise Math.tan(x) -
tensorTensor product ret[i][j] = x[i]*y[j] -
toCSVMake a CSV file -
transposeMatrix transpose -
uncminUnconstrained optimization + +

versionVersion string for the numeric library -
vstack
when
xorPointwise x^y -
xoreqPointwise x^=y +
benchBenchmarking routine +
epsilon2.220446049250313e-16 +
prettyPrintPretty-prints x +
precisionNumber of digits to prettyPrint +
largeArrayDon't prettyPrint Arrays larger than this +

@@ -324,6 +361,14 @@

Math Object functions

OUT> [true,true,false,true]
+You can use the conditional ternary operator <cond> ? <then> : <else> with the numeric.when() function. + +
+IN> a = [5,2,3]; b = [1,7,3];
+    c = [1,1,1]; d = [2,2,2];
+    numeric.when(numeric.lt(a,b),c,d);
+OUT> [2,1,2]
+

Utility functions

@@ -353,7 +398,9 @@

Utility functions

OUT> false
-You can create a multidimensional Array from a given value using numeric.rep() +You can create a multidimensional Array from a given value using numeric.rep(), +or you create Arrays of zeros or ones using the functions numeric.zeros() and +numeric.ones.
 IN> numeric.rep([3],5)
@@ -361,29 +408,11 @@ 

Utility functions

IN> numeric.rep([2,3],0) OUT> [[0,0,0], [0,0,0]] -
- -You can use the conditional ternary operator in a pointwise way with the numeric.when() function. - -
-IN> a = [5,2,3]; b = [1,7,3];
-    c = [1,1,1]; d = [2,2,2];
-    numeric.when(numeric.lt(a,b),c,d);
-OUT> [2,1,2]
-
- -You can loop over Arrays as you normally would. However, in order to quickly generate optimized -loops, the numeric library provides a few efficient loop-generation mechanisms. For example, the -numeric.reducefunc() function can be used to make a function that computes the sum of all the -entries of an Array. - -
-IN> sum = numeric.reducefunc('z = numeric.add(z, x[i])','z = numeric.rep(s, 0);'); sum([1,2,3])
-OUT> 6
-IN> sum([[1,2,3],[4,5,6]])
-OUT> 21
-IN> sum([[1,2,3],[4,5,6]],0)
-OUT> [5,7,9]
+IN> numeric.zeros([2,2])
+OUT> [[0,0],
+      [0,0]]
+IN> numeric.ones([5,1])
+OUT> [[1],[1],[1],[1],[1]]
 
The functions numeric.any() and numeric.all() allow you to check whether any or all entries @@ -405,7 +434,7 @@

Utility functions

The functions numeric.inf() and numeric.sup() allow you to get the smallest and largest values -in an Array. You can also use the numeric.argmax() and numeric.argmin() functions to get the +in an Array. You can also use the numeric.argsup() and numeric.arginf() functions to get the indices of these values.
@@ -413,14 +442,15 @@ 

Utility functions

OUT> 1.3 IN> numeric.sup([5.2,6.1,2.8,1.3]) OUT> 6.1 -IN> numeric.argmax([5.2,6.1,2.8,1.3]) +IN> numeric.argsup([5.2,6.1,2.8,1.3]) OUT> 1 -IN> numeric.argmin([5.2,6.1,2.8,1.3]) +IN> numeric.arginf([5.2,6.1,2.8,1.3]) OUT> 3
-These mapreduce functions can all be given an optional argument specifying the axis upon which to do the reduction. -If a negative index is given it will be used as an offset from the innermost axis. +These functions can all be given an optional argument specifying the axis upon which to do the operation. +If a negative index is given it will be used as an offset from the innermost axis. When no axis is given +the operation is performed on a flattened version of the Array.
 IN> numeric.sum([[1,2],[3,4],[5,6]], 0)
@@ -434,6 +464,47 @@ 

Utility functions

[11,15]]
+You can loop over Arrays as you normally would. However, in order to generate optimized +code, the numeric library provides a few efficient loop-generation mechanisms. For +example, the numeric.mapreduce() function can be used to make a function that +computes the sum of all the entries of an Array. + +It must be provided with two strings. The first is the code to be peformed on each iteration. +It has access to the variables i and x representing the index and Array. +The second string is code to be performed as setup. It is used to construct the base case. +To correctly construct the base case, the s variable contains the dimensions of each +element in x. + +
+IN> sum = numeric.mapreduce('z = numeric.add(z, x[i])','var z = numeric.zeros(s);'); sum([1,2,3])
+OUT> 6
+IN> sum([[1,2,3],[4,5,6]])
+OUT> 21
+IN> sum([[1,2,3],[4,5,6]],0)
+OUT> [5,7,9]
+
+ +The best way to create new pointwise functions is to compose the existing ones, but if for any reason this +wont work you can use numeric.pointwise to generate efficient functions that act like the built-ins. +This ensures they will be fast, and allows them to be combined, composed, and broadcast in the same way. + +To do this you must specify some code acting on the variables x, y, z, +and the corresponding indices i, j, k. Where x and y are +the inputs, and z is the output. For in-place functions x should be assigned to rather than z. +Code for a setup function can also be given, and will be performed before looping. + +The final argument is the type of the pointwise function to generate. This can be either 'binary', +'binary-inplace', 'unary', or 'unary-inplace'. + +
+IN> adddouble = numeric.pointwise('z[k] = 2 * (x[i] + y[j])','','binary'); adddouble([1,2,3],[4,5,6])
+OUT> [10,14,18]
+IN> adddouble(5, [10,11,12])
+OUT> [30,32,34]
+IN> justdouble = numeric.pointwise('x[i] = 2 * x[i]','','unary-inplace'); v = [1,2,3]; justdouble(v); v;
+OUT> [2,4,6]
+
+ You can create a diagonal matrix using numeric.diag()
@@ -444,6 +515,7 @@ 

Utility functions

The function numeric.identity() returns the identity matrix. +
 IN> numeric.identity(3)
 OUT> [[1,0,0],
@@ -452,10 +524,11 @@ 

Utility functions

Random Arrays can also be created: -
+
+
 IN> numeric.random([2,3])
-OUT> [[0.05303,0.1537,0.7280],
-      [0.3839,0.08818,0.6316]]
+OUT> [[0.748,0.5187,0.5475],
+      [0.2482,0.8741,0.4344]]
 
You can generate a vector of evenly spaced values: @@ -493,6 +566,7 @@

Utility functions

Arithmetic operations

The standard arithmetic operations have been vectorized and are polymorphic: +
 IN> numeric.add([1,2],[3,4])
 OUT> [4,6]
@@ -505,6 +579,7 @@ 

Arithmetic operations

The other arithmetic operations are available: +
 IN> numeric.sub([1,2],[3,4])
 OUT> [-2,-2]
@@ -514,7 +589,10 @@ 

Arithmetic operations

OUT> [0.3333,0.5]
-The in-place operators (such as +=) are also available: +The in-place operators (such as +=) are also available, but a word of warning - +these will not work correctly on scalar values as the standard arithmetic operatiors +do because they cannot edit the value of a scalar in-place. +
 IN> v = [1,2,3,4]; numeric.addeq(v,3); v
 OUT> [4,5,6,7]
@@ -522,10 +600,13 @@ 

Arithmetic operations

OUT> [-4,-1,2]
-Unary operators: +Unary operators and their in-place versions are also provided. +
 IN> numeric.neg([1,-2,3])
 OUT> [-1,2,-3]
+IN> v = [4,5,6]; numeric.negeq(v); v
+OUT> [-4,-5,-6]
 IN> numeric.isFinite([10,NaN,Infinity])
 OUT> [true,false,false]
 IN> numeric.isNaN([10,NaN,Infinity])
@@ -535,26 +616,26 @@ 

Arithmetic operations

Slicing

-The slice command allows for accessing numeric Arrays in more advanced ways. -In its most basic functionality you can pass in a list of indices to access on -each dimension. +The slice command allows for accessing parts of numeric Arrays in more advanced ways. + +It can be passed an Array of indices for each dimension.
 IN> numeric.slice([[1,2],[3,4],[5,6]], [2,0])
@@ -563,10 +644,10 @@ 

Slicing

OUT> [3,4]
-But rather than an integer you can also pass in it a slice string. This is -a string consisting of three number separated by colons start:stop:step -which tell the command to access the Array starting from some element index, stopping -at some element index, and performing some incrementing step size. +But inside this Array you can also pass in it a slice. This is +a string consisting of three numbers separated by colons start:stop:step +which tell the command to access the Array starting at some index, stopping +at some index, and performing some step size.
 IN> numeric.slice([0,1,2,3,4,5,6,7,8,9], [1+':'+7+':'+2])
@@ -575,9 +656,10 @@ 

Slicing

OUT> [1,1,26]
-The slice string is flexible. You can leave out the step section, or -omit actual numbers for the starting and stopping values, and defaults using the -start or end of the Array are assumed. +The string is flexible. You can leave out the step section, or +omit the starting and stopping values. In this case the slice starts at the +first element of the Array, and stops at the last. Therefore the string ':' +can be used to specify that every element on some axis be used.
 IN> numeric.slice([1,5,1,7,26], [1+':'+3])
@@ -592,9 +674,9 @@ 

Slicing

OUT> [2,4,6]
-Negative numbers can also be used as indices. These are assumed to be offsets from +Negative numbers can also be used. These are assumed to be offsets from the final element in the Array. So -1 can be used to mean the final element, --2 the second to last, etc. +-2 the second to last, and so on.
 IN> numeric.slice([0,1,2,3,4,5,6,7,8,9], [-1])
@@ -606,7 +688,8 @@ 

Slicing

The string '|' can be used to insert a new axis of a single element into -an Array. This is particularly useful when used in conjunction with broadcasting. +an Array. This is particularly useful when used in conjunction with broadcasting +(see below).
 IN> numeric.slice([0,1,2,3,4,5,6,7,8,9], ['|'])
@@ -621,28 +704,44 @@ 

Slicing

OUT> [10,1]
-As well as extracting data you can also set data using the sliceeq function. +The string '...' can be used in the position of the first axis to specify +an access pattern from the right hand side. It corresponds to using ':' +for all axes up until those specified. + +
+IN> numeric.slice([[0,1,2],[3,4,5],[6,7,8]], ['...',1])
+OUT> [1,4,7]
+IN> numeric.slice([[[0,1],[2,3],[4,5],[6,7],[8,9]]], ['...',1])
+OUT> [[1,3,5,7,9]]
+IN> numeric.slice([[[0,1,2],[3,4,5],[6,7,8]]], ['...',1+':'])
+OUT> [[[1,2],[4,5],[7,8]]]
+
+ +As well as getting data you can also set data using the sliceeq function. It takes +as input an Array, a slice Array, and the new values to set. It then sets the values of the +Array in-place. + If you have previously extracted some data using a slice this can be useful for inserting it back into an Array.
-IN> v = [1,2,3,4]; numeric.sliceeq(v,[0,0],[':'+2]); v
+IN> v = [1,2,3,4]; numeric.sliceeq(v,[':'+2],[0,0]); v
 OUT> [0,0,3,4]
-IN> v = [[1,2],[3,4]]; numeric.sliceeq(v,10,[':',1]); v
+IN> v = [[1,2],[3,4]]; numeric.sliceeq(v,[':',1],10); v
 OUT> [[1,10],[3,10]]
 

Broadcasting

-When performing pointwise operations between two Arrays it is sometimes possible +When performing pointwise operations between Arrays it is sometimes possible to calculate a result when the dimensions don't exactly match. This behaviour is -called broadcast. It works as follows. First each Array is wrapped in -new Arrays of a single element until both are the same size. Then on any dimension -with just a single element, the single element in this dimension will be used as the -operand for all calculations along that axis. You can think of this value being -stretched or repeated so that it is matched against every element -in the other Array. +called broadcast. First each Array is wrapped in single element Arrays +until both have the same number of dimensions. Then when performing the operation, +on any dimension with just a single element, the single element in this dimension +will be used as the operand for all calculations along that axis. You can think of +this value as being stretched or repeated, such that it is matched +against every element in the other Array.
 IN> numeric.mul([[1,2],[3,4],[5,6]], [10,11])
@@ -662,8 +761,9 @@ 

Broadcasting

[[1,1],[2,2]]]
-This can be very useful. For example we can use the new axis '|' slice -object to efficiently compute a pairwise multiplication between two vectors. +This can be very useful when used with the new axis '|' slice +string. For example here we can efficiently compute a pairwise multiplication +between two vectors by inserting new single element axis.
 IN> numeric.mul(numeric.slice([1,2,3],[':','|']), numeric.slice([4,5,6],['|',':']))
@@ -672,15 +772,13 @@ 

Broadcasting

[12,15,18]]
-Unlike Numpy's -broadcasting mechanics for performance, unless a scalar is used, numeric does not -automatically align shapes on the right hand side. It is the user's responsibility to add -all the new axis which are required before broadcasting can work. +For more information about broadcasting see Numpy's +broadcasting mechanics which numeric attempts to emulate.

Joining & Reshaping

-Arrays can be joined together using the numeric.concat() function. It takes as input -two arrays and the axis upon which to join them. +Arrays can be joined together using the numeric.concat() function. This +takes as input the two arrays to concatenate and the axis upon which to concatenate them.
 IN> numeric.concat([1,2],[3,4], 0)
@@ -691,10 +789,12 @@ 

Joining & Reshaping

OUT> [[1,2,5,6],[3,4,7,8]]
-If you want to join multiple Arrays you can use the numeric.stack() function which -takes a list of Arrays as input. Because concatenating on the innermost, second innermost -and third innermost axes are such common operations functions for these are provided as -numeric.hstack(), numeric.vstack() and numeric.dstack(). +If you want to concatenate multiple Arrays you can use the numeric.stack() function which +takes as input an Array of Arrays. + +Concatenating on the innermost, second innermost, and third innermost axes, is a very common operation, +so functions for these are provided as numeric.hstack(), numeric.vstack() and +numeric.dstack().
 IN> numeric.stack([[1,2],[3,4],[5,6]], 0)
@@ -714,7 +814,7 @@ 

Joining & Reshaping

Arrays can be reshaped to different dimensions using the numeric.reshape() function, -or they can be flattened into a single Array using the numeric.flatten() function. +and can be flattened into a single dimension Array using the numeric.flatten() function.
 IN> numeric.flatten([[1,2],[3,4],[5,6]])
@@ -729,13 +829,12 @@ 

Joining & Reshaping

OUT> [2,3]
-

Masking

+

Masking & Indexing

-Boolean Arrays can be used to mask off certain values in an Array. This is done -with the numeric.mask() and numeric.maskeq() functions. These masked -off values can either be returned using numeric.mask() or set using numeric.maskeq(). -Because masking doesn't ensure the shape of the Array will remain valid, the values are always -returned or set via a flattened array. +Boolean Arrays can be used to mask off certain values in an Array. This is done with the +numeric.mask() function. The first Array is matched against the second boolean Array and those +elements which are true in the boolean Array are returned. Because masking doesn't ensure the dimensions +of the Array will remain valid, the values are returned flattened.
 IN> a = [[1,5,3,4],[5,9,2,3]];
@@ -748,9 +847,9 @@ 

Masking

You can set the values in an Array with a mask using numeric.maskeq(). This is useful in conjunction with numeric.mask() function because it allows -different operations to be performed for different parts of an Array given some -condition. For example we can use it to multiply by 10 all the numbers in an Array -that are less than 5. +different operations to be performed on different parts of an Array given some +condition. For example we can use it to multiply by 10 only when the numbers in the +Array are less than 5.
 IN> a = [[1,5,3,4],[5,9,2,3]];
@@ -760,10 +859,9 @@ 

Masking

OUT> [[10,5,30,40],[5,9,20,30]]
-

Array Indexing

- -Arrays can be used as indices to other Arrays. This is similar to specifying multiple -indices at once. +Arrays can also be used as indices to other Arrays. This is similar to specifying +multiple indices at once. It allows you to get specific elements from an Array at once. +To do this the numeric.index() function is used.
 IN> numeric.index([[1,2],[3,4],[5,6]],[0,2])
@@ -772,8 +870,14 @@ 

Array Indexing

OUT> [[1],[4],[6]]
+To set values at specific indices you can use the numeric.indexeq() function. +This takes as input an Array, an Array of indices, an Array of values, and sets +the contents of the Array in-place. - +
+IN> x = [[1,2],[3,4],[5,6]]; numeric.indexeq(x, [0,2], [[0,0],[2,2]]); x;
+OUT> [[0,0],[3,4],[2,2]]
+

Linear algebra

diff --git a/src/documentation.html b/src/documentation.html index d62c68f..c3e2c89 100644 --- a/src/documentation.html +++ b/src/documentation.html @@ -109,8 +109,8 @@ meanThe mean of an Array varianceThe variance of an Array stdThe standard deviation of an Array -norm1Sum of the magnitudes of the entries of an Array -norm2Square root of the sum of the square of the entries of an Array +norm1Sum of the magnitudes of an Array +norm2Square root of the sum of the squares of an Array norm2SquaredSum of squares of entries of an Array norminfLargest modulus entry of an Array mapreduceConstruct a new map-reduce function diff --git a/src/numeric.js b/src/numeric.js index 9dd5593..f6e62ef 100644 --- a/src/numeric.js +++ b/src/numeric.js @@ -545,7 +545,7 @@ numeric._broadcast = function expand(x, sx, sy) { return x; } -numeric.anonid = 0; +numeric.anonID = 0; numeric.pointwise = function pointwise(body, setup, type) { if (typeof body === 'undefined') { body = ''; } @@ -553,29 +553,29 @@ numeric.pointwise = function pointwise(body, setup, type) { if (typeof type === 'undefined') { type = 'binary'; } if (type === 'unary') { - numeric['_anonymous'+numeric.anonid] = numeric._unary(body, setup); + numeric['_anonymous'+numeric.anonID] = numeric._unary(body, setup); var fun = Function('x', 'if(typeof x !== "object") {\n'+ ' var i=0,k=0,z=Array(1);'+setup+';\n'+ ' x=[x];'+body+';\n'+ ' return z[0];'+ '} else {\n'+ - ' return numeric._foreach(x,numeric.dim(x),0,numeric._anonymous'+numeric.anonid+');\n'+ + ' return numeric._foreach(x,numeric.dim(x),0,numeric._anonymous'+numeric.anonID+');\n'+ '}'); } else if (type === 'unary-inplace') { - numeric['_anonymous'+numeric.anonid] = numeric._unaryeq(body, setup); + numeric['_anonymous'+numeric.anonID] = numeric._unaryeq(body, setup); var fun = Function('x', 'if(typeof x !== "object") {\n'+ ' throw new Error("numeric: Cannot perform in-place operation on number");\n'+ '} else {\n'+ - ' numeric._foreacheq(x,numeric.dim(x),0,numeric._anonymous'+numeric.anonid+');\n'+ + ' numeric._foreacheq(x,numeric.dim(x),0,numeric._anonymous'+numeric.anonID+');\n'+ '}'); } else if (type === 'binary') { - numeric['_anonymous'+numeric.anonid] = numeric._binary(body, setup); + numeric['_anonymous'+numeric.anonID] = numeric._binary(body, setup); var fun = Function( 'var a,n=arguments.length,x=arguments[0],y,dim=numeric.dim;\n'+ 'for(a=1;a Date: Tue, 7 Oct 2014 14:38:12 +0100 Subject: [PATCH 15/22] Changed indexing behaviour to match numpy. Second argument to range in now optional. Added mathematical constants. --- src/documentation.html | 7 ++++++- src/numeric.js | 37 +++++++++++++++++++++++-------------- 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/src/documentation.html b/src/documentation.html index c3e2c89..999d58a 100644 --- a/src/documentation.html +++ b/src/documentation.html @@ -88,6 +88,7 @@ bxorPointwise binary xor x^y whenPointwise conditional operator x?y:z clipPointwise clip to some range +saturatePointwise clip to the range [0,1] sameDeep comparison of x and y cloneDeep copy of Array pointwiseConstruct a new pointwise function @@ -227,6 +228,8 @@ versionVersion string for the numeric library benchBenchmarking routine epsilon2.220446049250313e-16 +pi3.14159265358979... +e2.71828182845904... prettyPrintPretty-prints x precisionNumber of digits to prettyPrint largeArrayDon't prettyPrint Arrays larger than this @@ -543,6 +546,8 @@

Utility functions

Or via some range specifier:
+IN> numeric.range(7);
+OUT> [0,1,2,3,4,5,6]
 IN> numeric.range(0, 5);
 OUT> [0,1,2,3,4]
 IN> numeric.range(1, 3);
@@ -867,7 +872,7 @@ 

Masking & Indexing

IN> numeric.index([[1,2],[3,4],[5,6]],[0,2]) OUT> [[1,2],[5,6]] IN> numeric.index([[1,2],[3,4],[5,6]],[[0],[1],[1]]) -OUT> [[1],[4],[6]] +OUT> [[[1,2]],[[3,4]],[[3,4]]]
To set values at specific indices you can use the numeric.indexeq() function. diff --git a/src/numeric.js b/src/numeric.js index f6e62ef..ce8d0e7 100644 --- a/src/numeric.js +++ b/src/numeric.js @@ -783,6 +783,10 @@ numeric.clip = function clip(x, min, max) { return numeric.min(numeric.max(x, min), max); } +numeric.saturate = function saturate(x) { + return numeric.clip(x, 0, 1); +} + numeric.reducers = { any: ['z = or(z, bool(x[i]));', 'var z=numeric.rep(s,false), or=numeric.or, bool=numeric.bool;'], @@ -966,24 +970,26 @@ numeric.index = function index(x,y,s,k) { if(typeof s === 'undefined') { s=numeric.dim(y); } if (k === s.length-1) { return numeric._index(x,y,s,k); } var i,n=s[k],z=Array(n); - for(i=n-1;i>=0;--i) { z[i]=numeric.index(x[i],y[i],s,k+1); } + for(i=n-1;i>=0;--i) { z[i]=numeric.index(x,y[i],s,k+1); } return z; } -numeric._indexeq = function _indexeq(x,y,z,sx,sy,k) { - var i,n=sx[k],m=sy[k]; - if (m === 0) { for(i=n-1;i>=0;--i) { x[y[0]] = numeric.clone(z[0]); } } - else { for(i=m-1;i>=0;--i) { x[y[i]] = numeric.clone(z[i]); } } +numeric._indexeq = function _indexeq(x,y,z,sy,sz,k) { + var i,n=sy[k],m=sz[k]; + if (n === 0) { for(i=m-1;i>=0;--i) { x[y[0]] = numeric.clone(z[i]); } } + if (m === 0) { for(i=n-1;i>=0;--i) { x[y[i]] = numeric.clone(z[0]); } } + else { for(i=n-1;i>=0;--i) { x[y[i]] = numeric.clone(z[i]); } } } -numeric.indexeq = function indexeq(x,y,z,sx,sy,k) { +numeric.indexeq = function indexeq(x,y,z,sy,sz,k) { if(typeof k === 'undefined') { k=0; } - if(typeof sx === 'undefined') { sx=numeric.dim(x); } if(typeof sy === 'undefined') { sy=numeric.dim(y); } - if (k === sy.length-1) { numeric._indexeq(x,y,z,sx,sy,k); } - var i,n=sx[k],m=sy[k]; - if (m === 0) { for(i=n-1;i>=0;--i) { numeric.indexeq(x[i],y[0],z[0],sx,sy,k+1); } } - else { for(i=m-1;i>=0;--i) { numeric.indexeq(x[i],y[i],z[i],sx,sy,k+1); } } + if(typeof sz === 'undefined') { sz=numeric.dim(z); } + if (k === sy.length-1) { numeric._indexeq(x,y,z,sy,sz,k); } + var i,n=sy[k],m=sz[k]; + if (n === 0) { for(i=m-1;i>=0;--i) { numeric.indexeq(x,y[0],z[i],sy,sz,k+1); } } + if (m === 0) { for(i=n-1;i>=0;--i) { numeric.indexeq(x,y[i],z[0],sy,sz,k+1); } } + else { for(i=n-1;i>=0;--i) { numeric.indexeq(x,y[i],z[i],sy,sz,k+1); } } } numeric.trunc = numeric.pointwise('z[k] = round(x[i]/y[j])*y[j];','var round = Math.round;','binary'); @@ -1125,7 +1131,8 @@ numeric.linspace = function linspace(a,b,n) { } numeric.range = function range(start,stop,step) { - step=(typeof step === 'undefined')?1:step; + if (typeof step === 'undefined') { step = 1; } + if (typeof stop === 'undefined') { stop = start; start = 0; } if (step > 0 && (stop < start)) { return []; } if (step < 0 && (stop > start)) { return []; } var i,z=[]; @@ -1592,6 +1599,8 @@ numeric.toUpperHessenberg = function toUpperHessenberg(me) { } numeric.epsilon = 2.220446049250313e-16; +numeric.pi = 3.141592653589793238462643383279502884197169399375105820; +numeric.e = 2.71828182845904523536028747135266249775724709369995; numeric.QRFrancis = function(H,maxiter) { if(typeof maxiter === "undefined") { maxiter = 10000; } @@ -2885,7 +2894,7 @@ numeric.T.prototype.fft = function fft() { var n = x.length, log = Math.log, log2 = log(2), p = Math.ceil(log(2*n-1)/log2), m = Math.pow(2,p); var cx = numeric.rep([m],0), cy = numeric.rep([m],0), cos = Math.cos, sin = Math.sin; - var k, c = (-3.141592653589793238462643383279502884197169399375105820/n),t; + var k, c = (-numeric.pi/n),t; var a = numeric.rep([m],0), b = numeric.rep([m],0),nhalf = Math.floor(n/2); for(k=0;k Date: Fri, 10 Oct 2014 13:25:14 +0100 Subject: [PATCH 16/22] Fixed bugs in CSV parsing/writing --- src/numeric.js | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/numeric.js b/src/numeric.js index ce8d0e7..17944f6 100644 --- a/src/numeric.js +++ b/src/numeric.js @@ -129,29 +129,30 @@ numeric.parseCSV = function parseCSV(t) { var stripper = function(n) { return n.substr(0,n.length-1); } var count = 0; for(k=0;k0) { - ret[count] = []; - for(j=0;j0) { + ret[count] = []; + for(j=0;j Date: Fri, 10 Oct 2014 15:08:06 +0100 Subject: [PATCH 17/22] For some bizarre reason using the variable _n here causes a huge slowdown in numeric.abs on the benchmark... --- src/numeric.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/numeric.js b/src/numeric.js index 17944f6..2eab0bf 100644 --- a/src/numeric.js +++ b/src/numeric.js @@ -797,7 +797,7 @@ numeric.reducers = { 'var z=numeric.zeros(s), add=numeric.add;'], prod: ['z=mul(z,x[i]);', 'var z=numeric.ones(s), mul=numeric.mul;'], - mean: ['z=add(z,div(x[i],_n));', + mean: ['z=add(z,div(x[i],x.length));', 'var z=numeric.zeros(s), add=numeric.add, div=numeric.div;'], norm1: ['z=add(z,abs(x[i]))', 'var z=numeric.zeros(s), add=numeric.add, abs=numeric.abs;'], From 824a375ad5d9927f5484303fc648f5ee511ad440 Mon Sep 17 00:00:00 2001 From: Daniel Holden Date: Fri, 10 Oct 2014 15:08:21 +0100 Subject: [PATCH 18/22] built documentation --- documentation.html | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/documentation.html b/documentation.html index c3e2c89..999d58a 100644 --- a/documentation.html +++ b/documentation.html @@ -88,6 +88,7 @@ bxorPointwise binary xor x^y whenPointwise conditional operator x?y:z clipPointwise clip to some range +saturatePointwise clip to the range [0,1] sameDeep comparison of x and y cloneDeep copy of Array pointwiseConstruct a new pointwise function @@ -227,6 +228,8 @@ versionVersion string for the numeric library benchBenchmarking routine epsilon2.220446049250313e-16 +pi3.14159265358979... +e2.71828182845904... prettyPrintPretty-prints x precisionNumber of digits to prettyPrint largeArrayDon't prettyPrint Arrays larger than this @@ -543,6 +546,8 @@

Utility functions

Or via some range specifier:
+IN> numeric.range(7);
+OUT> [0,1,2,3,4,5,6]
 IN> numeric.range(0, 5);
 OUT> [0,1,2,3,4]
 IN> numeric.range(1, 3);
@@ -867,7 +872,7 @@ 

Masking & Indexing

IN> numeric.index([[1,2],[3,4],[5,6]],[0,2]) OUT> [[1,2],[5,6]] IN> numeric.index([[1,2],[3,4],[5,6]],[[0],[1],[1]]) -OUT> [[1],[4],[6]] +OUT> [[[1,2]],[[3,4]],[[3,4]]]
To set values at specific indices you can use the numeric.indexeq() function. From 0569966d2bdec766d3fc729a47b8b481ea794902 Mon Sep 17 00:00:00 2001 From: Daniel Holden Date: Sun, 19 Oct 2014 12:00:23 +0100 Subject: [PATCH 19/22] Fixed bug with mapreduce functions when passes scalar values. Added inner and outer products. Fixed bug with index function. Removed debug output from csv parser. --- documentation.html | 17 +++++++++++++++++ src/documentation.html | 17 +++++++++++++++++ src/numeric.js | 31 ++++++++++++++++++++++++++++--- 3 files changed, 62 insertions(+), 3 deletions(-) diff --git a/documentation.html b/documentation.html index 999d58a..ff91fdd 100644 --- a/documentation.html +++ b/documentation.html @@ -125,6 +125,7 @@ linspaceGenerate evenly spaced values flattenFlatten Array to a single dimension reshapeReshape an Array to given dimensions +wrapWrap an Array on a given axis concatConcatenate x and y together on a given axis stackConcatenate Arrays together on a given axis hstackConcatenate Arrays on their innermost axis @@ -148,6 +149,8 @@ diagCreate diagonal matrix identityIdentity matrix transposeMatrix transpose +innerInner product of two Arrays +outerOuter product of two Arrays tensorTensor product z[i][j] = x[i]*y[j] solveSolve Ax=b solveLPSolve a linear programming problem @@ -834,6 +837,20 @@

Joining & Reshaping

OUT> [2,3]
+Elements in an Array can be wrapped with a new Array using the numeric.wrap() function. +An optional axis argument can be given to say upon which axis to do the wrapping. + +
+IN> numeric.wrap([1,2,3,4])
+OUT> [[1],[2],[3],[4]]
+IN> numeric.wrap([[1,2],[3,4],[5,6]])
+OUT> [[[1],[2]],[[3],[4]],[[5],[6]]]
+IN> numeric.wrap([1,2,3,4], 0)
+OUT> [[1,2,3,4]]
+IN> numeric.wrap([[1,2],[3,4],[5,6]], 1)
+OUT> [[[1,2]],[[3,4]],[[5,6]]]
+
+

Masking & Indexing

Boolean Arrays can be used to mask off certain values in an Array. This is done with the diff --git a/src/documentation.html b/src/documentation.html index 999d58a..ff91fdd 100644 --- a/src/documentation.html +++ b/src/documentation.html @@ -125,6 +125,7 @@ linspaceGenerate evenly spaced values flattenFlatten Array to a single dimension reshapeReshape an Array to given dimensions +wrapWrap an Array on a given axis concatConcatenate x and y together on a given axis stackConcatenate Arrays together on a given axis hstackConcatenate Arrays on their innermost axis @@ -148,6 +149,8 @@ diagCreate diagonal matrix identityIdentity matrix transposeMatrix transpose +innerInner product of two Arrays +outerOuter product of two Arrays tensorTensor product z[i][j] = x[i]*y[j] solveSolve Ax=b solveLPSolve a linear programming problem @@ -834,6 +837,20 @@

Joining & Reshaping

OUT> [2,3]
+Elements in an Array can be wrapped with a new Array using the numeric.wrap() function. +An optional axis argument can be given to say upon which axis to do the wrapping. + +
+IN> numeric.wrap([1,2,3,4])
+OUT> [[1],[2],[3],[4]]
+IN> numeric.wrap([[1,2],[3,4],[5,6]])
+OUT> [[[1],[2]],[[3],[4]],[[5],[6]]]
+IN> numeric.wrap([1,2,3,4], 0)
+OUT> [[1,2,3,4]]
+IN> numeric.wrap([[1,2],[3,4],[5,6]], 1)
+OUT> [[[1,2]],[[3,4]],[[5,6]]]
+
+

Masking & Indexing

Boolean Arrays can be used to mask off certain values in an Array. This is done with the diff --git a/src/numeric.js b/src/numeric.js index 2eab0bf..b0fbd6e 100644 --- a/src/numeric.js +++ b/src/numeric.js @@ -139,7 +139,6 @@ numeric.parseCSV = function parseCSV(t) { ret[count][j] = parseFloat(baz); } else { ret[count][j] = baz; } - if (isNaN(ret[count][j])) { console.log('Warning: "'+baz+'"'); } } count++; } @@ -501,6 +500,18 @@ numeric.dot = function dot(x,y) { } } +numeric.outer = function outer(x, y) { + x = numeric.flatten(x); + y = numeric.flatten(y); + return numeric.dot(numeric.transpose([x]), [y]); +} + +numeric.inner = function inner(x, y) { + if(typeof x !== 'object') { return numeric.mul(x, y); } + if(typeof y !== 'object') { return numeric.mul(x, y); } + return numeric.sum(numeric.add(x, y), -1); +} + numeric.diag = function diag(d) { var i,i1,j,n = d.length, A = Array(n), Ai; for(i=n-1;i>=0;i--) { @@ -681,6 +692,7 @@ numeric._mapreduce = function _mapreduce(body,setup) { numeric.mapreduce = function mapreduce(body,setup) { numeric['_anonymous'+numeric.anonID] = numeric._mapreduce(body,setup) var fun = Function('x','a','s','k', + 'if(typeof x !== "object") { x = [x]; }\n'+ 'if(typeof a === "undefined") { x = numeric.flatten(x); a=0; }\n'+ 'if(typeof s === "undefined") { s = numeric.dim(x); }\n'+ 'if(typeof k === "undefined") { k = 0; }\n'+ @@ -928,6 +940,17 @@ numeric.sliceeq = function sliceeq(x,s,y,k) { } } +numeric.wrap = function wrap(x, a, s, k) { + if(typeof k === 'undefined') { k=0; } + if(typeof s === 'undefined') { s=numeric.dim(x); } + if(typeof a === 'undefined') { a=s.length; } + if(a < 0) { a = s.length+a; } + if(k === a) { return [numeric.clone(x)]; } + var i,n=s[k],z=Array(n); + for (i=n-1;i>=0;--i) { z[i] = wrap(x[i],a,s,k+1); } + return z; +} + numeric._mask = function _mask(x,m,s,k) { var i,n=s[k],z=[]; for(i=0;i Date: Mon, 20 Oct 2014 14:16:45 +0100 Subject: [PATCH 20/22] Added roll flip and kron functions --- documentation.html | 32 +++++++++++++++++++++++++ src/documentation.html | 32 +++++++++++++++++++++++++ src/numeric.js | 54 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 118 insertions(+) diff --git a/documentation.html b/documentation.html index ff91fdd..fb747a7 100644 --- a/documentation.html +++ b/documentation.html @@ -125,6 +125,11 @@ linspaceGenerate evenly spaced values flattenFlatten Array to a single dimension reshapeReshape an Array to given dimensions +flipFlip an Array on a given axis +fliplrFlip an Array on the innermost axis +flipudFlip an Array on the second innermost axis +rot90Rotate an Array 90 degrees counter clockwise +rollRoll an Array on a given axis wrapWrap an Array on a given axis concatConcatenate x and y together on a given axis stackConcatenate Arrays together on a given axis @@ -151,6 +156,7 @@ transposeMatrix transpose innerInner product of two Arrays outerOuter product of two Arrays +kronKronecker product of two matrices tensorTensor product z[i][j] = x[i]*y[j] solveSolve Ax=b solveLPSolve a linear programming problem @@ -837,6 +843,23 @@

Joining & Reshaping

OUT> [2,3]
+Arrays can be reversed using numeric.flip(), rotated using numeric.rot90(), and rolled using numeric.roll(). + +
+IN> numeric.flip([1,2,3,4])
+OUT> [4,3,2,1]
+IN> numeric.flip([[1,2],[3,4]], 0)
+OUT> [[3,4],[1,2]]
+IN> numeric.flip([[1,2],[3,4]], 1)
+OUT> [[2,1],[4,3]]
+IN> numeric.rot90([[1,2],[3,4]])
+OUT> [[2,4],[1,3]]
+IN> numeric.roll([1,2,3,4], 2)
+OUT> [3,4,1,2]
+IN> numeric.roll([[1,2],[3,4],[5,6]], 1, 0)
+OUT> [[5,6],[1,2],[3,4]]
+
+ Elements in an Array can be wrapped with a new Array using the numeric.wrap() function. An optional axis argument can be given to say upon which axis to do the wrapping. @@ -1004,6 +1027,15 @@

Linear algebra

[12]] +Kronecker product: +
+IN> numeric.kron([[1,0],[0,1]],[[1,2],[3,4]])
+OUT> [[1,2,0,0],
+      [3,4,0,0],
+      [0,0,1,2],
+      [0,0,3,4]]
+
+ You can compute the 2-norm of an Array, which is the square root of the sum of the squares of the entries.
 IN> numeric.norm2([1,2])
diff --git a/src/documentation.html b/src/documentation.html
index ff91fdd..fb747a7 100644
--- a/src/documentation.html
+++ b/src/documentation.html
@@ -125,6 +125,11 @@
 linspaceGenerate evenly spaced values
 flattenFlatten Array to a single dimension
 reshapeReshape an Array to given dimensions
+flipFlip an Array on a given axis
+fliplrFlip an Array on the innermost axis
+flipudFlip an Array on the second innermost axis
+rot90Rotate an Array 90 degrees counter clockwise
+rollRoll an Array on a given axis
 wrapWrap an Array on a given axis
 concatConcatenate x and y together on a given axis
 stackConcatenate Arrays together on a given axis
@@ -151,6 +156,7 @@
 transposeMatrix transpose
 innerInner product of two Arrays
 outerOuter product of two Arrays
+kronKronecker product of two matrices
 tensorTensor product z[i][j] = x[i]*y[j]
 solveSolve Ax=b
 solveLPSolve a linear programming problem
@@ -837,6 +843,23 @@ 

Joining & Reshaping

OUT> [2,3]
+Arrays can be reversed using numeric.flip(), rotated using numeric.rot90(), and rolled using numeric.roll(). + +
+IN> numeric.flip([1,2,3,4])
+OUT> [4,3,2,1]
+IN> numeric.flip([[1,2],[3,4]], 0)
+OUT> [[3,4],[1,2]]
+IN> numeric.flip([[1,2],[3,4]], 1)
+OUT> [[2,1],[4,3]]
+IN> numeric.rot90([[1,2],[3,4]])
+OUT> [[2,4],[1,3]]
+IN> numeric.roll([1,2,3,4], 2)
+OUT> [3,4,1,2]
+IN> numeric.roll([[1,2],[3,4],[5,6]], 1, 0)
+OUT> [[5,6],[1,2],[3,4]]
+
+ Elements in an Array can be wrapped with a new Array using the numeric.wrap() function. An optional axis argument can be given to say upon which axis to do the wrapping. @@ -1004,6 +1027,15 @@

Linear algebra

[12]] +Kronecker product: +
+IN> numeric.kron([[1,0],[0,1]],[[1,2],[3,4]])
+OUT> [[1,2,0,0],
+      [3,4,0,0],
+      [0,0,1,2],
+      [0,0,3,4]]
+
+ You can compute the 2-norm of an Array, which is the square root of the sum of the squares of the entries.
 IN> numeric.norm2([1,2])
diff --git a/src/numeric.js b/src/numeric.js
index b0fbd6e..9416b53 100644
--- a/src/numeric.js
+++ b/src/numeric.js
@@ -512,6 +512,60 @@ numeric.inner = function inner(x, y) {
     return numeric.sum(numeric.add(x, y), -1);
 }
 
+numeric.roll = function roll(x, r, a, s, k) {
+    if(typeof r === 'undefined') { r=1; }
+    if(typeof a === 'undefined') { a=-1; }
+    if(typeof s === 'undefined') { s=numeric.dim(x); }
+    if(typeof k === 'undefined') { k=0; }
+    if(a < 0) { a=s.length+a; }
+    if(k === a) { return x.slice(s[k]-r).concat(x.slice(0,s[k]-r)); }
+    var i,n=s[k],z=Array(n);
+    for(i=0;i=0;i--) {

From 01c0a521e771d442844cb0aa7ea582866457523d Mon Sep 17 00:00:00 2001
From: Daniel Holden 
Date: Mon, 20 Oct 2014 17:09:07 +0100
Subject: [PATCH 21/22] Added logspace and empty functions. Balanced cheat
 sheet documentation.

---
 documentation.html     | 40 +++++++++++++++++++++++++---------------
 src/documentation.html | 40 +++++++++++++++++++++++++---------------
 src/numeric.js         | 26 ++++++++++++++++++++------
 3 files changed, 70 insertions(+), 36 deletions(-)

diff --git a/documentation.html b/documentation.html
index fb747a7..27d8e10 100644
--- a/documentation.html
+++ b/documentation.html
@@ -93,16 +93,18 @@
 cloneDeep copy of Array
 pointwiseConstruct a new pointwise function
 
+
+sumThe sum of an Array +prodThe product of an Array +infThe smallest value of an Array +supThe largest value of an Array +
FunctionDescription

-
sumThe sum of an Array -
prodThe product of an Array -
infThe smallest value of an Array -
supThe largest value of an Array
arginfThe index of the smallest value of an Array
argsupThe index of the largest value of an Array
allWhen all the components of an Array are true @@ -118,11 +120,13 @@

dimGet Array dimensions +
emptyCreate an empty Array
repCreate an Array by duplicating values
zerosCreate an Array of zeros
onesCreate an Array of ones
rangeCreate an Array from a range
linspaceGenerate evenly spaced values +
logspaceGenerate logarithmically spaced values
flattenFlatten Array to a single dimension
reshapeReshape an Array to given dimensions
flipFlip an Array on a given axis @@ -131,11 +135,11 @@
rot90Rotate an Array 90 degrees counter clockwise
rollRoll an Array on a given axis
wrapWrap an Array on a given axis -
concatConcatenate x and y together on a given axis -
stackConcatenate Arrays together on a given axis -
hstackConcatenate Arrays on their innermost axis -
vstackConcatenate Arrays on their second innermost axis -
dstackConcatenate Arrays on their third innermost axis +
concatJoin x and y together on a given axis +
stackJoin Arrays together on a given axis +
hstackJoin Arrays on their innermost axis +
vstackJoin Arrays on their second innermost axis +
dstackJoin Arrays on their third innermost axis

sliceGet a slice of an Array @@ -163,16 +167,18 @@
solveQPSolve a quadratic programming problem
LUDense LU decomposition
LUsolveDense LU solve -
getDiagGet the diagonal of a matrix -
setDiagSet the diagonal of a matrix -
getBlockGet a block from a matrix -
setBlockSet a block of a matrix
FunctionDescription +

+
getDiagGet the diagonal of a matrix +
setDiagSet the diagonal of a matrix +
getBlockGet a block from a matrix +
setBlockSet a block of a matrix +

parseFloatPointwise parseFloat(x)
parseDatePointwise parseDate(x) @@ -412,7 +418,7 @@

Utility functions

You can create a multidimensional Array from a given value using numeric.rep(), or you create Arrays of zeros or ones using the functions numeric.zeros() and -numeric.ones. +numeric.ones(), and empty Arrays using numeric.empty().
 IN> numeric.rep([3],5)
@@ -425,6 +431,8 @@ 

Utility functions

[0,0]] IN> numeric.ones([5,1]) OUT> [[1],[1],[1],[1],[1]] +IN> numeric.empty([2,3]) +OUT> [[,,],[,,]]
The functions numeric.any() and numeric.all() allow you to check whether any or all entries @@ -543,13 +551,15 @@

Utility functions

[0.2482,0.8741,0.4344]] -You can generate a vector of evenly spaced values: +You can generate a vector of evenly or logarithmically spaced values:
 IN> numeric.linspace(1,5);
 OUT> [1,2,3,4,5]
 IN> numeric.linspace(1,3,5);
 OUT> [1,1.5,2,2.5,3]
+IN> numeric.logspace(1,3,5);
+OUT> [10,31.62,1e2,316.2,1e3]
 
Or via some range specifier: diff --git a/src/documentation.html b/src/documentation.html index fb747a7..27d8e10 100644 --- a/src/documentation.html +++ b/src/documentation.html @@ -93,16 +93,18 @@
cloneDeep copy of Array
pointwiseConstruct a new pointwise function +

+
sumThe sum of an Array +
prodThe product of an Array +
infThe smallest value of an Array +
supThe largest value of an Array +
FunctionDescription

-
sumThe sum of an Array -
prodThe product of an Array -
infThe smallest value of an Array -
supThe largest value of an Array
arginfThe index of the smallest value of an Array
argsupThe index of the largest value of an Array
allWhen all the components of an Array are true @@ -118,11 +120,13 @@

dimGet Array dimensions +
emptyCreate an empty Array
repCreate an Array by duplicating values
zerosCreate an Array of zeros
onesCreate an Array of ones
rangeCreate an Array from a range
linspaceGenerate evenly spaced values +
logspaceGenerate logarithmically spaced values
flattenFlatten Array to a single dimension
reshapeReshape an Array to given dimensions
flipFlip an Array on a given axis @@ -131,11 +135,11 @@
rot90Rotate an Array 90 degrees counter clockwise
rollRoll an Array on a given axis
wrapWrap an Array on a given axis -
concatConcatenate x and y together on a given axis -
stackConcatenate Arrays together on a given axis -
hstackConcatenate Arrays on their innermost axis -
vstackConcatenate Arrays on their second innermost axis -
dstackConcatenate Arrays on their third innermost axis +
concatJoin x and y together on a given axis +
stackJoin Arrays together on a given axis +
hstackJoin Arrays on their innermost axis +
vstackJoin Arrays on their second innermost axis +
dstackJoin Arrays on their third innermost axis

sliceGet a slice of an Array @@ -163,16 +167,18 @@
solveQPSolve a quadratic programming problem
LUDense LU decomposition
LUsolveDense LU solve -
getDiagGet the diagonal of a matrix -
setDiagSet the diagonal of a matrix -
getBlockGet a block from a matrix -
setBlockSet a block of a matrix
FunctionDescription +

+
getDiagGet the diagonal of a matrix +
setDiagSet the diagonal of a matrix +
getBlockGet a block from a matrix +
setBlockSet a block of a matrix +

parseFloatPointwise parseFloat(x)
parseDatePointwise parseDate(x) @@ -412,7 +418,7 @@

Utility functions

You can create a multidimensional Array from a given value using numeric.rep(), or you create Arrays of zeros or ones using the functions numeric.zeros() and -numeric.ones. +numeric.ones(), and empty Arrays using numeric.empty().
 IN> numeric.rep([3],5)
@@ -425,6 +431,8 @@ 

Utility functions

[0,0]] IN> numeric.ones([5,1]) OUT> [[1],[1],[1],[1],[1]] +IN> numeric.empty([2,3]) +OUT> [[,,],[,,]]
The functions numeric.any() and numeric.all() allow you to check whether any or all entries @@ -543,13 +551,15 @@

Utility functions

[0.2482,0.8741,0.4344]] -You can generate a vector of evenly spaced values: +You can generate a vector of evenly or logarithmically spaced values:
 IN> numeric.linspace(1,5);
 OUT> [1,2,3,4,5]
 IN> numeric.linspace(1,3,5);
 OUT> [1,1.5,2,2.5,3]
+IN> numeric.logspace(1,3,5);
+OUT> [10,31.62,1e2,316.2,1e3]
 
Or via some range specifier: diff --git a/src/numeric.js b/src/numeric.js index 9416b53..4476d19 100644 --- a/src/numeric.js +++ b/src/numeric.js @@ -384,17 +384,26 @@ numeric.same = function same(x,y) { return true; } +numeric.empty = function empty(s,k) { + if(typeof k === "undefined") { k=0; } + var n=s[k], z=Array(n), i; + if(s.length === 0) { return undefined; } + if(s.length-1 === k) { return z; } + for(i=n-1;i>=0;i--) { z[i] = numeric.empty(s,k+1); } + return z; +} + numeric.rep = function rep(s,v,k) { if(typeof k === "undefined") { k=0; } - var n = s[k], ret = Array(n), i; + var n=s[k], z=Array(n), i; if(s.length === 0) { return v; } if(s.length-1 === k) { - for(i=n-2;i>=0;i-=2) { ret[i+1] = v; ret[i] = v; } - if(i===-1) { ret[0] = v; } - return ret; + for(i=n-2;i>=0;i-=2) { z[i+1] = v; z[i] = v; } + if(i===-1) { z[0] = v; } + return z; } - for(i=n-1;i>=0;i--) { ret[i] = numeric.rep(s,v,k+1); } - return ret; + for(i=n-1;i>=0;i--) { z[i] = numeric.rep(s,v,k+1); } + return z; } numeric.zeros = function zeros(s) { return numeric.rep(s,0); } @@ -1210,6 +1219,11 @@ numeric.linspace = function linspace(a,b,n) { return z; } +numeric.logspace = function logspace(a,b,n,e) { + if(typeof e === 'undefined') { e=10; } + return numeric.pow(e, numeric.linspace(a,b,n)); +} + numeric.range = function range(start,stop,step) { if (typeof step === 'undefined') { step = 1; } if (typeof stop === 'undefined') { stop = start; start = 0; } From d4dd539c4a5b2adc5f77c2fb0d038ecd1d0aefd0 Mon Sep 17 00:00:00 2001 From: Martin von Gagern Date: Tue, 18 Nov 2014 10:58:33 +0100 Subject: [PATCH 22/22] Fix reciprocal of a complex number with zero imaginary part. --- documentation.html | 4 ++++ src/documentation.html | 4 ++++ src/numeric.js | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/documentation.html b/documentation.html index 9767498..80ac39a 100644 --- a/documentation.html +++ b/documentation.html @@ -638,6 +638,10 @@

Complex linear algebra

OUT> {x:0.5588,y:-0.2353} IN> z.sub(w) OUT> {x:1, y:-4} +IN> z.reciprocal() +OUT> {x: 0.12, y: -0.16} +IN> numeric.t(2, 0).reciprocal() +OUT> {x: 0.5, y: 0} Complex vectors and matrices can also be handled: diff --git a/src/documentation.html b/src/documentation.html index 9767498..80ac39a 100644 --- a/src/documentation.html +++ b/src/documentation.html @@ -638,6 +638,10 @@

Complex linear algebra

OUT> {x:0.5588,y:-0.2353} IN> z.sub(w) OUT> {x:1, y:-4} +IN> z.reciprocal() +OUT> {x: 0.12, y: -0.16} +IN> numeric.t(2, 0).reciprocal() +OUT> {x: 0.5, y: 0} Complex vectors and matrices can also be handled: diff --git a/src/numeric.js b/src/numeric.js index 537b68f..336f081 100644 --- a/src/numeric.js +++ b/src/numeric.js @@ -1071,7 +1071,7 @@ numeric.T.prototype.reciprocal = function reciprocal() { var d = numeric.add(mul(this.x,this.x),mul(this.y,this.y)); return new numeric.T(div(this.x,d),div(numeric.neg(this.y),d)); } - return new T(div(1,this.x)); + return new numeric.T(div(1,this.x), 0); } numeric.T.prototype.div = function div(y) { if(!(y instanceof numeric.T)) y = new numeric.T(y);