diff --git a/documentation.html b/documentation.html index 9767498..43ba773 100644 --- a/documentation.html +++ b/documentation.html @@ -32,125 +32,199 @@
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 -
asinArc-sine -
atanArc-tangeant -
atan2Arc-tangeant (two parameters) -
bandPointwise x & y -
benchBenchmarking routine -
bnotBinary negation ~x -
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... -
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 +
saturatePointwise clip to the range [0,1] +
sameDeep comparison of x and y
cloneDeep copy of Array -
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 + +

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

+
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 +
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 +
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 +
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 +
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 +
detDeterminant
eigEigenvalues and eigenvectors -
epsilon2.220446049250313e-16 -
eqPointwise comparison x === y -
expPointwise Math.exp(x) -
floorPoinwise Math.floor(x) -
geqPointwise x>=y -
getBlockExtract a block from a matrix -
getDiagGet the diagonal of a matrix -
gtPointwise x>y -
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 +
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 +
solveQPSolve a quadratic programming problem
LUDense LU decomposition
LUsolveDense LU solve -
mapreduceMake a pointwise map-reduce function -
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 -
randomCreate an Array of random numbers -
repCreate an Array by duplicating values +
FunctionDescription +

-
roundPointwise Math.round(x) -
rrshiftPointwise x>>>y -
rrshifteqPointwise x>>>=y -
rshiftPointwise x>>y -
rshifteqPointwise x>>=y -
samex and y are entrywise identical -
seedrandomThe seedrandom module +
getDiagGet the diagonal of a matrix +
setDiagSet the diagonal of a matrix +
getBlockGet a block from a matrix
setBlockSet a block of a matrix -
sinPointwise Math.sin(x) -
solveSolve Ax=b -
solveLPSolve a linear programming problem -
solveQPSolve a quadratic programming problem + +

+
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 +
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) -
subPointwise x-y -
subeqPointwise x-=y -
sumSum all the entries of x -
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 @@ -164,14 +238,17 @@
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 -
xorPointwise x^y -
xoreqPointwise x^=y +
benchBenchmarking routine +
epsilon2.220446049250313e-16 +
pi3.14159265358979... +
e2.71828182845904... +
prettyPrintPretty-prints x +
precisionNumber of digits to prettyPrint +
largeArrayDon't prettyPrint Arrays larger than this +

@@ -265,6 +342,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]
@@ -297,8 +375,18 @@ 

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]
+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

@@ -312,6 +400,7 @@

Utility functions

You can perform a deep comparison of Arrays using numeric.same(): +
 IN> numeric.same([1,2],[1,2])
 OUT> true
@@ -327,29 +416,28 @@ 

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(), and empty Arrays using numeric.empty(). +
 IN> numeric.rep([3],5)
 OUT> [5,5,5]
 IN> numeric.rep([2,3],0)
 OUT> [[0,0,0],
       [0,0,0]]
-
- -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 -entries of an Array. - -
-IN> sum = numeric.mapreduce('accum += xi','0'); sum([1,2,3])
-OUT> 6
-IN> sum([[1,2,3],[4,5,6]])
-OUT> 21
+IN> numeric.zeros([2,2])
+OUT> [[0,0],
+      [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 of an Array are boolean true values. +
 IN> numeric.any([false,true])
 OUT> true
@@ -365,7 +453,80 @@ 

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.argsup() and numeric.arginf() 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.argsup([5.2,6.1,2.8,1.3])
+OUT> 1
+IN> numeric.arginf([5.2,6.1,2.8,1.3])
+OUT> 3
+
+ +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)
+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 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() +
 IN> numeric.diag([1,2,3])
 OUT> [[1,0,0],
@@ -374,6 +535,7 @@ 

Utility functions

The function numeric.identity() returns the identity matrix. +
 IN> numeric.identity(3)
 OUT> [[1,0,0],
@@ -382,19 +544,35 @@ 

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: +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: + +
+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);
+OUT> [1,2]
+IN> numeric.range(-1, 6, 2);
+OUT> [-1, 1, 3, 5]
 
+

Slicing

+ +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])
+OUT> 5
+IN> numeric.slice([[1,2],[3,4],[5,6]], [1])
+OUT> [3,4]
+
+ +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])
+OUT> [1,3,5]
+IN> numeric.slice([1,5,1,7,26], [0+':'+5+':'+2])
+OUT> [1,1,26]
+
+ +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])
+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. 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, and so on. + +
+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 +(see below). + +
+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]
+
+ +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,[':'+2],[0,0]); v
+OUT> [0,0,3,4]
+IN> v = [[1,2],[3,4]]; numeric.sliceeq(v,[':',1],10); v
+OUT> [[1,10],[3,10]]
+
+ + +

Broadcasting

+ +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. 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])
+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 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],['|',':']))
+OUT> [[4,  5, 6],
+      [8, 10,12],
+      [12,15,18]]
+
+ +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. 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)
+OUT> [1,2,3,4]
+IN> numeric.concat([[1,2],[3,4]], [[5,6],[7,8]], 0)
+OUT> [[1,2],[3,4],[5,6],[7,8]]
+IN> numeric.concat([[1,2],[3,4]], [[5,6],[7,8]], 1)
+OUT> [[1,2,5,6],[3,4,7,8]]
+
+ +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)
+OUT> [1,2,3,4,5,6]
+IN> a = [[1,2],[3,4]];
+    b = [[5,6],[7,8]];
+    numeric.hstack([a,b])
+OUT> [[1,2,5,6],
+      [3,4,7,8]]
+IN> a = [[1,2],[3,4]];
+    b = [[5,6],[7,8]];
+    numeric.vstack([a,b])
+OUT> [[1,2],
+      [3,4],
+      [5,6],
+      [7,8]]
+
+ +Arrays can be reshaped to different dimensions using the numeric.reshape() function, +and can be flattened into a single dimension Array using the numeric.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]
+
+ +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. + +
+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 +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]];
+    numeric.mask(a, numeric.lt(a,5));
+OUT> [1,3,4,2,3]
+IN> a = [[1,5,3,4],[5,9,2,3]];
+    numeric.mask(a, numeric.gt(a,4));
+OUT> [5,5,9]
+
+ +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 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]];
+    m = numeric.lt(a,5);
+    b = numeric.mask(a, m);
+    numeric.maskeq(a,m,numeric.mul(b,10)); a;
+OUT> [[10,5,30,40],[5,9,20,30]]
+
+ +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])
+OUT> [[1,2],[5,6]]
+IN> numeric.index([[1,2],[3,4],[5,6]],[[0],[1],[1]])
+OUT> [[[1,2]],[[3,4]],[[3,4]]]
+
+ +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

@@ -577,6 +1037,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])
@@ -638,6 +1107,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..43ba773 100644 --- a/src/documentation.html +++ b/src/documentation.html @@ -32,125 +32,199 @@
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 -
asinArc-sine -
atanArc-tangeant -
atan2Arc-tangeant (two parameters) -
bandPointwise x & y -
benchBenchmarking routine -
bnotBinary negation ~x -
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... -
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 +
saturatePointwise clip to the range [0,1] +
sameDeep comparison of x and y
cloneDeep copy of Array -
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 + +

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

+
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 +
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 +
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 +
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 +
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 +
detDeterminant
eigEigenvalues and eigenvectors -
epsilon2.220446049250313e-16 -
eqPointwise comparison x === y -
expPointwise Math.exp(x) -
floorPoinwise Math.floor(x) -
geqPointwise x>=y -
getBlockExtract a block from a matrix -
getDiagGet the diagonal of a matrix -
gtPointwise x>y -
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 +
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 +
solveQPSolve a quadratic programming problem
LUDense LU decomposition
LUsolveDense LU solve -
mapreduceMake a pointwise map-reduce function -
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 -
randomCreate an Array of random numbers -
repCreate an Array by duplicating values +
FunctionDescription +

-
roundPointwise Math.round(x) -
rrshiftPointwise x>>>y -
rrshifteqPointwise x>>>=y -
rshiftPointwise x>>y -
rshifteqPointwise x>>=y -
samex and y are entrywise identical -
seedrandomThe seedrandom module +
getDiagGet the diagonal of a matrix +
setDiagSet the diagonal of a matrix +
getBlockGet a block from a matrix
setBlockSet a block of a matrix -
sinPointwise Math.sin(x) -
solveSolve Ax=b -
solveLPSolve a linear programming problem -
solveQPSolve a quadratic programming problem + +

+
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 +
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) -
subPointwise x-y -
subeqPointwise x-=y -
sumSum all the entries of x -
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 @@ -164,14 +238,17 @@
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 -
xorPointwise x^y -
xoreqPointwise x^=y +
benchBenchmarking routine +
epsilon2.220446049250313e-16 +
pi3.14159265358979... +
e2.71828182845904... +
prettyPrintPretty-prints x +
precisionNumber of digits to prettyPrint +
largeArrayDon't prettyPrint Arrays larger than this +

@@ -265,6 +342,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]
@@ -297,8 +375,18 @@ 

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]
+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

@@ -312,6 +400,7 @@

Utility functions

You can perform a deep comparison of Arrays using numeric.same(): +
 IN> numeric.same([1,2],[1,2])
 OUT> true
@@ -327,29 +416,28 @@ 

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(), and empty Arrays using numeric.empty(). +
 IN> numeric.rep([3],5)
 OUT> [5,5,5]
 IN> numeric.rep([2,3],0)
 OUT> [[0,0,0],
       [0,0,0]]
-
- -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 -entries of an Array. - -
-IN> sum = numeric.mapreduce('accum += xi','0'); sum([1,2,3])
-OUT> 6
-IN> sum([[1,2,3],[4,5,6]])
-OUT> 21
+IN> numeric.zeros([2,2])
+OUT> [[0,0],
+      [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 of an Array are boolean true values. +
 IN> numeric.any([false,true])
 OUT> true
@@ -365,7 +453,80 @@ 

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.argsup() and numeric.arginf() 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.argsup([5.2,6.1,2.8,1.3])
+OUT> 1
+IN> numeric.arginf([5.2,6.1,2.8,1.3])
+OUT> 3
+
+ +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)
+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 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() +
 IN> numeric.diag([1,2,3])
 OUT> [[1,0,0],
@@ -374,6 +535,7 @@ 

Utility functions

The function numeric.identity() returns the identity matrix. +
 IN> numeric.identity(3)
 OUT> [[1,0,0],
@@ -382,19 +544,35 @@ 

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: +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: + +
+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);
+OUT> [1,2]
+IN> numeric.range(-1, 6, 2);
+OUT> [-1, 1, 3, 5]
 
+

Slicing

+ +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])
+OUT> 5
+IN> numeric.slice([[1,2],[3,4],[5,6]], [1])
+OUT> [3,4]
+
+ +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])
+OUT> [1,3,5]
+IN> numeric.slice([1,5,1,7,26], [0+':'+5+':'+2])
+OUT> [1,1,26]
+
+ +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])
+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. 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, and so on. + +
+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 +(see below). + +
+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]
+
+ +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,[':'+2],[0,0]); v
+OUT> [0,0,3,4]
+IN> v = [[1,2],[3,4]]; numeric.sliceeq(v,[':',1],10); v
+OUT> [[1,10],[3,10]]
+
+ + +

Broadcasting

+ +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. 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])
+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 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],['|',':']))
+OUT> [[4,  5, 6],
+      [8, 10,12],
+      [12,15,18]]
+
+ +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. 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)
+OUT> [1,2,3,4]
+IN> numeric.concat([[1,2],[3,4]], [[5,6],[7,8]], 0)
+OUT> [[1,2],[3,4],[5,6],[7,8]]
+IN> numeric.concat([[1,2],[3,4]], [[5,6],[7,8]], 1)
+OUT> [[1,2,5,6],[3,4,7,8]]
+
+ +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)
+OUT> [1,2,3,4,5,6]
+IN> a = [[1,2],[3,4]];
+    b = [[5,6],[7,8]];
+    numeric.hstack([a,b])
+OUT> [[1,2,5,6],
+      [3,4,7,8]]
+IN> a = [[1,2],[3,4]];
+    b = [[5,6],[7,8]];
+    numeric.vstack([a,b])
+OUT> [[1,2],
+      [3,4],
+      [5,6],
+      [7,8]]
+
+ +Arrays can be reshaped to different dimensions using the numeric.reshape() function, +and can be flattened into a single dimension Array using the numeric.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]
+
+ +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. + +
+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 +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]];
+    numeric.mask(a, numeric.lt(a,5));
+OUT> [1,3,4,2,3]
+IN> a = [[1,5,3,4],[5,9,2,3]];
+    numeric.mask(a, numeric.gt(a,4));
+OUT> [5,5,9]
+
+ +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 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]];
+    m = numeric.lt(a,5);
+    b = numeric.mask(a, m);
+    numeric.maskeq(a,m,numeric.mul(b,10)); a;
+OUT> [[10,5,30,40],[5,9,20,30]]
+
+ +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])
+OUT> [[1,2],[5,6]]
+IN> numeric.index([[1,2],[3,4],[5,6]],[[0],[1],[1]])
+OUT> [[[1,2]],[[3,4]],[[3,4]]]
+
+ +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

@@ -577,6 +1037,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])
@@ -638,6 +1107,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..d0c8d42 100644 --- a/src/numeric.js +++ b/src/numeric.js @@ -29,6 +29,7 @@ numeric._myIndexOf = (function _myIndexOf(w) { for(k=0;k0) { - ret[count] = []; - for(j=0;j0) { + ret[count] = []; + for(j=0;j=0;i--) {\n'+ - ' accum = arguments.callee(x[i],accum,_s,_k+1);\n'+ - ' }'+ - ' return accum;\n'+ - '}\n'+ - 'for(i=_n-1;i>=1;i-=2) { \n'+ - ' xi = x[i];\n'+ - ' '+body+';\n'+ - ' xi = x[i-1];\n'+ - ' '+body+';\n'+ - '}\n'+ - 'if(i === 0) {\n'+ - ' xi = x[i];\n'+ - ' '+body+'\n'+ - '}\n'+ - 'return accum;' - ); +numeric.flatten = function flatten(x,s,k) { + if(typeof x !== 'object') { return x; } + if(typeof k === 'undefined') { k=0; } + if(typeof s === 'undefined') { s=numeric.dim(x); } + if(k === s.length-1) { return x; } + var i,n=x.length,z=[]; + for(i=0;i=0;--i) { z[i] = numeric.concat(x[i],y[i],a,s,k+1); } + return z; +} + +numeric.stack = function stack(xs,a) { + var i,x=xs[0],n=xs.length; + for (i=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; - if(k === s.length-1) { - for(i=n-2;i>=0;i-=2) { ret[i+1] = v; ret[i] = v; } - if(i===-1) { ret[0] = v; } - return ret; + 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) { 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); } +numeric.ones = function ones(s) { return numeric.rep(s,1); } numeric.dotMMsmall = function dotMMsmall(x,y) { var i,j,k,p,q,r,ret,foo,bar,woo,i0,k0,p0,r0; @@ -414,6 +429,7 @@ numeric.dotMMsmall = function dotMMsmall(x,y) { } return ret; } + numeric._getCol = function _getCol(A,j,x) { var n = A.length, i; for(i=n-1;i>0;--i) { @@ -423,6 +439,7 @@ numeric._getCol = function _getCol(A,j,x) { } if(i===0) x[0] = A[0][j]; } + numeric.dotMMbig = function dotMMbig(x,y){ var gc = numeric._getCol, p = y.length, v = Array(p); var m = x.length, n = y[0].length, A = new Array(m), xj; @@ -492,6 +509,72 @@ 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.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--) { @@ -512,6 +595,7 @@ numeric.diag = function diag(d) { } return A; } + numeric.getDiag = function(A) { var n = Math.min(A.length,A[0].length),i,ret = Array(n); for(i=n-1;i>=1;--i) { @@ -525,149 +609,193 @@ numeric.getDiag = function(A) { return ret; } +numeric.setDiag = function(A, x) { + for(var i=0;i=0;i--) ret[i] = arguments.callee('+params.join(',')+',_s,_k+1);\n'+ - ' return ret;\n'+ + +numeric._broadcast = function expand(x, sx, sy) { + for(var i=0;i=0;i--) { _biforeach(typeof x==="object"?x[i]:x,typeof y==="object"?y[i]:y,s,k+1,f); } -}); -numeric._biforeach2 = (function _biforeach2(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); } - return ret; -}); -numeric._foreach = (function _foreach(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); } -}); -numeric._foreach2 = (function _foreach2(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); } - 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._binary = function _binary(body,setup) { + return Function('x','y','_n','_m', + 'var i,j,k,z=_n===1?Array(_m):Array(_n);\n'+setup+';\n'+ + 'if(_n === 1) { for(j=_m-1;j>=0;--j) {i=0;k=j;'+body+'} } else \n'+ + 'if(_m === 1) { for(i=_n-1;i>=0;--i) {j=0;k=i;'+body+'} } else \n'+ + ' { for(i=_n-1;i>=0;--i) {j=i;k=i;'+body+'} }\n'+ + 'return z;'); +} -numeric.ops2 = { - add: '+', - sub: '-', - mul: '*', - div: '/', - mod: '%', - and: '&&', - or: '||', - eq: '===', - neq: '!==', - lt: '<', - gt: '>', - leq: '<=', - geq: '>=', - band: '&', - bor: '|', - bxor: '^', - lshift: '<<', - rshift: '>>', - rrshift: '>>>' +numeric._binaryeq = function _binaryeq(body,setup) { + return Function('x','y','_n','_m', + 'var i,j,k;\n'+setup+';\n'+ + 'if(_m === 1) { for(i=_n-1;i>=0;--i) {j=0;k=i;'+body+'} } else \n'+ + ' { for(i=_n-1;i>=0;--i) {j=i;k=i;'+body+'} }\n'); +} + +numeric._unary = function _unary(body,setup) { + return Function('x','_n', + 'var i,k,z=Array(_n);\n'+setup+';\n'+ + 'for(i=_n-1;i>=0;--i) {k=i;'+body+'}'+ + 'return z;'); +} + +numeric._unaryeq = function _unaryeq(body,setup) { + return Function('x','_n', + 'var i,k;\n'+setup+';\n'+ + 'for(i=_n-1;i>=0;--i) {k=i;'+body+'}'); +} + +numeric._biforeacheq = function _biforeacheq(x,y,sx,sy,k,f) { + if(k === sx.length-1) { f(x,y,sx[k],sy[k]); return; } + var i,n=sx[k],m=sy[k]; + if (m === 1) { for(i=n-1;i>=0;i--) { _biforeacheq(x[i],y[0],sx,sy,k+1,f); }} + else { for(i=n-1;i>=0;i--) { _biforeacheq(x[i],y[i],sx,sy,k+1,f); }} }; -numeric.opseq = { - addeq: '+=', - subeq: '-=', - muleq: '*=', - diveq: '/=', - modeq: '%=', - lshifteq: '<<=', - rshifteq: '>>=', - rrshifteq: '>>>=', - bandeq: '&=', - boreq: '|=', - bxoreq: '^=' + +numeric._biforeach = function _biforeach(x,y,sx,sy,k,f) { + if(k === sx.length-1) { return f(x,y,sx[k],sy[k]); } + var i,n=sx[k],m=sy[k],z=(n===1)?Array(m):Array(n); + if (n === 1) { for(i=m-1;i>=0;--i) { z[i] = _biforeach(x[0],y[i],sx,sy,k+1,f); }} + else if (m === 1) { for(i=n-1;i>=0;--i) { z[i] = _biforeach(x[i],y[0],sx,sy,k+1,f); }} + else { for(i=n-1;i>=0;--i) { z[i] = _biforeach(x[i],y[i],sx,sy,k+1,f); }} + return z; }; -numeric.mathfuns = ['abs','acos','asin','atan','ceil','cos', - 'exp','floor','log','round','sin','sqrt','tan', - 'isNaN','isFinite']; -numeric.mathfuns2 = ['atan2','pow','max','min']; + +numeric._foreacheq = function _foreacheq(x,s,k,f) { + if(k === s.length-1) { f(x,s[k]); return; } + for(var i=s[k]-1;i>=0;i--) { _foreacheq(x[i],s,k+1,f); } +}; + +numeric._foreach = function _foreach(x,s,k,f) { + if(k === s.length-1) { return f(x,s[k]); } + var i,n=s[k],z=Array(n); + for(i=n-1;i>=0;i--) { z[i] = _foreach(x[i],s,k+1,f); } + return z; +}; + +numeric._mapreduce = function _mapreduce(body,setup) { + return Function('x','s','_n', setup+'; for(var i=_n-1;i>=0;--i) { '+body+' }; return z;'); +}; + +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'+ + 'if(a < 0) { a = numeric.dim(x).length+a; }'+ + 'return numeric._mapreduceeach(x,a,s,k,numeric._anonymous'+numeric.anonID+')'); + numeric.anonID++; + return fun; +}; + +numeric._mapreduceeach = function _mapreduceeach(x,a,s,k,f) { + if (a === k) { return f(x,s.slice().splice(k+1),s[k]); } + var i,n=s[k],z=Array(n); + for (i=n-1;i>=0;--i) { z[i]=numeric._mapreduceeach(x[i],a,s,k+1,f); } + return z; +}; + numeric.ops1 = { - neg: '-', - not: '!', - bnot: '~', - clone: '' + neg: '-', not: '!', bnot: '~', bool: '!!', clone: '' }; -numeric.mapreducers = { - any: ['if(xi) return true;','var accum = false;'], - all: ['if(!xi) return false;','var accum = true;'], - sum: ['accum += xi;','var accum = 0;'], - prod: ['accum *= xi;','var accum = 1;'], - norm2Squared: ['accum += xi*xi;','var accum = 0;'], - norminf: ['accum = max(accum,abs(xi));','var accum = 0, max = Math.max, abs = Math.abs;'], - norm1: ['accum += abs(xi)','var accum = 0, abs = Math.abs;'], - sup: ['accum = max(accum,xi);','var accum = -Infinity, max = Math.max;'], - inf: ['accum = min(accum,xi);','var accum = Infinity, min = Math.min;'] + +numeric.ops2 = { + add: '+', sub: '-', mul: '*', div: '/', mod: '%', + and: '&&', or: '||', eq: '===', neq: '!==', lt: '<', + gt: '>', leq: '<=', geq: '>=', band: '&', bor: '|', + bxor: '^', lshift: '<<', rshift: '>>', rrshift: '>>>' +}; + +numeric.opseq = { + addeq: '+=', subeq: '-=', muleq: '*=', diveq: '/=', + modeq: '%=', lshifteq: '<<=', rshifteq: '>>=', rrshifteq: '>>>=', + bandeq: '&=', boreq: '|=', bxoreq: '^=' }; +numeric.mathfuns = [ + 'abs','acos', 'asin','atan', 'ceil','cos', + 'exp','floor','log', 'round','sin', 'sqrt', + 'tan','isNaN','isFinite']; + +numeric.mathfuns2 = ['atan2','pow','max','min']; + (function () { var i,o; for(i=0;ir.stop):(i=0) && (ir.stop):(i=0) && (ir.stop):(i=0) && (ir.stop):(i=0) && (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=0;--i) { z[i] = numeric.clone(x[y[i]]); } + return z; +} + +numeric.index = function index(x,y,s,k) { + if(typeof y !== 'object') { return x[y]; } + if(typeof k === 'undefined') { k=0; } + 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,y[i],s,k+1); } + return z; +} + +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,sy,sz,k) { + if(typeof k === 'undefined') { k=0; } + if(typeof sy === 'undefined') { sy=numeric.dim(y); } + 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'); + numeric.inv = function inv(x) { var s = numeric.dim(x), abs = Math.abs, m = s[0], n = s[1]; var A = numeric.clone(x), Ai, Aj; @@ -849,95 +1140,110 @@ numeric.det = function det(x) { } numeric.transpose = function transpose(x) { - var i,j,m = x.length,n = x[0].length, ret=Array(n),A0,A1,Bj; - for(j=0;j=1;i-=2) { A1 = x[i]; A0 = x[i-1]; for(j=n-1;j>=1;--j) { - Bj = ret[j]; Bj[i] = A1[j]; Bj[i-1] = A0[j]; + Bj = z[j]; Bj[i] = A1[j]; Bj[i-1] = A0[j]; --j; - Bj = ret[j]; Bj[i] = A1[j]; Bj[i-1] = A0[j]; + Bj = z[j]; Bj[i] = A1[j]; Bj[i-1] = A0[j]; } if(j===0) { - Bj = ret[0]; Bj[i] = A1[0]; Bj[i-1] = A0[0]; + Bj = z[0]; Bj[i] = A1[0]; Bj[i-1] = A0[0]; } } if(i===0) { A0 = x[0]; for(j=n-1;j>=1;--j) { - ret[j][0] = A0[j]; + z[j][0] = A0[j]; --j; - ret[j][0] = A0[j]; + z[j][0] = A0[j]; } - if(j===0) { ret[0][0] = A0[0]; } + if(j===0) { z[0][0] = A0[0]; } } - return ret; + return z; } numeric.negtranspose = function negtranspose(x) { - var i,j,m = x.length,n = x[0].length, ret=Array(n),A0,A1,Bj; - for(j=0;j=1;i-=2) { A1 = x[i]; A0 = x[i-1]; for(j=n-1;j>=1;--j) { - Bj = ret[j]; Bj[i] = -A1[j]; Bj[i-1] = -A0[j]; + Bj = z[j]; Bj[i] = -A1[j]; Bj[i-1] = -A0[j]; --j; - Bj = ret[j]; Bj[i] = -A1[j]; Bj[i-1] = -A0[j]; + Bj = z[j]; Bj[i] = -A1[j]; Bj[i-1] = -A0[j]; } if(j===0) { - Bj = ret[0]; Bj[i] = -A1[0]; Bj[i-1] = -A0[0]; + Bj = z[0]; Bj[i] = -A1[0]; Bj[i-1] = -A0[0]; } } if(i===0) { A0 = x[0]; for(j=n-1;j>=1;--j) { - ret[j][0] = -A0[j]; + z[j][0] = -A0[j]; --j; - ret[j][0] = -A0[j]; + z[j][0] = -A0[j]; } - if(j===0) { ret[0][0] = -A0[0]; } + if(j===0) { z[0][0] = -A0[0]; } } - return ret; + return z; } numeric._random = function _random(s,k) { - var i,n=s[k],ret=Array(n), rnd; + var i,n=s[k],z=Array(n), rnd; if(k === s.length-1) { rnd = Math.random; for(i=n-1;i>=1;i-=2) { - ret[i] = rnd(); - ret[i-1] = rnd(); + z[i] = rnd(); + z[i-1] = rnd(); } - if(i===0) { ret[0] = rnd(); } - return ret; + if(i===0) { z[0] = rnd(); } + return z; } - for(i=n-1;i>=0;i--) ret[i] = _random(s,k+1); - return ret; + for(i=n-1;i>=0;i--) z[i] = _random(s,k+1); + return z; } numeric.random = function random(s) { return numeric._random(s,0); } -numeric.norm2 = function norm2(x) { return Math.sqrt(numeric.norm2Squared(x)); } +numeric.norm2 = function norm2(x,a) { return numeric.sqrt(numeric.norm2Squared(x,a)); } numeric.linspace = function linspace(a,b,n) { if(typeof n === "undefined") n = Math.max(Math.round(b-a)+1,1); if(n<2) { return n===1?[a]:[]; } - var i,ret = Array(n); + var i,z = Array(n); n--; - for(i=n;i>=0;i--) { ret[i] = (i*b+(n-i)*a)/n; } - return ret; + for(i=n;i>=0;i--) { z[i] = (i*b+(n-i)*a)/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; } + if (step > 0 && (stop < start)) { return []; } + if (step < 0 && (stop > start)) { return []; } + var i,z=[]; + for(i=start;i=0;i--) { ret[i] = x[i+a]; } - return ret; + for(i=n;i>=0;i--) { z[i] = x[i+a]; } + return z; } - for(i=n;i>=0;i--) { ret[i] = foo(x[i+a],k+1); } - return ret; + for(i=n;i>=0;i--) { z[i] = foo(x[i+a],k+1); } + return z; } return foo(x,0); } @@ -1071,7 +1377,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); @@ -1387,6 +1693,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; } @@ -2163,24 +2471,24 @@ numeric.sdotMV = function dotMV(A,x) { numeric.sdotVM = function dotMV(x,A) { var i,j,Ai,alpha; - var ret = [], accum; + var z=[], accum; for(i in x) { if(!x.hasOwnProperty(i)) continue; Ai = A[i]; alpha = x[i]; for(j in Ai) { if(!Ai.hasOwnProperty(j)) continue; - if(!ret[j]) { ret[j] = 0; } - ret[j] += alpha*Ai[j]; + if(!z[j]) { z[j] = 0; } + z[j] += alpha*Ai[j]; } } - return ret; + return z; } numeric.sdotVV = function dotVV(x,y) { - var i,ret=0; - for(i in x) { if(x[i] && y[i]) ret+= x[i]*y[i]; } - return ret; + var i,z=0; + for(i in x) { if(x[i] && y[i]) z+= x[i]*y[i]; } + return z; } numeric.sdot = function dot(A,B) { @@ -2680,7 +2988,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