diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..4872ee1 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,12 @@ +*.sh text eol=lf +*.php text eol=lf +*.inc text eol=lf +*.html text eol=lf +*.js text eol=lf +*.css text eol=lf +*.ini text eol=lf +*.txt text eol=lf +*.xml text eol=lf +*.md text eol=lf +*.markdown text eol=lf + diff --git a/.gitignore b/.gitignore index 8e83bcb..1f2b86c 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,9 @@ *.rar *.tar *.zip + +# installed NPM packages +node_modules/ # Emacs backups *~ diff --git a/README.md b/README.md index 8646b37..dfe5970 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,48 @@ -Numeric Javascript by Sébastien Loisel -====================================== +This is a fork of Numeric Javascript by Sébastien Loisel. + +Changes +------ + +Notable changes compared with numeric-1.2.6.js + +- numeric.jacobi(A, maxiter), that diagonalizes symmetric real matrices (real hermitian). No problems with repeated eigenvalues/symmetry. + +- numeric.eigh(A, maxiter), mirrors numeric.jacobi. + +- numeric.jacobinorm(A), helper for numeric.jacobi, computes the weight in the upper triangular part of a square matrix. + +- extra iterative solvers: + + + numeric.ccsMV(A, x), CCS matrix mul dense vector helper + + + numeric.bicgstab(A, b, maxIters, residue), BICGSTAB algorithm + + + numeric.cg(A, b, maxIters, residue), conjugate gradient (CG) solver. Supports both full matrix and sparse matrix. + + + numeric.sor(A, b, relax, maxIters, residue), SOR solver. The performance of the SOR solver is not as good as CG and BiCGSTAB, but similar to ccsLUPSolve. In practice, CG and BiCGSTAB should always be the best options. + + + numeric.newtonSolve(F, A, x), Newton solver. Ported from GSL(GNU Scientific Library)'s globally convergent Newton method (gsl-1.15\multiroots\gnewton.c). This Newton solver has been successfully used to implement a simple geometric constraint solver in project Rena (https://github.com/kaige/Rena). + + + numeric.uniroot(func, lowerLimit, upperLimit, errorTol, maxIter), search the interval from lowerLimit to upperLimit for a root (i.e., zero) of the function func with respect to its first argument using Brent's method root-finding algorithm. + +- numeric.logspace(), another fill routine akin to numeric.linspace() but now for logarithmic space fills. + +- numeric.zeros(), numeric.ones(), numeric.empty(), numeric.range(): methods to fill a vector or Array with fixed values. + +- numeric.roll(), numeric.flip(), numeric.fliplr(), numeric.flipud(), numeric.rot90(): methods to flip/rotate Arrays (matrices). + +- numeric.kron(x, y), Kronecker's method applied to a matrix. + +- numeric.ccsDiag(diag), numeric.ccsTranspose(A): numeric.ccsScatter helpers + +- numeric.pi, numeric.e: high precision math constants + +- CSV I/O bugfixes + + + +Introduction +------ Numeric Javascript is a javascript library for doing numerical analysis in the browser. Because Numeric Javascript uses only the @@ -12,7 +55,7 @@ asking a server to compute something. Indeed, you do not need a powerful server (or any server at all) since your web app will perform all its calculations in the client. -For further information, see http://www.numericjs.com/ +The original website, see http://www.numericjs.com/ Discussion forum: http://groups.google.com/group/numericjs License @@ -47,5 +90,4 @@ the numericjs.com web site, which you probably won't need. Building and testing -------------------- -If you tweak the code, you can build and test the library by running the script /tools/build.sh. If you plan -to send me patches, please at least run this build script and check that all the tests pass. +If you tweak the code, you can build and test the library by running the script /tools/build.sh. diff --git a/benchmark.html b/benchmark.html index dae16f7..4dcde98 100644 --- a/benchmark.html +++ b/benchmark.html @@ -1,6 +1,10 @@ - + + + + + @@ -25,8 +29,8 @@ + +--> +--> + + + +


+ diff --git a/bower.json b/bower.json new file mode 100644 index 0000000..3113b58 --- /dev/null +++ b/bower.json @@ -0,0 +1,22 @@ +{ + "name": "numericjs", + "version": "1.2.6", + "main": "lib/numeric.js", + "description": "Numerical analysis in Javascript", + "license": "MIT", + "repo": "sloisel/numeric" + "ignore": [ + ".jshintrc", + "**/*.txt" + ], + "keywords": [ + "numerical", + "analysis" + ], + "dependencies": { + "seedrandom": "latest", + "quadprog": "lib/quadprog.js", + "sparse2": "lib/sparse2.js", + "svd": "lib/svd.js", + } +} diff --git a/demo.html b/demo.html index d82d21e..0a1d4a1 100644 --- a/demo.html +++ b/demo.html @@ -1,26 +1,17 @@ + + + + + + -Numeric Javascript +Numeric Javascript: Demo + -Fork me on GitHub - - + Numeric Javascript is a library for numerical computations in Javascript. You can write Javascript @@ -60,7 +51,7 @@

Performance

Although Javascript does not reach the same performance as native programs, the Numeric Javascript library is carefully tuned to obtain the best possible performance for a Javascript program. You can compare the performance of Numeric, Sylvester and -Google Closure's +Google Closure's Matrix object using our Benchmark. @@ -91,3 +82,4 @@

About the Author




+ \ No newline at end of file diff --git a/documentation.html b/documentation.html index 80ac39a..a988652 100644 --- a/documentation.html +++ b/documentation.html @@ -1,6 +1,10 @@ - + + + + + @@ -49,6 +53,7 @@ bnotBinary negation ~x borBinary or x|y bxorBinary xor x^y +ccsDiagCreate sparse diagonal matrix ccsDimDimensions of sparse matrix ccsDotSparse matrix-matrix product ccsFullConvert sparse to full @@ -58,6 +63,7 @@ ccsLUPSolveSolve Ax=b using LUP decomp ccsScatterScatter entries of sparse matrix ccsSparseConvert from full to sparse +ccsTransposeSparse matrix transpose ccsTSolveSolve upper/lower triangular system ccs<op>Supported ops include: add/div/mul/geq/etc... cLUCoordinate matrix LU decomposition @@ -81,10 +87,15 @@ FunctionDescription
dotMatrix-Matrix, Matrix-Vector and Vector-Matrix product +e2.71828182845904... eigEigenvalues and eigenvectors +emptyCreate an empty Array epsilon2.220446049250313e-16 eqPointwise comparison x === y expPointwise Math.exp(x) +flipFlip an Array on a given axis +fliplrFlip an Array on the innermost axis +flipudFlip an Array on the second innermost axis floorPoinwise Math.floor(x) geqPointwise x>=y getBlockExtract a block from a matrix @@ -95,9 +106,11 @@ invMatrix inverse isFinitePointwise isFinite(x) isNaNPointwise isNaN(x) +kronKronecker product of two matrices largeArrayDon't prettyPrint Arrays larger than this leqPointwise x<=y linspaceGenerate evenly spaced values +logspaceGenerate logarithmically spaced values logPointwise Math.log(x) lshiftPointwise x<<y lshifteqPointwise x<<=y @@ -110,26 +123,31 @@ mulPointwise x*y negPointwise -x neqPointwise x!==y -norm2Square root of the sum of the square of the entries of x +norm2Square root of the sum of the squares of an Array norm2SquaredSum of squares of entries of x norminfLargest modulus entry of x notPointwise logical negation !x +onesCreate an Array of ones orPointwise logical or x||y oreqPointwise x|=y parseCSVParse a CSV file into an Array parseDatePointwise parseDate(x) parseFloatPointwise parseFloat(x) +pi3.14159265358979... pointwiseCreate a pointwise function -powPointwise Math.pow(x) +powPointwise Math.pow(x,y) precisionNumber of digits to prettyPrint prettyPrintPretty-prints x randomCreate an Array of random numbers +rangeCreate an Array from a range repCreate an Array by duplicating values
FunctionDescription

+
rollRoll an Array on a given axis +
rot90Rotate an Array 90 degrees counter clockwise
roundPointwise Math.round(x)
rrshiftPointwise x>>>y
rrshifteqPointwise x>>>=y @@ -172,6 +190,7 @@
versionVersion string for the numeric library
xorPointwise x^y
xoreqPointwise x^=y +
zerosCreate an Array of zeros

@@ -246,7 +265,7 @@

Numerical analysis in Javascript

 IN> numeric.identity(100)
 OUT> ...Large Array...
-
+ By default, this happens with the Array's length is more than 50. This can be controlled by setting the variable numeric.largeArray to an appropriate value:
@@ -336,6 +355,19 @@ 

Utility functions

[0,0,0]]
+You can create a multidimensional Array of zeros or ones using the functions numeric.zeros() and +numeric.ones(), and empty Arrays using numeric.empty(). + +
+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> [[,,],[,,]]
+
+ 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 @@ -366,6 +398,7 @@

Utility functions

You can create a diagonal matrix using numeric.diag() +
 IN> numeric.diag([1,2,3])
 OUT> [[1,0,0],
@@ -373,6 +406,23 @@ 

Utility functions

[0,0,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]]
+
+ The function numeric.identity() returns the identity matrix.
 IN> numeric.identity(3)
@@ -397,6 +447,28 @@ 

Utility functions

OUT> [1,1.5,2,2.5,3]
+Or a vector of logarithmically spaced values between Math.pow(exp,a) and Math.pow(exp,b), where the default exp exponent is 10: + +
+IN> numeric.logspace(0,1,5);
+OUT> [1, 1.7782794100389228, 3.1622776601683795, 5.623413251903491, 10]
+IN> numeric.logspace(1,3,5,10);
+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]
+
+ @@ -842,6 +928,20 @@

Sparse linear algebra

IN> numeric.ccsDot(M,[[0,3],[0,1,2],x]) OUT> [[0,3],[0,1,2],[9,3,2]] +Create a sparse diangoal matrix +
+IN> SA = numeric.ccsDiag([1,2,3]);
+OUT> [[ 0, 1, 2, 3],
+      [ 0, 1, 2],
+      [ 1, 2, 3]]
+
+Tranpose a sparse matrix +
+IN> numeric.ccsTranspose(numeric.ccsScatter([[0,1,2],[2,1,0],[1,2,4]]));
+OUT> [[ 0, 1, 2, 3],
+      [ 2, 1, 0],
+      [ 1, 2, 4]]  
+
We provide an LU=PA decomposition:
 IN> A = [[0,5,10,15,20,25],
@@ -887,8 +987,8 @@ 

Sparse linear algebra

foo = numeric.ccsFull(numeric.ccsDot(LUP.L,LUP.U)); PA = numeric.ccsFull(numeric.ccsGetBlock(A,LUP.P)); res = numeric.norminf(numeric.sub(foo,PA)); - if(!isFinite(res) || res>1e-6) { - result = { + if(!isFinite(res) || res>1e-6) { + result = { code: "Failed during 1000 sparse LUP", k:k,A:A,LUP:LUP,res:res }; @@ -948,19 +1048,19 @@

Solving PDEs

 IN> g = numeric.cgrid(5)
-OUT> 
+OUT>
 [[-1,-1,-1,-1,-1],
  [-1, 0, 1, 2,-1],
  [-1, 3, 4, 5,-1],
  [-1, 6, 7, 8,-1],
  [-1,-1,-1,-1,-1]]
 IN> coordL = numeric.cdelsq(g)
-OUT> 
+OUT>
 [[ 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8],
  [ 1, 3, 0, 0, 2, 4, 1, 1, 5, 2, 0, 4, 6, 3, 1, 3, 5, 7, 4, 2, 4, 8, 5, 3, 7, 6, 4, 6, 8, 7, 5, 7, 8],
  [-1,-1, 4,-1,-1,-1, 4,-1,-1, 4,-1,-1,-1, 4,-1,-1,-1,-1, 4,-1,-1,-1, 4,-1,-1, 4,-1,-1,-1, 4,-1,-1, 4]]
 IN> L = numeric.sscatter(coordL); // Just to see what it looks like
-OUT> 
+OUT>
 [[          4,         -1,           ,         -1],
  [         -1,          4,         -1,           ,         -1],
  [           ,         -1,          4,           ,           ,         -1],
@@ -975,21 +1075,21 @@ 

Solving PDEs

IN> numeric.cdotMV(coordL,x) OUT> [1,1,1,1,1,1,1,1,1] IN> G = numeric.rep([5,5],0); for(i=0;i<5;i++) for(j=0;j<5;j++) if(g[i][j]>=0) G[i][j] = x[g[i][j]]; G -OUT> +OUT> [[ 0 , 0 , 0 , 0 , 0 ], [ 0 , 0.6875, 0.875 , 0.6875, 0 ], [ 0 , 0.875 , 1.125 , 0.875 , 0 ], [ 0 , 0.6875, 0.875 , 0.6875, 0 ], [ 0 , 0 , 0 , 0 , 0 ]] IN> workshop.html('<img src="'+numeric.imageURL(numeric.mul([G,G,G],200))+'" width=100 />'); -OUT> +OUT>
You can also work on an L-shaped or arbitrary-shape domain:
 IN> numeric.cgrid(6,'L')
-OUT> 
+OUT>
 [[-1,-1,-1,-1,-1,-1],
  [-1, 0, 1,-1,-1,-1],
  [-1, 2, 3,-1,-1,-1],
@@ -997,7 +1097,7 @@ 

Solving PDEs

[-1, 8, 9,10,11,-1], [-1,-1,-1,-1,-1,-1]] IN> numeric.cgrid(5,function(i,j) { return i!==2 || j!==2; }) -OUT> +OUT> [[-1,-1,-1,-1,-1], [-1, 0, 1, 2,-1], [-1, 3,-1, 4,-1], @@ -1076,84 +1176,84 @@

Unconstrained optimization

Here are some demos from from Moré et al., 1981:
-IN> sqr = function(x) { return x*x; }; 
+IN> sqr = function(x) { return x*x; };
     numeric.uncmin(function(x) { return sqr(10*(x[1]-x[0]*x[0])) + sqr(1-x[0]); },[-1.2,1]).solution
 OUT> [1,1]
-IN> f = function(x) { return sqr(-13+x[0]+((5-x[1])*x[1]-2)*x[1])+sqr(-29+x[0]+((x[1]+1)*x[1]-14)*x[1]); }; 
+IN> f = function(x) { return sqr(-13+x[0]+((5-x[1])*x[1]-2)*x[1])+sqr(-29+x[0]+((x[1]+1)*x[1]-14)*x[1]); };
     x0 = numeric.uncmin(f,[0.5,-2]).solution
 OUT> [11.41,-0.8968]
-IN> f = function(x) { return sqr(1e4*x[0]*x[1]-1)+sqr(Math.exp(-x[0])+Math.exp(-x[1])-1.0001); }; 
+IN> f = function(x) { return sqr(1e4*x[0]*x[1]-1)+sqr(Math.exp(-x[0])+Math.exp(-x[1])-1.0001); };
     x0 = numeric.uncmin(f,[0,1]).solution
 OUT> [1.098e-5,9.106]
-IN> f = function(x) { return sqr(x[0]-1e6)+sqr(x[1]-2e-6)+sqr(x[0]*x[1]-2)}; 
+IN> f = function(x) { return sqr(x[0]-1e6)+sqr(x[1]-2e-6)+sqr(x[0]*x[1]-2)};
     x0 = numeric.uncmin(f,[0,1]).solution
 OUT> [1e6,2e-6]
-IN> f = function(x) { 
+IN> f = function(x) {
        return sqr(1.5-x[0]*(1-x[1]))+sqr(2.25-x[0]*(1-x[1]*x[1]))+sqr(2.625-x[0]*(1-x[1]*x[1]*x[1]));
-    }; 
+    };
     x0 = numeric.uncmin(f,[1,1]).solution
 OUT> [3,0.5]
-IN> f = function(x) { 
-        var ret = 0,i; 
+IN> f = function(x) {
+        var ret = 0,i;
         for(i=1;i<=10;i++) ret+=sqr(2+2*i-Math.exp(i*x[0])-Math.exp(i*x[1]));
-         return ret; 
+         return ret;
     };
     x0 = numeric.uncmin(f,[0.3,0.4]).solution
 OUT> [0.2578,0.2578]
-IN> y = [0.14,0.18,0.22,0.25,0.29,0.32,0.35,0.39,0.37,0.58,0.73,0.96,1.34,2.10,4.39]; 
-    f = function(x) { 
-        var ret = 0,i; 
-        for(i=1;i<=15;i++) ret+=sqr(y[i-1]-(x[0]+i/((16-i)*x[1]+Math.min(i,16-i)*x[2]))); 
-        return ret; 
-    }; 
+IN> y = [0.14,0.18,0.22,0.25,0.29,0.32,0.35,0.39,0.37,0.58,0.73,0.96,1.34,2.10,4.39];
+    f = function(x) {
+        var ret = 0,i;
+        for(i=1;i<=15;i++) ret+=sqr(y[i-1]-(x[0]+i/((16-i)*x[1]+Math.min(i,16-i)*x[2])));
+        return ret;
+    };
     x0 = numeric.uncmin(f,[1,1,1]).solution
 OUT> [0.08241,1.133,2.344]
-IN> y = [0.0009,0.0044,0.0175,0.0540,0.1295,0.2420,0.3521,0.3989,0.3521,0.2420,0.1295,0.0540,0.0175,0.0044,0.0009]; 
-    f = function(x) { 
-        var ret = 0,i; 
-        for(i=1;i<=15;i++) 
-        ret+=sqr(x[0]*Math.exp(-x[1]*sqr((8-i)/2-x[2])/2)-y[i-1]); 
-        return ret; 
-    }; 
+IN> y = [0.0009,0.0044,0.0175,0.0540,0.1295,0.2420,0.3521,0.3989,0.3521,0.2420,0.1295,0.0540,0.0175,0.0044,0.0009];
+    f = function(x) {
+        var ret = 0,i;
+        for(i=1;i<=15;i++)
+        ret+=sqr(x[0]*Math.exp(-x[1]*sqr((8-i)/2-x[2])/2)-y[i-1]);
+        return ret;
+    };
     x0 = numeric.div(numeric.round(numeric.mul(numeric.uncmin(f,[1,1,1]).solution,1000)),1000)
 OUT> [0.399,1,0]
-IN> f = function(x) { return sqr(x[0]+10*x[1])+5*sqr(x[2]-x[3])+sqr(sqr(x[1]-2*x[2]))+10*sqr(x[0]-x[3]); }; 
+IN> f = function(x) { return sqr(x[0]+10*x[1])+5*sqr(x[2]-x[3])+sqr(sqr(x[1]-2*x[2]))+10*sqr(x[0]-x[3]); };
     x0 = numeric.div(numeric.round(numeric.mul(numeric.uncmin(f,[3,-1,0,1]).solution,1e5)),1e5)
 OUT> [0,0,0,0]
-IN> f = function(x) { 
+IN> f = function(x) {
         return (sqr(10*(x[1]-x[0]*x[0]))+sqr(1-x[0])+
                 90*sqr(x[3]-x[2]*x[2])+sqr(1-x[2])+
-                10*sqr(x[1]+x[3]-2)+0.1*sqr(x[1]-x[3])); }; 
+                10*sqr(x[1]+x[3]-2)+0.1*sqr(x[1]-x[3])); };
     x0 = numeric.uncmin(f,[-3,-1,-3,-1]).solution
 OUT> [1,1,1,1]
-IN> y = [0.1957,0.1947,0.1735,0.1600,0.0844,0.0627,0.0456,0.0342,0.0323,0.0235,0.0246]; 
-    u = [4,2,1,0.5,0.25,0.167,0.125,0.1,0.0833,0.0714,0.0625]; 
-    f = function(x) { 
-        var ret=0, i; 
-        for(i=0;i<11;++i) ret += sqr(y[i]-x[0]*(u[i]*u[i]+u[i]*x[1])/(u[i]*u[i]+u[i]*x[2]+x[3])); 
-        return ret; 
-    }; 
+IN> y = [0.1957,0.1947,0.1735,0.1600,0.0844,0.0627,0.0456,0.0342,0.0323,0.0235,0.0246];
+    u = [4,2,1,0.5,0.25,0.167,0.125,0.1,0.0833,0.0714,0.0625];
+    f = function(x) {
+        var ret=0, i;
+        for(i=0;i<11;++i) ret += sqr(y[i]-x[0]*(u[i]*u[i]+u[i]*x[1])/(u[i]*u[i]+u[i]*x[2]+x[3]));
+        return ret;
+    };
     x0 = numeric.uncmin(f,[0.25,0.39,0.415,0.39]).solution
 OUT> [     0.1928,     0.1913,     0.1231,     0.1361]
 IN> y = [0.844,0.908,0.932,0.936,0.925,0.908,0.881,0.850,0.818,0.784,0.751,0.718,
          0.685,0.658,0.628,0.603,0.580,0.558,0.538,0.522,0.506,0.490,0.478,0.467,
-         0.457,0.448,0.438,0.431,0.424,0.420,0.414,0.411,0.406]; 
-    f = function(x) { 
-        var ret=0, i; 
-        for(i=0;i<33;++i) ret += sqr(y[i]-(x[0]+x[1]*Math.exp(-10*i*x[3])+x[2]*Math.exp(-10*i*x[4]))); 
-        return ret; 
-    }; 
+         0.457,0.448,0.438,0.431,0.424,0.420,0.414,0.411,0.406];
+    f = function(x) {
+        var ret=0, i;
+        for(i=0;i<33;++i) ret += sqr(y[i]-(x[0]+x[1]*Math.exp(-10*i*x[3])+x[2]*Math.exp(-10*i*x[4])));
+        return ret;
+    };
     x0 = numeric.uncmin(f,[0.5,1.5,-1,0.01,0.02]).solution
 OUT> [     0.3754,      1.936,     -1.465,    0.01287,    0.02212]
-IN> f = function(x) { 
-        var ret=0, i,ti,yi,exp=Math.exp; 
-        for(i=1;i<=13;++i) { 
-            ti = 0.1*i; 
-            yi = exp(-ti)-5*exp(-10*ti)+3*exp(-4*ti); 
-            ret += sqr(x[2]*exp(-ti*x[0])-x[3]*exp(-ti*x[1])+x[5]*exp(-ti*x[4])-yi); 
-        } 
-        return ret; 
-    }; 
+IN> f = function(x) {
+        var ret=0, i,ti,yi,exp=Math.exp;
+        for(i=1;i<=13;++i) {
+            ti = 0.1*i;
+            yi = exp(-ti)-5*exp(-10*ti)+3*exp(-4*ti);
+            ret += sqr(x[2]*exp(-ti*x[0])-x[3]*exp(-ti*x[1])+x[5]*exp(-ti*x[4])-yi);
+        }
+        return ret;
+    };
     x0 = numeric.uncmin(f,[1,2,1,1,1,1],1e-14).solution;
     f(x0)<1e-20;
 OUT> true
@@ -1163,8 +1263,8 @@ 

Unconstrained optimization

gradient of f(). If it is not provided, a numerical gradient is used. The iteration stops when maxit iterations have been performed. The optional callback() parameter, if provided, is called at each step:
-IN> z = []; 
-    cb = function(i,x,f,g,H) { z.push({i:i, x:x, f:f, g:g, H:H }); }; 
+IN> z = [];
+    cb = function(i,x,f,g,H) { z.push({i:i, x:x, f:f, g:g, H:H }); };
     x0 = numeric.uncmin(function(x) { return Math.cos(2*x[0]); },
                         [1],1e-10,
                         function(x) { return [-2*Math.sin(2*x[0])]; },
@@ -1193,7 +1293,7 @@ 

Linear programming

IN> x = numeric.solveLP([1,1], /* minimize [1,1]*x */ [[-1,0],[0,-1],[-1,-2]], /* matrix of inequalities */ [0,0,-3] /* right-hand-side of inequalities */ - ); + ); numeric.trunc(x.solution,1e-12); OUT> [0,1.5]
@@ -1349,7 +1449,7 @@

Solving ODEs

Seedrandom (David Bau)

-The object numeric.seedrandom is based on +The object numeric.seedrandom is based on David Bau's seedrandom.js. This small library can be used to create better pseudorandom numbers than Math.random() which can furthermore be "seeded". @@ -1367,4 +1467,4 @@

Seedrandom (David Bau)




- + \ No newline at end of file diff --git a/favicon.ico b/favicon.ico old mode 100755 new mode 100644 diff --git a/index.php b/index.php index 6a6d2ed..5ee25b5 100644 --- a/index.php +++ b/index.php @@ -1,13 +1,19 @@ + + + + + Numeric Javascript + @@ -62,7 +68,7 @@ Although Javascript does not reach the same performance as native programs, the Numeric Javascript library is carefully tuned to obtain the best possible performance for a Javascript program. You can compare the performance of Numeric, Sylvester and -Google Closure's +Google Closure's Matrix object using our Benchmark. @@ -94,3 +100,4 @@


+ diff --git a/lib/.gitignore b/lib/.gitignore index 2fec4ab..72e4a4d 100644 --- a/lib/.gitignore +++ b/lib/.gitignore @@ -1,2 +1,3 @@ -*.js + +*.min.js *.tar.gz diff --git a/lib/numeric-1.2.7.js b/lib/numeric-1.2.7.js new file mode 100644 index 0000000..86fffff --- /dev/null +++ b/lib/numeric-1.2.7.js @@ -0,0 +1,5575 @@ +(function (root, factory) { + if (typeof exports === 'object') { + // Node. + module.exports = factory(); + } else if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(factory); + } else { + // Browser globals (root is window) + root.numeric = factory(); + } +}(this, function() { + +'use strict'; +var numeric = function numeric(){}; + +//if(typeof global !== "undefined") { global.numeric = numeric; } + +numeric.version = "1.2.7"; + +// 1. Utility functions +numeric.bench = function bench (f,interval) { + var t1,t2,n,i; + if(typeof interval === "undefined") { interval = 15; } + n = 0.5; + t1 = new Date(); + while(1) { + n*=2; + for(i=n;i>3;i-=4) { f(); f(); f(); f(); } + while(i>0) { f(); i--; } + t2 = new Date(); + if(t2-t1 > interval) break; + } + for(i=n;i>3;i-=4) { f(); f(); f(); f(); } + while(i>0) { f(); i--; } + t2 = new Date(); + return 1000*(3*n-1)/(t2-t1); +}; + +numeric._myIndexOf = (function _myIndexOf(w) { + var n = this.length,k; + for(k=0;k numeric.largeArray) { ret.push('...Large Array...'); return true; } + var flag = false; + ret.push('['); + for(k=0;k0) { ret.push(','); if(flag) ret.push('\n '); } flag = foo(x[k]); } + ret.push(']'); + return true; + } + ret.push('{'); + var flag = false; + for(k in x) { if(x.hasOwnProperty(k)) { if(flag) ret.push(',\n'); flag = true; ret.push(k); ret.push(': \n'); foo(x[k]); } } + ret.push('}'); + return true; + } + foo(x); + return ret.join(''); +}; + +numeric.parseDate = function parseDate(d) { + function foo(d) { + if(typeof d === 'string') { return Date.parse(d.replace(/-/g,'/')); } + if(!(d instanceof Array)) { throw new Error("parseDate: parameter must be arrays of strings"); } + var ret = [],k; + for(k=0;k0) { + ret[count] = []; + for(j=0;j> 2; + q = ((x & 3) << 4) + (y >> 4); + r = ((y & 15) << 2) + (z >> 6); + s = z & 63; + if(i+1>=n) { r = s = 64; } + else if(i+2>=n) { s = 64; } + ret += key.charAt(p) + key.charAt(q) + key.charAt(r) + key.charAt(s); + } + return ret; + } + function crc32Array (a,from,to) { + if(typeof from === "undefined") { from = 0; } + if(typeof to === "undefined") { to = a.length; } + var table = [0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, + 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, + 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, + 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, + 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, + 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, + 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, + 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, + 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, + 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, + 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, + 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, + 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, + 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, + 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, + 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, + 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, + 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, + 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, + 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, + 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, + 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D]; + + var crc = -1, y = 0, n = a.length,i; + + for (i = from; i < to; i++) { + y = (crc ^ a[i]) & 0xFF; + crc = (crc >>> 8) ^ table[y]; + } + + return crc ^ (-1); + } + + var h = img[0].length, w = img[0][0].length, s1, s2, next,k,length,a,b,i,j,adler32,crc32; + var stream = [ + 137, 80, 78, 71, 13, 10, 26, 10, // 0: PNG signature + 0,0,0,13, // 8: IHDR Chunk length + 73, 72, 68, 82, // 12: "IHDR" + (w >> 24) & 255, (w >> 16) & 255, (w >> 8) & 255, w&255, // 16: Width + (h >> 24) & 255, (h >> 16) & 255, (h >> 8) & 255, h&255, // 20: Height + 8, // 24: bit depth + 2, // 25: RGB + 0, // 26: deflate + 0, // 27: no filter + 0, // 28: no interlace + -1,-2,-3,-4, // 29: CRC + -5,-6,-7,-8, // 33: IDAT Chunk length + 73, 68, 65, 84, // 37: "IDAT" + // RFC 1950 header starts here + 8, // 41: RFC1950 CMF + 29 // 42: RFC1950 FLG + ]; + crc32 = crc32Array(stream,12,29); + stream[29] = (crc32>>24)&255; + stream[30] = (crc32>>16)&255; + stream[31] = (crc32>>8)&255; + stream[32] = (crc32)&255; + s1 = 1; + s2 = 0; + for(i=0;i>8)&255; + stream.push(a); stream.push(b); + stream.push((~a)&255); stream.push((~b)&255); + if(i===0) stream.push(0); + for(j=0;j255) a = 255; + else if(a<0) a=0; + else a = Math.round(a); + s1 = (s1 + a )%65521; + s2 = (s2 + s1)%65521; + stream.push(a); + } + } + stream.push(0); + } + adler32 = (s2<<16)+s1; + stream.push((adler32>>24)&255); + stream.push((adler32>>16)&255); + stream.push((adler32>>8)&255); + stream.push((adler32)&255); + length = stream.length - 41; + stream[33] = (length>>24)&255; + stream[34] = (length>>16)&255; + stream[35] = (length>>8)&255; + stream[36] = (length)&255; + crc32 = crc32Array(stream,37); + stream.push((crc32>>24)&255); + stream.push((crc32>>16)&255); + stream.push((crc32>>8)&255); + stream.push((crc32)&255); + stream.push(0); + stream.push(0); + stream.push(0); + stream.push(0); +// a = stream.length; + stream.push(73); // I + stream.push(69); // E + stream.push(78); // N + stream.push(68); // D + stream.push(174); // CRC1 + stream.push(66); // CRC2 + stream.push(96); // CRC3 + stream.push(130); // CRC4 + return 'data:image/png;base64,'+base64(stream); +}; + +// 2. Linear algebra with Arrays. +numeric._dim = function _dim(x) { + var ret = []; + while(typeof x === "object") { ret.push(x.length); x = x[0]; } + return ret; +}; + +numeric.dim = function dim(x) { + var y,z; + if(typeof x === "object") { + y = x[0]; + if(typeof y === "object") { + z = y[0]; + if(typeof z === "object") { + return numeric._dim(x); + } + return [x.length,y.length]; + } + return [x.length]; + } + return []; +}; + +// mapreduce +numeric.mapreduce = function mapreduce(body, init) { + return numeric.compile('x','accum','_s','_k', + 'if(typeof accum === "undefined") accum = '+init+';\n'+ + 'if(typeof x === "number") { var xi = x; '+body+'; return accum; }\n'+ + 'if(typeof _s === "undefined") _s = numeric.dim(x);\n'+ + 'if(typeof _k === "undefined") _k = 0;\n'+ + 'var _n = _s[_k];\n'+ + 'var i,xi;\n'+ + 'if(_k < _s.length-1) {\n'+ + ' for(i=_n-1;i>=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.mapreduce2 = function mapreduce2(body, setup) { + return numeric.compile('x', + 'var n = x.length;\n'+ + 'var i,xi;\n'+setup+'\n'+ + 'for(i=n-1;i!==-1;--i) { \n'+ + ' xi = x[i];\n'+ + ' '+body+'\n'+ + '}\n'+ + 'return accum;' + ); +}; + +// compare arrays/tensors +numeric.same = function same(x,y) { + var i, n; + + if(!(x instanceof Array) || !(y instanceof Array)) { return false; } + + n = x.length; + + if(n !== y.length) { return false; } + + for(i = 0; i < n; i++) + { + if(x[i] === y[i]) { continue; } + if(typeof x[i] === "object") { if(!same(x[i], y[i])) return false; } + else { return false; } + } + 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; +}; + +// repeat +numeric.rep = function rep(s, v, k) +{ + // repeat value v over a tensor of size s = [s0, s1, s2, ...] + // k recursive index + 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; + } + + for(i = n - 1; i >= 0; i--) { ret[i] = numeric.rep(s, v, k+1); } + + return ret; +}; + +numeric.zeros = function zeros(s) { return numeric.rep(s,0); }; +numeric.ones = function ones(s) { return numeric.rep(s,1); }; + +// dot functions +numeric.dotMMsmall = function dotMMsmall(x,y) +{ + var i,j,k,p,q,r,ret,foo,bar,woo,i0,k0,p0,r0; + p = x.length; q = y.length; r = y[0].length; + ret = Array(p); + for(i=p-1;i>=0;i--) { + foo = Array(r); + bar = x[i]; + for(k=r-1;k>=0;k--) { + woo = bar[q-1]*y[q-1][k]; + for(j=q-2;j>=1;j-=2) { + i0 = j-1; + woo += bar[j]*y[j][k] + bar[i0]*y[i0][k]; + } + if(j===0) { woo += bar[0]*y[0][k]; } + foo[k] = woo; + } + ret[i] = foo; + } + return ret; +}; + +numeric._getCol = function _getCol(A,j,x) { + var n = A.length, i; + for(i=n-1;i>0;--i) { + x[i] = A[i][j]; + --i; + x[i] = A[i][j]; + } + 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; + var VV = numeric.dotVV; + var i,j,k,z; + --p; + --m; + for(i=m;i!==-1;--i) A[i] = Array(n); + --n; + for(i=n;i!==-1;--i) { + gc(y,i,v); + for(j=m;j!==-1;--j) { + z=0; + xj = x[j]; + A[j][i] = VV(xj,v); + } + } + return A; +}; + +numeric.dotMV = function dotMV(x,y) { + var p = x.length, q = y.length,i; + var ret = Array(p), dotVV = numeric.dotVV; + for(i=p-1;i>=0;i--) { ret[i] = dotVV(x[i],y); } + return ret; +}; + +numeric.dotVM = function dotVM(x,y) { + var i,j,k,p,q,r,ret,foo,bar,woo,i0,k0,p0,r0,s1,s2,s3,baz,accum; + p = x.length; q = y[0].length; + ret = Array(q); + for(k=q-1;k>=0;k--) { + woo = x[p-1]*y[p-1][k]; + for(j=p-2;j>=1;j-=2) { + i0 = j-1; + woo += x[j]*y[j][k] + x[i0]*y[i0][k]; + } + if(j===0) { woo += x[0]*y[0][k]; } + ret[k] = woo; + } + return ret; +}; + +numeric.dotVV = function dotVV(x,y) { + var i,n=x.length,i1,ret = x[n-1]*y[n-1]; + for(i=n-2;i>=1;i-=2) { + i1 = i-1; + ret += x[i]*y[i] + x[i1]*y[i1]; + } + if(i===0) { ret += x[0]*y[0]; } + return ret; +}; + +numeric.dot = function dot(x,y) { + var d = numeric.dim; + switch(d(x).length*1000+d(y).length) { + case 2002: + if(y.length < 10) return numeric.dotMMsmall(x,y); + else return numeric.dotMMbig(x,y); + case 2001: return numeric.dotMV(x,y); + case 1002: return numeric.dotVM(x,y); + case 1001: return numeric.dotVV(x,y); + case 1000: return numeric.mulVS(x,y); + case 1: return numeric.mulSV(x,y); + case 0: return x*y; + default: throw new Error('numeric.dot only works on vectors and matrices'); + } +}; + +// diag function + +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--) { + Ai = Array(n); + i1 = i+2; + for(j=n-1;j>=i1;j-=2) { + Ai[j] = 0; + Ai[j-1] = 0; + } + if(j>i) { Ai[j] = 0; } + Ai[i] = d[i]; + for(j=i-1;j>=1;j-=2) { + Ai[j] = 0; + Ai[j-1] = 0; + } + if(j===0) { Ai[0] = 0; } + A[i] = Ai; + } + 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) { + ret[i] = A[i][i]; + --i; + ret[i] = A[i][i]; + } + if(i===0) { + ret[0] = A[0][0]; + } + return ret; +}; + +numeric.identity = function identity(n) { return numeric.diag(numeric.rep([n],1)); }; + +numeric.pointwise = function pointwise(params,body,setup) +{ + if(typeof setup === "undefined") { setup = ""; } + var fun = []; + var k; + var avec = /\[i\]$/,p,thevec = ''; + var haveret = false; + for(k=0;k=0;i--) ret[i] = arguments.callee('+params.join(',')+',_s,_k+1);\n'+ + ' return ret;\n'+ + '}\n'+ + setup+'\n'+ + 'for(i=_n-1;i!==-1;--i) {\n'+ + ' '+body+'\n'+ + '}\n'+ + 'return ret;' + ); + return numeric.compile.apply(null,fun); +}; + +numeric.pointwise2 = function pointwise2(params,body,setup) +{ + if(typeof setup === "undefined") { setup = ""; } + var fun = []; + var k; + var avec = /\[i\]$/,p,thevec = ''; + var haveret = false; + for(k=0;k=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.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']; + +numeric.ops1 = { + neg: '-', + not: '!', + bnot: '~', + 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;'] +}; + +(function () { + var i,o; + for(i=0;iv0) { i0 = i; v0 = k; } } + Aj = A[i0]; A[i0] = A[j]; A[j] = Aj; + Ij = I[i0]; I[i0] = I[j]; I[j] = Ij; + x = Aj[j]; + for(k=j;k!==n;++k) Aj[k] /= x; + for(k=n-1;k!==-1;--k) Ij[k] /= x; + for(i=m-1;i!==-1;--i) { + if(i!==j) { + Ai = A[i]; + Ii = I[i]; + x = Ai[j]; + for(k=j+1;k!==n;++k) Ai[k] -= Aj[k]*x; + for(k=n-1;k>0;--k) { Ii[k] -= Ij[k]*x; --k; Ii[k] -= Ij[k]*x; } + if(k===0) Ii[0] -= Ij[0]*x; + } + } + } + return I; +}; + +numeric.det = function det(x) { + var s = numeric.dim(x); + if(s.length !== 2 || s[0] !== s[1]) { throw new Error('numeric: det() only works on square matrices'); } + var n = s[0], ret = 1,i,j,k,A = numeric.clone(x),Aj,Ai,alpha,temp,k1,k2,k3; + for(j=0;j Math.abs(A[k][j])) { k = i; } } + if(k !== j) { + temp = A[k]; A[k] = A[j]; A[j] = temp; + ret *= -1; + } + Aj = A[j]; + for(i=j+1;i=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]; + --j; + Bj = ret[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]; + } + } + if(i===0) { + A0 = x[0]; + for(j=n-1;j>=1;--j) { + ret[j][0] = A0[j]; + --j; + ret[j][0] = A0[j]; + } + if(j===0) { ret[0][0] = A0[0]; } + } + return ret; +}; + +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]; + --j; + Bj = ret[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]; + } + } + if(i===0) { + A0 = x[0]; + for(j=n-1;j>=1;--j) { + ret[j][0] = -A0[j]; + --j; + ret[j][0] = -A0[j]; + } + if(j===0) { ret[0][0] = -A0[0]; } + } + return ret; +}; + +numeric._random = function _random(s,k) { + var i,n=s[k],ret=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(); + } + if(i===0) { ret[0] = rnd(); } + return ret; + } + for(i=n-1;i>=0;i--) ret[i] = _random(s,k+1); + return ret; +}; + +numeric.random = function random(s) { return numeric._random(s,0); }; + +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); + n--; + for(i=n;i>=0;i--) { ret[i] = (i*b+(n-i)*a)/n; } + return ret; +}; + +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--) { ret[i] = foo(x[i+a],k+1); } + return ret; + } + return foo(x,0); +}; + +numeric.setBlock = function setBlock(x,from,to,B) { + var s = numeric.dim(x); + function foo(x,y,k) { + var i,a = from[k], n = to[k]-a; + if(k === s.length-1) { for(i=n;i>=0;i--) { x[i+a] = y[i]; } } + for(i=n;i>=0;i--) { foo(x[i+a],y[i],k+1); } + } + foo(x,B,0); + return x; +}; + +numeric.getRange = function getRange(A, I,J ) { + var m = I.length, n = J.length; + var i,j; + var B = Array(m), Bi, AI; + for(i=m-1;i!==-1;--i) { + B[i] = Array(n); + Bi = B[i]; + AI = A[I[i]]; + for(j=n-1;j!==-1;--j) Bi[j] = AI[J[j]]; + } + return B; +}; + +numeric.blockMatrix = function blockMatrix(X) { + var s = numeric.dim(X); + if(s.length<4) return numeric.blockMatrix([X]); + var m=s[0],n=s[1],M,N,i,j,Xij; + M = 0; N = 0; + for(i=0;i=0;i--) { + Ai = Array(n); + xi = x[i]; + for(j=n-1;j>=3;--j) { + Ai[j] = xi * y[j]; + --j; + Ai[j] = xi * y[j]; + --j; + Ai[j] = xi * y[j]; + --j; + Ai[j] = xi * y[j]; + } + while(j>=0) { Ai[j] = xi * y[j]; --j; } + A[i] = Ai; + } + return A; +}; + +// 3. The Tensor type T +numeric.T = function T(x,y) { this.x = x; this.y = y; }; +numeric.t = function t(x,y) { return new numeric.T(x,y); }; + +numeric.Tbinop = function Tbinop(rr,rc,cr,cc,setup) { + var io = numeric.indexOf; + if(typeof setup !== "string") { + var k; + setup = ''; + for(k in numeric) { + if(numeric.hasOwnProperty(k) && (rr.indexOf(k)>=0 || rc.indexOf(k)>=0 || cr.indexOf(k)>=0 || cc.indexOf(k)>=0) && k.length>1) { + setup += 'var '+k+' = numeric.'+k+';\n'; + } + } + } + return numeric.compile(['y'], + 'var x = this;\n'+ + 'if(!(y instanceof numeric.T)) { y = new numeric.T(y); }\n'+ + setup+'\n'+ + 'if(x.y) {'+ + ' if(y.y) {'+ + ' return new numeric.T('+cc+');\n'+ + ' }\n'+ + ' return new numeric.T('+cr+');\n'+ + '}\n'+ + 'if(y.y) {\n'+ + ' return new numeric.T('+rc+');\n'+ + '}\n'+ + 'return new numeric.T('+rr+');\n' + ); +}; + +numeric.T.prototype.add = numeric.Tbinop( + 'add(x.x,y.x)', + 'add(x.x,y.x),y.y', + 'add(x.x,y.x),x.y', + 'add(x.x,y.x),add(x.y,y.y)'); +numeric.T.prototype.sub = numeric.Tbinop( + 'sub(x.x,y.x)', + 'sub(x.x,y.x),neg(y.y)', + 'sub(x.x,y.x),x.y', + 'sub(x.x,y.x),sub(x.y,y.y)'); +numeric.T.prototype.mul = numeric.Tbinop( + 'mul(x.x,y.x)', + 'mul(x.x,y.x),mul(x.x,y.y)', + 'mul(x.x,y.x),mul(x.y,y.x)', + 'sub(mul(x.x,y.x),mul(x.y,y.y)),add(mul(x.x,y.y),mul(x.y,y.x))'); + +numeric.T.prototype.reciprocal = function reciprocal() { + var mul = numeric.mul, div = numeric.div; + if(this.y) { + 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 numeric.T(div(1,this.x), 0); +}; + +numeric.T.prototype.div = function div(y) { + if(!(y instanceof numeric.T)) y = new numeric.T(y); + if(y.y) { return this.mul(y.reciprocal()); } + var div = numeric.div; + if(this.y) { return new numeric.T(div(this.x,y.x),div(this.y,y.x)); } + return new numeric.T(div(this.x,y.x)); +}; + +numeric.T.prototype.dot = numeric.Tbinop( + 'dot(x.x,y.x)', + 'dot(x.x,y.x),dot(x.x,y.y)', + 'dot(x.x,y.x),dot(x.y,y.x)', + 'sub(dot(x.x,y.x),dot(x.y,y.y)),add(dot(x.x,y.y),dot(x.y,y.x))' + ); + +numeric.T.prototype.transpose = function transpose() { + var t = numeric.transpose, x = this.x, y = this.y; + if(y) { return new numeric.T(t(x),t(y)); } + return new numeric.T(t(x)); +}; + +numeric.T.prototype.transjugate = function transjugate() { + var t = numeric.transpose, x = this.x, y = this.y; + if(y) { return new numeric.T(t(x),numeric.negtranspose(y)); } + return new numeric.T(t(x)); +}; + +numeric.Tunop = function Tunop(r,c,s) { + if(typeof s !== "string") { s = ''; } + return numeric.compile( + 'var x = this;\n'+ + s+'\n'+ + 'if(x.y) {'+ + ' '+c+'\n'+ + '}\n'+ + r+'\n' + ); +}; + +numeric.T.prototype.exp = numeric.Tunop( + 'return new numeric.T(ex);', + 'return new numeric.T(mul(cos(x.y),ex),mul(sin(x.y),ex));', + 'var ex = numeric.exp(x.x), cos = numeric.cos, sin = numeric.sin, mul = numeric.mul;'); +numeric.T.prototype.conj = numeric.Tunop( + 'return new numeric.T(x.x);', + 'return new numeric.T(x.x,numeric.neg(x.y));'); +numeric.T.prototype.neg = numeric.Tunop( + 'return new numeric.T(neg(x.x));', + 'return new numeric.T(neg(x.x),neg(x.y));', + 'var neg = numeric.neg;'); +numeric.T.prototype.sin = numeric.Tunop( + 'return new numeric.T(numeric.sin(x.x));', + 'return x.exp().sub(x.neg().exp()).div(new numeric.T(0,2));'); +numeric.T.prototype.cos = numeric.Tunop( + 'return new numeric.T(numeric.cos(x.x));', + 'return x.exp().add(x.neg().exp()).div(2);'); +numeric.T.prototype.abs = numeric.Tunop( + 'return new numeric.T(numeric.abs(x.x));', + 'return new numeric.T(numeric.sqrt(numeric.add(mul(x.x,x.x),mul(x.y,x.y))));', + 'var mul = numeric.mul;'); +numeric.T.prototype.log = numeric.Tunop( + 'return new numeric.T(numeric.log(x.x));', + 'var theta = new numeric.T(numeric.atan2(x.y,x.x)), r = x.abs();\n'+ + 'return new numeric.T(numeric.log(r.x),theta.x);'); +numeric.T.prototype.norm2 = numeric.Tunop( + 'return numeric.norm2(x.x);', + 'var f = numeric.norm2Squared;\n'+ + 'return Math.sqrt(f(x.x)+f(x.y));'); + +numeric.T.prototype.inv = function inv() { + var A = this; + if(typeof A.y === "undefined") { return new numeric.T(numeric.inv(A.x)); } + var n = A.x.length, i, j, k; + var Rx = numeric.identity(n),Ry = numeric.rep([n,n],0); + var Ax = numeric.clone(A.x), Ay = numeric.clone(A.y); + var Aix, Aiy, Ajx, Ajy, Rix, Riy, Rjx, Rjy; + var i,j,k,d,d1,ax,ay,bx,by,temp; + for(i=0;i d) { k=j; d = d1; } + } + if(k!==i) { + temp = Ax[i]; Ax[i] = Ax[k]; Ax[k] = temp; + temp = Ay[i]; Ay[i] = Ay[k]; Ay[k] = temp; + temp = Rx[i]; Rx[i] = Rx[k]; Rx[k] = temp; + temp = Ry[i]; Ry[i] = Ry[k]; Ry[k] = temp; + } + Aix = Ax[i]; Aiy = Ay[i]; + Rix = Rx[i]; Riy = Ry[i]; + ax = Aix[i]; ay = Aiy[i]; + for(j=i+1;j0;i--) { + Rix = Rx[i]; Riy = Ry[i]; + for(j=i-1;j>=0;j--) { + Rjx = Rx[j]; Rjy = Ry[j]; + ax = Ax[j][i]; ay = Ay[j][i]; + for(k=n-1;k>=0;k--) { + bx = Rix[k]; by = Riy[k]; + Rjx[k] -= ax*bx - ay*by; + Rjy[k] -= ax*by + ay*bx; + } + } + } + return new numeric.T(Rx,Ry); +}; + +numeric.T.prototype.get = function get(i) { + var x = this.x, y = this.y, k = 0, ik, n = i.length; + if(y) { + while(k= 0 ? 1 : -1; + var alpha = s*numeric.norm2(x); + v[0] += alpha; + var foo = numeric.norm2(v); + if(foo === 0) { /* this should not happen */ throw new Error('eig: internal error'); } + return numeric.div(v,foo); +}; + +// upper hessenberg +numeric.toUpperHessenberg = function toUpperHessenberg(me) { + var s = numeric.dim(me); + if(s.length !== 2 || s[0] !== s[1]) { throw new Error('numeric: toUpperHessenberg() only works on square matrices'); } + var m = s[0], i,j,k,x,v,A = numeric.clone(me),B,C,Ai,Ci,Q = numeric.identity(m),Qi; + for(j=0;j0) { + v = numeric.house(x); + B = numeric.getBlock(A,[j+1,j],[m-1,m-1]); + C = numeric.tensor(v,numeric.dot(v,B)); + for(i=j+1;i=4*det) { + var s1,s2; + s1 = 0.5*(tr+Math.sqrt(tr*tr-4*det)); + s2 = 0.5*(tr-Math.sqrt(tr*tr-4*det)); + Hloc = numeric.add(numeric.sub(numeric.dot(Hloc,Hloc), + numeric.mul(Hloc,s1+s2)), + numeric.diag(numeric.rep([3],s1*s2))); + } else { + Hloc = numeric.add(numeric.sub(numeric.dot(Hloc,Hloc), + numeric.mul(Hloc,tr)), + numeric.diag(numeric.rep([3],det))); + } + x = [Hloc[0][0],Hloc[1][0],Hloc[2][0]]; + v = numeric.house(x); + B = [H[0],H[1],H[2]]; + C = numeric.tensor(v,numeric.dot(v,B)); + for(i=0;i<3;i++) { Hi = H[i]; Ci = C[i]; for(k=0;k 4 && termp == Math.abs(d[p]) && termq == Math.abs(d[q])) + { + // remove small elmts + A[p][q] = 0; + } + else + { + if (Math.abs(A[p][q]) >= tresh) + { + // apply rotation + h = d[q] - d[p]; + term = Math.abs(h) + gapq; + if (term == Math.abs(h)) + { + t = A[p][q]/h; + } + else + { + theta = 0.5 * h / A[p][q]; + t = 1/(Math.abs(theta) + Math.sqrt(1 + theta*theta)); + if (theta < 0) + { + t = -t; + } + } + c = 1/Math.sqrt(1 + t*t); + s = t * c; + tau = s/(1 + c); + h = t * A[p][q]; + zw[p] = zw[p] - h; + zw[q] = zw[q] + h; + d[p] = d[p] - h; + d[q] = d[q] + h; + A[p][q] = 0; + // rotate and use upper tria only + for (var j = 0; j < p; j++) + { + g = A[j][p]; + h = A[j][q]; + A[j][p] = g - s * (h + g * tau); + A[j][q] = h + s * (g - h * tau); + } + for (var j = p + 1; j < q; j++) + { + g = A[p][j]; + h = A[j][q]; + A[p][j] = g - s * (h + g * tau); + A[j][q] = h + s * (g - h * tau); + } + for (var j = q + 1; j < n; j++) + { + g = A[p][j]; + h = A[q][j]; + A[p][j] = g - s * (h + g * tau); + A[q][j] = h + s * (g - h * tau); + } + // eigenstates + for (var j = 0; j < n; j++) + { + g = v[j][p]; + h = v[j][q]; + v[j][p] = g - s * (h + g * tau); + v[j][q] = h + s * (g - h * tau); + } + nrot++; + } + } + } + } + bw = numeric.add(bw, zw); + d = numeric.clone(bw); + zw = numeric.rep([n], 0); + } + + return {E: {x: v}, lambda: {x: d}, iterations: iters, niter: niter, nrot: nrot}; +} + +numeric.jacobinorm = function(A) +{ + // used in numeric.jacobi + var n = A.length; + var s = 0; + for (var i = 0; i < n; i ++) + { + for (var j = i + 1; j < n; j ++) + { + s = s + Math.pow(A[i][j], 2) + } + } + return Math.sqrt(s); +} + +// eig function +numeric.eig = function eig(A,maxiter) { + var QH = numeric.toUpperHessenberg(A); + var QB = numeric.QRFrancis(QH.H,maxiter); + var T = numeric.T; + var n = A.length,i,k,flag = false,B = QB.B,H = numeric.dot(QB.Q,numeric.dot(QH.H,numeric.transpose(QB.Q))); + var Q = new T(numeric.dot(QB.Q,QH.Q)),Q0; + var m = B.length,j; + var a,b,c,d,p1,p2,disc,x,y,p,q,n1,n2; + var sqrt = Math.sqrt; + for(k=0;k=0) { + if(p1<0) x = -0.5*(p1-sqrt(disc)); + else x = -0.5*(p1+sqrt(disc)); + n1 = (a-x)*(a-x)+b*b; + n2 = c*c+(d-x)*(d-x); + if(n1>n2) { + n1 = sqrt(n1); + p = (a-x)/n1; + q = b/n1; + } else { + n2 = sqrt(n2); + p = c/n2; + q = (d-x)/n2; + } + Q0 = new T([[q,-p],[p,q]]); + Q.setRows(i,j,Q0.dot(Q.getRows(i,j))); + } else { + x = -0.5*p1; + y = 0.5*sqrt(-disc); + n1 = (a-x)*(a-x)+b*b; + n2 = c*c+(d-x)*(d-x); + if(n1>n2) { + n1 = sqrt(n1+y*y); + p = (a-x)/n1; + q = b/n1; + x = 0; + y /= n1; + } else { + n2 = sqrt(n2+y*y); + p = c/n2; + q = (d-x)/n2; + x = y/n2; + y = 0; + } + Q0 = new T([[q,-p],[p,q]],[[x,y],[y,-x]]); + Q.setRows(i,j,Q0.dot(Q.getRows(i,j))); + } + } + } + var R = Q.dot(A).dot(Q.transjugate()), n = A.length, E = numeric.T.identity(n); + for(j=0;j0) { + for(k=j-1;k>=0;k--) { + var Rk = R.get([k,k]), Rj = R.get([j,j]); + if(numeric.neq(Rk.x,Rj.x) || numeric.neq(Rk.y,Rj.y)) { + x = R.getRow(k).getBlock([k],[j-1]); + y = E.getRow(j).getBlock([k],[j-1]); + E.set([j,k],(R.get([k,j]).neg().sub(x.dot(y))).div(Rk.sub(Rj))); + } else { + E.setRow(j,E.getRow(k)); + continue; + } + } + } + } + for(j=0;j=counts.length) counts[counts.length] = 0; + if(foo[j]!==0) counts[j]++; + } + } + var n = counts.length; + var Ai = Array(n+1); + Ai[0] = 0; + for(i=0;i= k11) { + xj[n] = j[m]; + if(m===0) return; + ++n; + --m; + km = k[m]; + k11 = k1[m]; + } else { + foo = Pinv[Aj[km]]; + if(x[foo] === 0) { + x[foo] = 1; + k[m] = km; + ++m; + j[m] = foo; + km = Ai[foo]; + k1[m] = k11 = Ai[foo+1]; + } else ++km; + } + } +}; + +numeric.ccsLPSolve = function ccsLPSolve(A,B,x,xj,I,Pinv,dfs) { + var Ai = A[0], Aj = A[1], Av = A[2],m = Ai.length-1, n=0; + var Bi = B[0], Bj = B[1], Bv = B[2]; + + var i,i0,i1,j,J,j0,j1,k,l,l0,l1,a; + i0 = Bi[I]; + i1 = Bi[I+1]; + xj.length = 0; + for(i=i0;i a) { e = k; a = c; } + } + if(abs(x[i])= k11) { + xj[n] = Pinv[j[m]]; + if(m===0) return; + ++n; + --m; + km = k[m]; + k11 = k1[m]; + } else { + foo = Aj[km]; + if(x[foo] === 0) { + x[foo] = 1; + k[m] = km; + ++m; + j[m] = foo; + foo = Pinv[foo]; + km = Ai[foo]; + k1[m] = k11 = Ai[foo+1]; + } else ++km; + } + } +}; + +numeric.ccsLPSolve0 = function ccsLPSolve0(A,B,y,xj,I,Pinv,P,dfs) { + var Ai = A[0], Aj = A[1], Av = A[2],m = Ai.length-1, n=0; + var Bi = B[0], Bj = B[1], Bv = B[2]; + + var i,i0,i1,j,J,j0,j1,k,l,l0,l1,a; + i0 = Bi[I]; + i1 = Bi[I+1]; + xj.length = 0; + for(i=i0;i a) { e = k; a = c; } + } + if(abs(y[P[i]]) ret[k]) ret[k] = A.length; + var i; + for(i in A) { + if(A.hasOwnProperty(i)) dim(A[i],ret,k+1); + } + return ret; +}; + +numeric.sclone = function clone(A,k,n) { + if(typeof k === "undefined") { k=0; } + if(typeof n === "undefined") { n = numeric.sdim(A).length; } + var i,ret = Array(A.length); + if(k === n-1) { + for(i in A) { if(A.hasOwnProperty(i)) ret[i] = A[i]; } + return ret; + } + for(i in A) { + if(A.hasOwnProperty(i)) ret[i] = clone(A[i],k+1,n); + } + return ret; +}; + +numeric.sdiag = function diag(d) { + var n = d.length,i,ret = Array(n),i1,i2,i3; + for(i=n-1;i>=1;i-=2) { + i1 = i-1; + ret[i] = []; ret[i][i] = d[i]; + ret[i1] = []; ret[i1][i1] = d[i1]; + } + if(i===0) { ret[0] = []; ret[0][0] = d[i]; } + return ret; +}; + +numeric.sidentity = function identity(n) { return numeric.sdiag(numeric.rep([n],1)); }; + +numeric.stranspose = function transpose(A) { + var ret = [], n = A.length, i,j,Ai; + for(i in A) { + if(!(A.hasOwnProperty(i))) continue; + Ai = A[i]; + for(j in Ai) { + if(!(Ai.hasOwnProperty(j))) continue; + if(typeof ret[j] !== "object") { ret[j] = []; } + ret[j][i] = Ai[j]; + } + } + return ret; +}; + +numeric.sLUP = function LUP(A,tol) { + throw new Error("The function numeric.sLUP had a bug in it and has been removed. Please use the new numeric.ccsLUP function instead."); +}; + +numeric.sdotMM = function dotMM(A,B) { + var p = A.length, q = B.length, BT = numeric.stranspose(B), r = BT.length, Ai, BTk; + var i,j,k,accum; + var ret = Array(p),reti; + for(i=p-1;i>=0;i--) { + reti = []; + Ai = A[i]; + for(k=r-1;k>=0;k--) { + accum = 0; + BTk = BT[k]; + for(j in Ai) { + if(!(Ai.hasOwnProperty(j))) continue; + if(j in BTk) { accum += Ai[j]*BTk[j]; } + } + if(accum) reti[k] = accum; + } + ret[i] = reti; + } + return ret; +}; + +numeric.sdotMV = function dotMV(A,x) { + var p = A.length, Ai, i,j; + var ret = Array(p), accum; + for(i=p-1;i>=0;i--) { + Ai = A[i]; + accum = 0; + for(j in Ai) { + if(!(Ai.hasOwnProperty(j))) continue; + if(x[j]) accum += Ai[j]*x[j]; + } + if(accum) ret[i] = accum; + } + return ret; +}; + +numeric.sdotVM = function dotMV(x,A) { + var i,j,Ai,alpha; + var ret = [], 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]; + } + } + return ret; +}; + +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; +}; + +numeric.sdot = function dot(A,B) { + var m = numeric.sdim(A).length, n = numeric.sdim(B).length; + var k = m*1000+n; + switch(k) { + case 0: return A*B; + case 1001: return numeric.sdotVV(A,B); + case 2001: return numeric.sdotMV(A,B); + case 1002: return numeric.sdotVM(A,B); + case 2002: return numeric.sdotMM(A,B); + default: throw new Error('numeric.sdot not implemented for tensors of order '+m+' and '+n); + } +}; + +numeric.sscatter = function scatter(V) { + var n = V[0].length, Vij, i, j, m = V.length, A = [], Aj; + for(i=n-1;i>=0;--i) { + if(!V[m-1][i]) continue; + Aj = A; + for(j=0;j=0;--i) ret[i] = []; + } + for(i=n;i>=0;--i) ret[i].push(k[i]); + ret[n+1].push(Ai); + } + } else gather(Ai,ret,k); + } + } + if(k.length>n) k.pop(); + return ret; +}; + +// 6. Coordinate matrices +numeric.cLU = function LU(A) { + var I = A[0], J = A[1], V = A[2]; + var p = I.length, m=0, i,j,k,a,b,c; + for(i=0;im) m=I[i]; + m++; + var L = Array(m), U = Array(m), left = numeric.rep([m],Infinity), right = numeric.rep([m],-Infinity); + var Ui, Uj,alpha; + for(k=0;kright[i]) right[i] = j; + } + for(i=0;i right[i+1]) right[i+1] = right[i]; } + for(i=m-1;i>=1;i--) { if(left[i]=0;i--) { + while(Uj[k] > i) { + ret[i] -= Uv[k]*ret[Uj[k]]; + k--; + } + ret[i] /= Uv[k]; + k--; + } + return ret; +}; + +numeric.cgrid = function grid(n,shape) { + if(typeof n === "number") n = [n,n]; + var ret = numeric.rep(n,-1); + var i,j,count; + if(typeof shape !== "function") { + switch(shape) { + case 'L': + shape = function(i,j) { return (i>=n[0]/2 || jN) N = Ai[k]; } + N++; + ret = numeric.rep([N],0); + for(k=0;k1) { + mid = floor((p+q)/2); + if(x[mid] <= x0) p = mid; + else q = mid; + } + return this._at(x0,p); + } + var n = x0.length, i, ret = Array(n); + for(i=n-1;i!==-1;--i) ret[i] = this.at(x0[i]); + return ret; +}; + +numeric.Spline.prototype.diff = function diff() { + var x = this.x; + var yl = this.yl; + var yr = this.yr; + var kl = this.kl; + var kr = this.kr; + var n = yl.length; + var i,dx,dy; + var zl = kl, zr = kr, pl = Array(n), pr = Array(n); + var add = numeric.add, mul = numeric.mul, div = numeric.div, sub = numeric.sub; + for(i=n-1;i!==-1;--i) { + dx = x[i+1]-x[i]; + dy = sub(yr[i+1],yl[i]); + pl[i] = div(add(mul(dy, 6),mul(kl[i],-4*dx),mul(kr[i+1],-2*dx)),dx*dx); + pr[i+1] = div(add(mul(dy,-6),mul(kl[i], 2*dx),mul(kr[i+1], 4*dx)),dx*dx); + } + return new numeric.Spline(x,zl,zr,pl,pr); +}; + +numeric.Spline.prototype.roots = function roots() { + function sqr(x) { return x*x; } + function heval(y0,y1,k0,k1,x) { + var A = k0*2-(y1-y0); + var B = -k1*2+(y1-y0); + var t = (x+1)*0.5; + var s = t*(1-t); + return (1-t)*y0+t*y1+A*s*(1-t)+B*s*t; + } + var ret = []; + var x = this.x, yl = this.yl, yr = this.yr, kl = this.kl, kr = this.kr; + if(typeof yl[0] === "number") { + yl = [yl]; + yr = [yr]; + kl = [kl]; + kr = [kr]; + } + var m = yl.length,n=x.length-1,i,j,k,y,s,t; + var ai,bi,ci,di, ret = Array(m),ri,k0,k1,y0,y1,A,B,D,dx,cx,stops,z0,z1,zm,t0,t1,tm; + var sqrt = Math.sqrt; + for(i=0;i!==m;++i) { + ai = yl[i]; + bi = yr[i]; + ci = kl[i]; + di = kr[i]; + ri = []; + for(j=0;j!==n;j++) { + if(j>0 && bi[j]*ai[j]<0) ri.push(x[j]); + dx = (x[j+1]-x[j]); + cx = x[j]; + y0 = ai[j]; + y1 = bi[j+1]; + k0 = ci[j]/dx; + k1 = di[j+1]/dx; + D = sqr(k0-k1+3*(y0-y1)) + 12*k1*y0; + A = k1+3*y0+2*k0-3*y1; + B = 3*(k1+k0+2*(y0-y1)); + if(D<=0) { + z0 = A/B; + if(z0>x[j] && z0x[j] && z0x[j] && z10) { + t0 = t1; + z0 = z1; + continue; + } + var side = 0; + while(1) { + tm = (z0*t1-z1*t0)/(z0-z1); + if(tm <= t0 || tm >= t1) { break; } + zm = this._at(tm,j); + if(zm*z1>0) { + t1 = tm; + z1 = zm; + if(side === -1) z0*=0.5; + side = -1; + } else if(zm*z0>0) { + t0 = tm; + z0 = zm; + if(side === 1) z1*=0.5; + side = 1; + } else break; + } + ri.push(tm); + t0 = stops[k+1]; + z0 = this._at(t0, j); + } + if(z1 === 0) ri.push(t1); + } + ret[i] = ri; + } + if(typeof this.yl[0] === "number") return ret[0]; + return ret; +}; + +numeric.spline = function spline(x,y,k1,kn) { + var n = x.length, b = [], dx = [], dy = []; + var i; + var sub = numeric.sub,mul = numeric.mul,add = numeric.add; + for(i=n-2;i>=0;i--) { dx[i] = x[i+1]-x[i]; dy[i] = sub(y[i+1],y[i]); } + if(typeof k1 === "string" || typeof kn === "string") { + k1 = kn = "periodic"; + } + // Build sparse tridiagonal system + var T = [[],[],[]]; + switch(typeof k1) { + case "undefined": + b[0] = mul(3/(dx[0]*dx[0]),dy[0]); + T[0].push(0,0); + T[1].push(0,1); + T[2].push(2/dx[0],1/dx[0]); + break; + case "string": + b[0] = add(mul(3/(dx[n-2]*dx[n-2]),dy[n-2]),mul(3/(dx[0]*dx[0]),dy[0])); + T[0].push(0,0,0); + T[1].push(n-2,0,1); + T[2].push(1/dx[n-2],2/dx[n-2]+2/dx[0],1/dx[0]); + break; + default: + b[0] = k1; + T[0].push(0); + T[1].push(0); + T[2].push(1); + break; + } + for(i=1;i20) { throw new Error("Numerical gradient fails"); } + x0[i] = x[i]+h; + f1 = f(x0); + x0[i] = x[i]-h; + f2 = f(x0); + x0[i] = x[i]; + if(isNaN(f1) || isNaN(f2)) { h/=16; continue; } + J[i] = (f1-f2)/(2*h); + t0 = x[i]-h; + t1 = x[i]; + t2 = x[i]+h; + d1 = (f1-f0)/h; + d2 = (f0-f2)/h; + N = max(abs(J[i]),abs(f0),abs(f1),abs(f2),abs(t0),abs(t1),abs(t2),1e-8); + errest = min(max(abs(d1-J[i]),abs(d2-J[i]),abs(d1-d2))/N,h/N); + if(errest>eps) { h/=16; } + else break; + } + } + return J; +}; + +numeric.uncmin = function uncmin(f,x0,tol,gradient,maxit,callback,options) { + var grad = numeric.gradient; + if(typeof options === "undefined") { options = {}; } + if(typeof tol === "undefined") { tol = 1e-8; } + if(typeof gradient === "undefined") { gradient = function(x) { return grad(f,x); }; } + if(typeof maxit === "undefined") maxit = 1000; + x0 = numeric.clone(x0); + var n = x0.length; + var f0 = f(x0),f1,df0; + if(isNaN(f0)) throw new Error('uncmin: f(x0) is a NaN!'); + var max = Math.max, norm2 = numeric.norm2; + tol = max(tol,numeric.epsilon); + var step,g0,g1,H1 = options.Hinv || numeric.identity(n); + var dot = numeric.dot, inv = numeric.inv, sub = numeric.sub, add = numeric.add, ten = numeric.tensor, div = numeric.div, mul = numeric.mul; + var all = numeric.all, isfinite = numeric.isFinite, neg = numeric.neg; + var it=0,i,s,x1,y,Hy,Hs,ys,i0,t,nstep,t1,t2; + var msg = ""; + g0 = gradient(x0); + while(it= 0.1*t*df0 || isNaN(f1)) { + t *= 0.5; + ++it; + continue; + } + break; + } + if(t*nstep < tol) { msg = "Line search step size smaller than tol"; break; } + if(it === maxit) { msg = "maxit reached during line search"; break; } + g1 = gradient(x1); + y = sub(g1,g0); + ys = dot(y,s); + Hy = dot(H1,y); + H1 = sub(add(H1, + mul( + (ys+dot(y,Hy))/(ys*ys), + ten(s,s) )), + div(add(ten(Hy,s),ten(s,Hy)),ys)); + x0 = x1; + f0 = f1; + g0 = g1; + ++it; + } + return {solution: x0, f: f0, gradient: g0, invHessian: H1, iterations:it, message: msg}; +}; + +// 10. Ode solver (Dormand-Prince) +numeric.Dopri = function Dopri(x,y,f,ymid,iterations,msg,events) { + this.x = x; + this.y = y; + this.f = f; + this.ymid = ymid; + this.iterations = iterations; + this.events = events; + this.message = msg; +}; + +numeric.Dopri.prototype._at = function _at(xi,j) { + function sqr(x) { return x*x; } + var sol = this; + var xs = sol.x; + var ys = sol.y; + var k1 = sol.f; + var ymid = sol.ymid; + var n = xs.length; + var x0,x1,xh,y0,y1,yh,xi; + var floor = Math.floor,h; + var c = 0.5; + var add = numeric.add, mul = numeric.mul,sub = numeric.sub, p,q,w; + x0 = xs[j]; + x1 = xs[j+1]; + y0 = ys[j]; + y1 = ys[j+1]; + h = x1-x0; + xh = x0+c*h; + yh = ymid[j]; + p = sub(k1[j ],mul(y0,1/(x0-xh)+2/(x0-x1))); + q = sub(k1[j+1],mul(y1,1/(x1-xh)+2/(x1-x0))); + w = [sqr(xi - x1) * (xi - xh) / sqr(x0 - x1) / (x0 - xh), + sqr(xi - x0) * sqr(xi - x1) / sqr(x0 - xh) / sqr(x1 - xh), + sqr(xi - x0) * (xi - xh) / sqr(x1 - x0) / (x1 - xh), + (xi - x0) * sqr(xi - x1) * (xi - xh) / sqr(x0-x1) / (x0 - xh), + (xi - x1) * sqr(xi - x0) * (xi - xh) / sqr(x0-x1) / (x1 - xh)]; + return add(add(add(add(mul(y0,w[0]), + mul(yh,w[1])), + mul(y1,w[2])), + mul( p,w[3])), + mul( q,w[4])); +}; + +numeric.Dopri.prototype.at = function at(x) { + var i,j,k,floor = Math.floor; + if(typeof x !== "number") { + var n = x.length, ret = Array(n); + for(i=n-1;i!==-1;--i) { + ret[i] = this.at(x[i]); + } + return ret; + } + var x0 = this.x; + i = 0; j = x0.length-1; + while(j-i>1) { + k = floor(0.5*(i+j)); + if(x0[k] <= x) i = k; + else j = k; + } + return this._at(x,i); +}; + +numeric.dopri = function dopri(x0,x1,y0,f,tol,maxit,event) { + if(typeof tol === "undefined") { tol = 1e-6; } + if(typeof maxit === "undefined") { maxit = 1000; } + var xs = [x0], ys = [y0], k1 = [f(x0,y0)], k2,k3,k4,k5,k6,k7, ymid = []; + var A2 = 1/5; + var A3 = [3/40,9/40]; + var A4 = [44/45,-56/15,32/9]; + var A5 = [19372/6561,-25360/2187,64448/6561,-212/729]; + var A6 = [9017/3168,-355/33,46732/5247,49/176,-5103/18656]; + var b = [35/384,0,500/1113,125/192,-2187/6784,11/84]; + var bm = [0.5*6025192743/30085553152, + 0, + 0.5*51252292925/65400821598, + 0.5*-2691868925/45128329728, + 0.5*187940372067/1594534317056, + 0.5*-1776094331/19743644256, + 0.5*11237099/235043384]; + var c = [1/5,3/10,4/5,8/9,1,1]; + var e = [-71/57600,0,71/16695,-71/1920,17253/339200,-22/525,1/40]; + var i = 0,er,j; + var h = (x1-x0)/10; + var it = 0; + var add = numeric.add, mul = numeric.mul, y1,erinf; + var max = Math.max, min = Math.min, abs = Math.abs, norminf = numeric.norminf,pow = Math.pow; + var any = numeric.any, lt = numeric.lt, and = numeric.and, sub = numeric.sub; + var e0, e1, ev; + var ret = new numeric.Dopri(xs,ys,k1,ymid,-1,""); + if(typeof event === "function") e0 = event(x0,y0); + while(x0x1) h = x1-x0; + k2 = f(x0+c[0]*h, add(y0,mul( A2*h,k1[i]))); + k3 = f(x0+c[1]*h, add(add(y0,mul(A3[0]*h,k1[i])),mul(A3[1]*h,k2))); + k4 = f(x0+c[2]*h, add(add(add(y0,mul(A4[0]*h,k1[i])),mul(A4[1]*h,k2)),mul(A4[2]*h,k3))); + k5 = f(x0+c[3]*h, add(add(add(add(y0,mul(A5[0]*h,k1[i])),mul(A5[1]*h,k2)),mul(A5[2]*h,k3)),mul(A5[3]*h,k4))); + k6 = f(x0+c[4]*h,add(add(add(add(add(y0,mul(A6[0]*h,k1[i])),mul(A6[1]*h,k2)),mul(A6[2]*h,k3)),mul(A6[3]*h,k4)),mul(A6[4]*h,k5))); + y1 = add(add(add(add(add(y0,mul(k1[i],h*b[0])),mul(k3,h*b[2])),mul(k4,h*b[3])),mul(k5,h*b[4])),mul(k6,h*b[5])); + k7 = f(x0+h,y1); + er = add(add(add(add(add(mul(k1[i],h*e[0]),mul(k3,h*e[2])),mul(k4,h*e[3])),mul(k5,h*e[4])),mul(k6,h*e[5])),mul(k7,h*e[6])); + if(typeof er === "number") erinf = abs(er); + else erinf = norminf(er); + if(erinf > tol) { // reject + h = 0.2*h*pow(tol/erinf,0.25); + if(x0+h === x0) { + ret.msg = "Step size became too small"; + break; + } + continue; + } + ymid[i] = add(add(add(add(add(add(y0, + mul(k1[i],h*bm[0])), + mul(k3 ,h*bm[2])), + mul(k4 ,h*bm[3])), + mul(k5 ,h*bm[4])), + mul(k6 ,h*bm[5])), + mul(k7 ,h*bm[6])); + ++i; + xs[i] = x0+h; + ys[i] = y1; + k1[i] = k7; + if(typeof event === "function") { + var yi,xl = x0,xr = x0+0.5*h,xi; + e1 = event(xr,ymid[i-1]); + ev = and(lt(e0,0),lt(0,e1)); + if(!any(ev)) { xl = xr; xr = x0+h; e0 = e1; e1 = event(xr,y1); ev = and(lt(e0,0),lt(0,e1)); } + if(any(ev)) { + var xc, yc, en,ei; + var side=0, sl = 1.0, sr = 1.0; + while(1) { + if(typeof e0 === "number") xi = (sr*e1*xl-sl*e0*xr)/(sr*e1-sl*e0); + else { + xi = xr; + for(j=e0.length-1;j!==-1;--j) { + if(e0[j]<0 && e1[j]>0) xi = min(xi,(sr*e1[j]*xl-sl*e0[j]*xr)/(sr*e1[j]-sl*e0[j])); + } + } + if(xi <= xl || xi >= xr) break; + yi = ret._at(xi, i-1); + ei = event(xi,yi); + en = and(lt(e0,0),lt(0,ei)); + if(any(en)) { + xr = xi; + e1 = ei; + ev = en; + sr = 1.0; + if(side === -1) sl *= 0.5; + else sl = 1.0; + side = -1; + } else { + xl = xi; + e0 = ei; + sl = 1.0; + if(side === 1) sr *= 0.5; + else sr = 1.0; + side = 1; + } + } + y1 = ret._at(0.5*(x0+xi),i-1); + ret.f[i] = f(xi,yi); + ret.x[i] = xi; + ret.y[i] = yi; + ret.ymid[i-1] = y1; + ret.events = ev; + ret.iterations = it; + return ret; + } + } + x0 += h; + y0 = y1; + e0 = e1; + h = min(0.8*h*pow(tol/erinf,0.25),4*h); + } + ret.iterations = it; + return ret; +}; + +// 11. Ax = b +numeric.LU = function(A, fast) { + fast = fast || false; + + var abs = Math.abs; + var i, j, k, absAjk, Akk, Ak, Pk, Ai; + var max; + var n = A.length, n1 = n-1; + var P = new Array(n); + if(!fast) A = numeric.clone(A); + + for (k = 0; k < n; ++k) { + Pk = k; + Ak = A[k]; + max = abs(Ak[k]); + for (j = k + 1; j < n; ++j) { + absAjk = abs(A[j][k]); + if (max < absAjk) { + max = absAjk; + Pk = j; + } + } + P[k] = Pk; + + if (Pk != k) { + A[k] = A[Pk]; + A[Pk] = Ak; + Ak = A[k]; + } + + Akk = Ak[k]; + + for (i = k + 1; i < n; ++i) { + A[i][k] /= Akk; + } + + for (i = k + 1; i < n; ++i) { + Ai = A[i]; + for (j = k + 1; j < n1; ++j) { + Ai[j] -= Ai[k] * Ak[j]; + ++j; + Ai[j] -= Ai[k] * Ak[j]; + } + if(j===n1) Ai[j] -= Ai[k] * Ak[j]; + } + } + + return { + LU: A, + P: P + }; +}; + +numeric.LUsolve = function LUsolve(LUP, b) { + var i, j; + var LU = LUP.LU; + var n = LU.length; + var x = numeric.clone(b); + var P = LUP.P; + var Pi, LUi, LUii, tmp; + + for (i=n-1;i!==-1;--i) x[i] = b[i]; + for (i = 0; i < n; ++i) { + Pi = P[i]; + if (P[i] !== i) { + tmp = x[i]; + x[i] = x[Pi]; + x[Pi] = tmp; + } + + LUi = LU[i]; + for (j = 0; j < i; ++j) { + x[i] -= x[j] * LUi[j]; + } + } + + for (i = n - 1; i >= 0; --i) { + LUi = LU[i]; + for (j = i + 1; j < n; ++j) { + x[i] -= x[j] * LUi[j]; + } + + x[i] /= LUi[i]; + } + + return x; +}; + +numeric.solve = function solve(A,b,fast) { return numeric.LUsolve(numeric.LU(A,fast), b); }; + +// 12. Linear programming +numeric.echelonize = function echelonize(A) { + var s = numeric.dim(A), m = s[0], n = s[1]; + var I = numeric.identity(m); + var P = Array(m); + var i,j,k,l,Ai,Ii,Z,a; + var abs = Math.abs; + var diveq = numeric.diveq; + A = numeric.clone(A); + for(i=0;ia1) alpha = a1; + g = add(c,mul(alpha,p)); + H = dot(A1,A0); + for(i=m-1;i!==-1;--i) H[i][i] += 1; + d = solve(H,div(g,alpha),true); + var t0 = div(z,dot(A,d)); + var t = 1.0; + for(i=n-1;i!==-1;--i) if(t0[i]<0) t = min(t,-0.999*t0[i]); + y = sub(x,mul(d,t)); + z = sub(b,dot(A,y)); + if(!all(gt(z,0))) return { solution: x, message: "", iterations: count }; + x = y; + if(alpha=0) unbounded = false; + else unbounded = true; + } + if(unbounded) return { solution: y, message: "Unbounded", iterations: count }; + } + return { solution: x, message: "maximum iteration count exceeded", iterations:count }; +}; + +numeric._solveLP = function _solveLP(c,A,b,tol,maxit) { + var m = c.length, n = b.length,y; + var sum = numeric.sum, log = numeric.log, mul = numeric.mul, sub = numeric.sub, dot = numeric.dot, div = numeric.div, add = numeric.add; + var c0 = numeric.rep([m],0).concat([1]); + var J = numeric.rep([n,1],-1); + var A0 = numeric.blockMatrix([[A , J ]]); + var b0 = b; + var y = numeric.rep([m],0).concat(Math.max(0,numeric.sup(numeric.neg(b)))+1); + var x0 = numeric.__solveLP(c0,A0,b0,tol,maxit,y,false); + var x = numeric.clone(x0.solution); + x.length = m; + var foo = numeric.inf(sub(b,dot(A,x))); + if(foo<0) { return { solution: NaN, message: "Infeasible", iterations: x0.iterations }; } + var ret = numeric.__solveLP(c, A, b, tol, maxit-x0.iterations, x, true); + ret.iterations += x0.iterations; + return ret; +}; + +numeric.solveLP = function solveLP(c,A,b,Aeq,beq,tol,maxit) { + if(typeof maxit === "undefined") maxit = 1000; + if(typeof tol === "undefined") tol = numeric.epsilon; + if(typeof Aeq === "undefined") return numeric._solveLP(c,A,b,tol,maxit); + var m = Aeq.length, n = Aeq[0].length, o = A.length; + var B = numeric.echelonize(Aeq); + var flags = numeric.rep([n],0); + var P = B.P; + var Q = []; + var i; + for(i=P.length-1;i!==-1;--i) flags[P[i]] = 1; + for(i=n-1;i!==-1;--i) if(flags[i]===0) Q.push(i); + var g = numeric.getRange; + var I = numeric.linspace(0,m-1), J = numeric.linspace(0,o-1); + var Aeq2 = g(Aeq,I,Q), A1 = g(A,J,P), A2 = g(A,J,Q), dot = numeric.dot, sub = numeric.sub; + var A3 = dot(A1,B.I); + var A4 = sub(A2,dot(A3,Aeq2)), b4 = sub(b,dot(A3,beq)); + var c1 = Array(P.length), c2 = Array(Q.length); + for(i=P.length-1;i!==-1;--i) c1[i] = c[P[i]]; + for(i=Q.length-1;i!==-1;--i) c2[i] = c[Q[i]]; + var c4 = sub(c2,dot(c1,dot(B.I,Aeq2))); + var S = numeric._solveLP(c4,A4,b4,tol,maxit); + var x2 = S.solution; + if(x2!==x2) return S; + var x1 = dot(B.I,sub(beq,dot(Aeq2,x2))); + var x = Array(c.length); + for(i=P.length-1;i!==-1;--i) x[P[i]] = x1[i]; + for(i=Q.length-1;i!==-1;--i) x[Q[i]] = x2[i]; + return { solution: x, message:S.message, iterations: S.iterations }; +}; + +numeric.MPStoLP = function MPStoLP(MPS) { + if(MPS instanceof String) { MPS.split('\n'); } + var state = 0; + var states = ['Initial state','NAME','ROWS','COLUMNS','RHS','BOUNDS','ENDATA']; + var n = MPS.length; + var i,j,z,N=0,rows = {}, sign = [], rl = 0, vars = {}, nv = 0; + var name; + var c = [], A = [], b = []; + function err(e) { throw new Error('MPStoLP: '+e+'\nLine '+i+': '+MPS[i]+'\nCurrent state: '+states[state]+'\n'); } + for(i=0;i +// +// Math.seedrandom('yipee'); Sets Math.random to a function that is +// initialized using the given explicit seed. +// +// Math.seedrandom(); Sets Math.random to a function that is +// seeded using the current time, dom state, +// and other accumulated local entropy. +// The generated seed string is returned. +// +// Math.seedrandom('yowza', true); +// Seeds using the given explicit seed mixed +// together with accumulated entropy. +// +// +// Seeds using physical random bits downloaded +// from random.org. +// +// Seeds using urandom bits from call.jsonlib.com, +// which is faster than random.org. +// +// Examples: +// +// Math.seedrandom("hello"); // Use "hello" as the seed. +// document.write(Math.random()); // Always 0.5463663768140734 +// document.write(Math.random()); // Always 0.43973793770592234 +// var rng1 = Math.random; // Remember the current prng. +// +// var autoseed = Math.seedrandom(); // New prng with an automatic seed. +// document.write(Math.random()); // Pretty much unpredictable. +// +// Math.random = rng1; // Continue "hello" prng sequence. +// document.write(Math.random()); // Always 0.554769432473455 +// +// Math.seedrandom(autoseed); // Restart at the previous seed. +// document.write(Math.random()); // Repeat the 'unpredictable' value. +// +// Notes: +// +// Each time seedrandom('arg') is called, entropy from the passed seed +// is accumulated in a pool to help generate future seeds for the +// zero-argument form of Math.seedrandom, so entropy can be injected over +// time by calling seedrandom with explicit data repeatedly. +// +// On speed - This javascript implementation of Math.random() is about +// 3-10x slower than the built-in Math.random() because it is not native +// code, but this is typically fast enough anyway. Seeding is more expensive, +// especially if you use auto-seeding. Some details (timings on Chrome 4): +// +// Our Math.random() - avg less than 0.002 milliseconds per call +// seedrandom('explicit') - avg less than 0.5 milliseconds per call +// seedrandom('explicit', true) - avg less than 2 milliseconds per call +// seedrandom() - avg about 38 milliseconds per call +// +// LICENSE (BSD): +// +// Copyright 2010 David Bau, all rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of this module nor the names of its contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/** + * All code is in an anonymous closure to keep the global namespace clean. + * + * @param {number=} overflow + * @param {number=} startdenom + */ + +// Patched by Seb so that seedrandom.js does not pollute the Math object. +// My tests suggest that doing Math.trouble = 1 makes Math lookups about 5% +// slower. +numeric.seedrandom = { pow:Math.pow, random:Math.random }; + +(function (pool, math, width, chunks, significance, overflow, startdenom) { + + +// +// seedrandom() +// This is the seedrandom function described above. +// +math['seedrandom'] = function seedrandom(seed, use_entropy) { + var key = []; + var arc4; + + // Flatten the seed string or build one from local entropy if needed. + seed = mixkey(flatten( + use_entropy ? [seed, pool] : + arguments.length ? seed : + [new Date().getTime(), pool, window], 3), key); + + // Use the seed to initialize an ARC4 generator. + arc4 = new ARC4(key); + + // Mix the randomness into accumulated entropy. + mixkey(arc4.S, pool); + + // Override Math.random + + // This function returns a random double in [0, 1) that contains + // randomness in every bit of the mantissa of the IEEE 754 value. + + math['random'] = function random() { // Closure to return a random double: + var n = arc4.g(chunks); // Start with a numerator n < 2 ^ 48 + var d = startdenom; // and denominator d = 2 ^ 48. + var x = 0; // and no 'extra last byte'. + while (n < significance) { // Fill up all significant digits by + n = (n + x) * width; // shifting numerator and + d *= width; // denominator and generating a + x = arc4.g(1); // new least-significant-byte. + } + while (n >= overflow) { // To avoid rounding up, before adding + n /= 2; // last byte, shift everything + d /= 2; // right using integer math until + x >>>= 1; // we have exactly the desired bits. + } + return (n + x) / d; // Form the number within [0, 1). + }; + + // Return the seed that was used + return seed; +}; + +// +// ARC4 +// +// An ARC4 implementation. The constructor takes a key in the form of +// an array of at most (width) integers that should be 0 <= x < (width). +// +// The g(count) method returns a pseudorandom integer that concatenates +// the next (count) outputs from ARC4. Its return value is a number x +// that is in the range 0 <= x < (width ^ count). +// +/** @constructor */ +function ARC4(key) { + var t, u, me = this, keylen = key.length; + var i = 0, j = me.i = me.j = me.m = 0; + me.S = []; + me.c = []; + + // The empty key [] is treated as [0]. + if (!keylen) { key = [keylen++]; } + + // Set up S using the standard key scheduling algorithm. + while (i < width) { me.S[i] = i++; } + for (i = 0; i < width; i++) { + t = me.S[i]; + j = lowbits(j + t + key[i % keylen]); + u = me.S[j]; + me.S[i] = u; + me.S[j] = t; + } + + // The "g" method returns the next (count) outputs as one number. + me.g = function getnext(count) { + var s = me.S; + var i = lowbits(me.i + 1); var t = s[i]; + var j = lowbits(me.j + t); var u = s[j]; + s[i] = u; + s[j] = t; + var r = s[lowbits(t + u)]; + while (--count) { + i = lowbits(i + 1); t = s[i]; + j = lowbits(j + t); u = s[j]; + s[i] = u; + s[j] = t; + r = r * width + s[lowbits(t + u)]; + } + me.i = i; + me.j = j; + return r; + }; + // For robust unpredictability discard an initial batch of values. + // See http://www.rsa.com/rsalabs/node.asp?id=2009 + me.g(width); +} + +// +// flatten() +// Converts an object tree to nested arrays of strings. +// +/** @param {Object=} result + * @param {string=} prop + * @param {string=} typ */ +function flatten(obj, depth, result, prop, typ) { + result = []; + typ = typeof(obj); + if (depth && typ == 'object') { + for (prop in obj) { + if (prop.indexOf('S') < 5) { // Avoid FF3 bug (local/sessionStorage) + try { result.push(flatten(obj[prop], depth - 1)); } catch (e) {} + } + } + } + return (result.length ? result : obj + (typ != 'string' ? '\0' : '')); +} + +// +// mixkey() +// Mixes a string seed into a key that is an array of integers, and +// returns a shortened string seed that is equivalent to the result key. +// +/** @param {number=} smear + * @param {number=} j */ +function mixkey(seed, key, smear, j) { + seed += ''; // Ensure the seed is a string + smear = 0; + for (j = 0; j < seed.length; j++) { + key[lowbits(j)] = + lowbits((smear ^= key[lowbits(j)] * 19) + seed.charCodeAt(j)); + } + seed = ''; + for (j in key) { seed += String.fromCharCode(key[j]); } + return seed; +} + +// +// lowbits() +// A quick "n mod width" for width a power of 2. +// +function lowbits(n) { return n & (width - 1); } + +// +// The following constants are related to IEEE 754 limits. +// +startdenom = math.pow(width, chunks); +significance = math.pow(2, significance); +overflow = significance * 2; + +// +// When seedrandom.js is loaded, we immediately mix a few bits +// from the built-in RNG into the entropy pool. Because we do +// not want to intefere with determinstic PRNG state later, +// seedrandom will not call math.random on its own again after +// initialization. +// +mixkey(math.random(), pool); + +// End anonymous scope, and pass initial values. +}( + [], // pool: entropy pool starts empty + numeric.seedrandom, // math: package containing random, pow, and seedrandom + 256, // width: each RC4 output is 0 <= x < 256 + 6, // chunks: at least six RC4 outputs for each double + 52 // significance: there are 52 significant digits in a double + )); +/* This file is a slightly modified version of quadprog.js from Alberto Santini. + * It has been slightly modified by Sébastien Loisel to make sure that it handles + * 0-based Arrays instead of 1-based Arrays. + * License is in resources/LICENSE.quadprog */ + +function base0to1(A) { + if(typeof A !== "object") { return A; } + var ret = [], i,n=A.length; + for(i=0;i meq) { + work[l] = sum; + } else { + work[l] = -Math.abs(sum); + if (sum > 0) { + for (j = 1; j <= n; j = j + 1) { + amat[j][i] = -amat[j][i]; + } + bvec[i] = -bvec[i]; + } + } + } + + for (i = 1; i <= nact; i = i + 1) { + work[iwsv + iact[i]] = 0; + } + + nvl = 0; + temp = 0; + for (i = 1; i <= q; i = i + 1) { + if (work[iwsv + i] < temp * work[iwnbv + i]) { + nvl = i; + temp = work[iwsv + i] / work[iwnbv + i]; + } + } + if (nvl === 0) { + return 999; + } + + return 0; + } + + function fn_goto_55() { + for (i = 1; i <= n; i = i + 1) { + sum = 0; + for (j = 1; j <= n; j = j + 1) { + sum = sum + dmat[j][i] * amat[j][nvl]; + } + work[i] = sum; + } + + l1 = iwzv; + for (i = 1; i <= n; i = i + 1) { + work[l1 + i] = 0; + } + for (j = nact + 1; j <= n; j = j + 1) { + for (i = 1; i <= n; i = i + 1) { + work[l1 + i] = work[l1 + i] + dmat[i][j] * work[j]; + } + } + + t1inf = true; + for (i = nact; i >= 1; i = i - 1) { + sum = work[i]; + l = iwrm + (i * (i + 3)) / 2; + l1 = l - i; + for (j = i + 1; j <= nact; j = j + 1) { + sum = sum - work[l] * work[iwrv + j]; + l = l + j; + } + sum = sum / work[l1]; + work[iwrv + i] = sum; + if (iact[i] < meq) { + // continue; + break; + } + if (sum < 0) { + // continue; + break; + } + t1inf = false; + it1 = i; + } + + if (!t1inf) { + t1 = work[iwuv + it1] / work[iwrv + it1]; + for (i = 1; i <= nact; i = i + 1) { + if (iact[i] < meq) { + // continue; + break; + } + if (work[iwrv + i] < 0) { + // continue; + break; + } + temp = work[iwuv + i] / work[iwrv + i]; + if (temp < t1) { + t1 = temp; + it1 = i; + } + } + } + + sum = 0; + for (i = iwzv + 1; i <= iwzv + n; i = i + 1) { + sum = sum + work[i] * work[i]; + } + if (Math.abs(sum) <= vsmall) { + if (t1inf) { + ierr[1] = 1; + // GOTO 999 + return 999; + } else { + for (i = 1; i <= nact; i = i + 1) { + work[iwuv + i] = work[iwuv + i] - t1 * work[iwrv + i]; + } + work[iwuv + nact + 1] = work[iwuv + nact + 1] + t1; + // GOTO 700 + return 700; + } + } else { + sum = 0; + for (i = 1; i <= n; i = i + 1) { + sum = sum + work[iwzv + i] * amat[i][nvl]; + } + tt = -work[iwsv + nvl] / sum; + t2min = true; + if (!t1inf) { + if (t1 < tt) { + tt = t1; + t2min = false; + } + } + + for (i = 1; i <= n; i = i + 1) { + sol[i] = sol[i] + tt * work[iwzv + i]; + if (Math.abs(sol[i]) < vsmall) { + sol[i] = 0; + } + } + + crval[1] = crval[1] + tt * sum * (tt / 2 + work[iwuv + nact + 1]); + for (i = 1; i <= nact; i = i + 1) { + work[iwuv + i] = work[iwuv + i] - tt * work[iwrv + i]; + } + work[iwuv + nact + 1] = work[iwuv + nact + 1] + tt; + + if (t2min) { + nact = nact + 1; + iact[nact] = nvl; + + l = iwrm + ((nact - 1) * nact) / 2 + 1; + for (i = 1; i <= nact - 1; i = i + 1) { + work[l] = work[i]; + l = l + 1; + } + + if (nact === n) { + work[l] = work[n]; + } else { + for (i = n; i >= nact + 1; i = i - 1) { + if (work[i] === 0) { + // continue; + break; + } + gc = Math.max(Math.abs(work[i - 1]), Math.abs(work[i])); + gs = Math.min(Math.abs(work[i - 1]), Math.abs(work[i])); + if (work[i - 1] >= 0) { + temp = Math.abs(gc * Math.sqrt(1 + gs * gs / (gc * gc))); + } else { + temp = -Math.abs(gc * Math.sqrt(1 + gs * gs / (gc * gc))); + } + gc = work[i - 1] / temp; + gs = work[i] / temp; + + if (gc === 1) { + // continue; + break; + } + if (gc === 0) { + work[i - 1] = gs * temp; + for (j = 1; j <= n; j = j + 1) { + temp = dmat[j][i - 1]; + dmat[j][i - 1] = dmat[j][i]; + dmat[j][i] = temp; + } + } else { + work[i - 1] = temp; + nu = gs / (1 + gc); + for (j = 1; j <= n; j = j + 1) { + temp = gc * dmat[j][i - 1] + gs * dmat[j][i]; + dmat[j][i] = nu * (dmat[j][i - 1] + temp) - dmat[j][i]; + dmat[j][i - 1] = temp; + + } + } + } + work[l] = work[nact]; + } + } else { + sum = -bvec[nvl]; + for (j = 1; j <= n; j = j + 1) { + sum = sum + sol[j] * amat[j][nvl]; + } + if (nvl > meq) { + work[iwsv + nvl] = sum; + } else { + work[iwsv + nvl] = -Math.abs(sum); + if (sum > 0) { + for (j = 1; j <= n; j = j + 1) { + amat[j][nvl] = -amat[j][nvl]; + } + bvec[nvl] = -bvec[nvl]; + } + } + // GOTO 700 + return 700; + } + } + + return 0; + } + + function fn_goto_797() { + l = iwrm + (it1 * (it1 + 1)) / 2 + 1; + l1 = l + it1; + if (work[l1] === 0) { + // GOTO 798 + return 798; + } + gc = Math.max(Math.abs(work[l1 - 1]), Math.abs(work[l1])); + gs = Math.min(Math.abs(work[l1 - 1]), Math.abs(work[l1])); + if (work[l1 - 1] >= 0) { + temp = Math.abs(gc * Math.sqrt(1 + gs * gs / (gc * gc))); + } else { + temp = -Math.abs(gc * Math.sqrt(1 + gs * gs / (gc * gc))); + } + gc = work[l1 - 1] / temp; + gs = work[l1] / temp; + + if (gc === 1) { + // GOTO 798 + return 798; + } + if (gc === 0) { + for (i = it1 + 1; i <= nact; i = i + 1) { + temp = work[l1 - 1]; + work[l1 - 1] = work[l1]; + work[l1] = temp; + l1 = l1 + i; + } + for (i = 1; i <= n; i = i + 1) { + temp = dmat[i][it1]; + dmat[i][it1] = dmat[i][it1 + 1]; + dmat[i][it1 + 1] = temp; + } + } else { + nu = gs / (1 + gc); + for (i = it1 + 1; i <= nact; i = i + 1) { + temp = gc * work[l1 - 1] + gs * work[l1]; + work[l1] = nu * (work[l1 - 1] + temp) - work[l1]; + work[l1 - 1] = temp; + l1 = l1 + i; + } + for (i = 1; i <= n; i = i + 1) { + temp = gc * dmat[i][it1] + gs * dmat[i][it1 + 1]; + dmat[i][it1 + 1] = nu * (dmat[i][it1] + temp) - dmat[i][it1 + 1]; + dmat[i][it1] = temp; + } + } + + return 0; + } + + function fn_goto_798() { + l1 = l - it1; + for (i = 1; i <= it1; i = i + 1) { + work[l1] = work[l]; + l = l + 1; + l1 = l1 + 1; + } + + work[iwuv + it1] = work[iwuv + it1 + 1]; + iact[it1] = iact[it1 + 1]; + it1 = it1 + 1; + if (it1 < nact) { + // GOTO 797 + return 797; + } + + return 0; + } + + function fn_goto_799() { + work[iwuv + nact] = work[iwuv + nact + 1]; + work[iwuv + nact + 1] = 0; + iact[nact] = 0; + nact = nact - 1; + iter[2] = iter[2] + 1; + + return 0; + } + + go = 0; + while (true) { + go = fn_goto_50(); + if (go === 999) { + return; + } + while (true) { + go = fn_goto_55(); + if (go === 0) { + break; + } + if (go === 999) { + return; + } + if (go === 700) { + if (it1 === nact) { + fn_goto_799(); + } else { + while (true) { + fn_goto_797(); + go = fn_goto_798(); + if (go !== 797) { + break; + } + } + fn_goto_799(); + } + } + } + } + +} + +function solveQP(Dmat, dvec, Amat, bvec, meq, factorized) { + Dmat = base0to1(Dmat); + dvec = base0to1(dvec); + Amat = base0to1(Amat); + var i, n, q, + nact, r, + crval = [], iact = [], sol = [], work = [], iter = [], + message; + + meq = meq || 0; + factorized = factorized ? base0to1(factorized) : [undefined, 0]; + bvec = bvec ? base0to1(bvec) : []; + + // In Fortran the array index starts from 1 + n = Dmat.length - 1; + q = Amat[1].length - 1; + + if (!bvec) { + for (i = 1; i <= q; i = i + 1) { + bvec[i] = 0; + } + } + for (i = 1; i <= q; i = i + 1) { + iact[i] = 0; + } + nact = 0; + r = Math.min(n, q); + for (i = 1; i <= n; i = i + 1) { + sol[i] = 0; + } + crval[1] = 0; + for (i = 1; i <= (2 * n + (r * (r + 5)) / 2 + 2 * q + 1); i = i + 1) { + work[i] = 0; + } + for (i = 1; i <= 2; i = i + 1) { + iter[i] = 0; + } + + qpgen2(Dmat, dvec, n, n, sol, crval, Amat, + bvec, n, q, meq, iact, nact, iter, work, factorized); + + message = ""; + if (factorized[1] === 1) { + message = "constraints are inconsistent, no solution!"; + } + if (factorized[1] === 2) { + message = "matrix D in quadratic function is not positive definite!"; + } + + return { + solution: base1to0(sol), + value: base1to0(crval), + unconstrained_solution: base1to0(dvec), + iterations: base1to0(iter), + iact: base1to0(iact), + message: message + }; +} + +numeric.solveQP = solveQP; +/* +Shanti Rao sent me this routine by private email. I had to modify it +slightly to work on Arrays instead of using a Matrix object. +It is apparently translated from http://stitchpanorama.sourceforge.net/Python/svd.py +*/ + +numeric.svd= function svd(A) { + var temp; +//Compute the thin SVD from G. H. Golub and C. Reinsch, Numer. Math. 14, 403-420 (1970) + var prec= numeric.epsilon; //Math.pow(2,-52) // assumes double prec + var tolerance= 1.e-64/prec; + var itmax= 50; + var c=0; + var i=0; + var j=0; + var k=0; + var l=0; + + var u= numeric.clone(A); + var m= u.length; + + var n= u[0].length; + + if (m < n) throw "Need more rows than columns"; + + var e = new Array(n); + var q = new Array(n); + for (i=0; i b) + return a*Math.sqrt(1.0+(b*b/a/a)); + else if (b == 0.0) + return a; + return b*Math.sqrt(1.0+(a*a/b/b)); + } + + //Householder's reduction to bidiagonal form + + var f= 0.0; + var g= 0.0; + var h= 0.0; + var x= 0.0; + var y= 0.0; + var z= 0.0; + var s= 0.0; + + for (i=0; i < n; i++) + { + e[i]= g; + s= 0.0; + l= i+1; + for (j=i; j < m; j++) + s += (u[j][i]*u[j][i]); + if (s <= tolerance) + g= 0.0; + else + { + f= u[i][i]; + g= Math.sqrt(s); + if (f >= 0.0) g= -g; + h= f*g-s; + u[i][i]=f-g; + for (j=l; j < n; j++) + { + s= 0.0; + for (k=i; k < m; k++) + s += u[k][i]*u[k][j]; + f= s/h; + for (k=i; k < m; k++) + u[k][j]+=f*u[k][i]; + } + } + q[i]= g; + s= 0.0; + for (j=l; j < n; j++) + s= s + u[i][j]*u[i][j]; + if (s <= tolerance) + g= 0.0; + else + { + f= u[i][i+1]; + g= Math.sqrt(s); + if (f >= 0.0) g= -g; + h= f*g - s; + u[i][i+1] = f-g; + for (j=l; j < n; j++) e[j]= u[i][j]/h; + for (j=l; j < m; j++) + { + s=0.0; + for (k=l; k < n; k++) + s += (u[j][k]*u[i][k]); + for (k=l; k < n; k++) + u[j][k]+=s*e[k]; + } + } + y= Math.abs(q[i])+Math.abs(e[i]); + if (y>x) + x=y; + } + + // accumulation of right hand gtransformations + for (i=n-1; i != -1; i+= -1) + { + if (g != 0.0) + { + h= g*u[i][i+1]; + for (j=l; j < n; j++) + v[j][i]=u[i][j]/h; + for (j=l; j < n; j++) + { + s=0.0; + for (k=l; k < n; k++) + s += u[i][k]*v[k][j]; + for (k=l; k < n; k++) + v[k][j]+=(s*v[k][i]); + } + } + for (j=l; j < n; j++) + { + v[i][j] = 0; + v[j][i] = 0; + } + v[i][i] = 1; + g= e[i]; + l= i; + } + + // accumulation of left hand transformations + for (i=n-1; i != -1; i+= -1) + { + l= i+1; + g= q[i]; + for (j=l; j < n; j++) + u[i][j] = 0; + if (g != 0.0) + { + h= u[i][i]*g; + for (j=l; j < n; j++) + { + s=0.0; + for (k=l; k < m; k++) s += u[k][i]*u[k][j]; + f= s/h; + for (k=i; k < m; k++) u[k][j]+=f*u[k][i]; + } + for (j=i; j < m; j++) u[j][i] = u[j][i]/g; + } + else + for (j=i; j < m; j++) u[j][i] = 0; + u[i][i] += 1; + } + + // diagonalization of the bidiagonal form + prec= prec*x; + for (k=n-1; k != -1; k+= -1) + { + for (var iteration=0; iteration < itmax; iteration++) + { // test f splitting + var test_convergence = false; + for (l=k; l != -1; l+= -1) + { + if (Math.abs(e[l]) <= prec) + { test_convergence= true; + break; + } + if (Math.abs(q[l-1]) <= prec) + break; + } + if (!test_convergence) + { // cancellation of e[l] if l>0 + c= 0.0; + s= 1.0; + var l1= l-1; + for (i =l; i= itmax-1) + throw 'Error: no convergence.'; + // shift from bottom 2x2 minor + x= q[l]; + y= q[k-1]; + g= e[k-1]; + h= e[k]; + f= ((y-z)*(y+z)+(g-h)*(g+h))/(2.0*h*y); + g= pythag(f,1.0); + if (f < 0.0) + f= ((x-z)*(x+z)+h*(y/(f-g)-h))/x; + else + f= ((x-z)*(x+z)+h*(y/(f+g)-h))/x; + // next QR transformation + c= 1.0; + s= 1.0; + for (i=l+1; i< k+1; i++) + { + g= e[i]; + y= q[i]; + h= s*g; + g= c*g; + z= pythag(f,h); + e[i-1]= z; + c= f/z; + s= h/z; + f= x*c+g*s; + g= -x*s+g*c; + h= y*s; + y= y*c; + for (j=0; j < n; j++) + { + x= v[j][i-1]; + z= v[j][i]; + v[j][i-1] = x*c+z*s; + v[j][i] = -x*s+z*c; + } + z= pythag(f,h); + q[i-1]= z; + c= f/z; + s= h/z; + f= c*g+s*y; + x= -s*g+c*y; + for (j=0; j < m; j++) + { + y= u[j][i-1]; + z= u[j][i]; + u[j][i-1] = y*c+z*s; + u[j][i] = -y*s+z*c; + } + } + e[l]= 0.0; + e[k]= f; + q[k]= x; + } + } + + //vt= transpose(v) + //return (u,q,vt) + for (i=0;i= 0; j--) + { + if (q[j] < q[i]) + { + // writeln(i,'-',j) + c = q[j]; + q[j] = q[i]; + q[i] = c; + for(k=0;k phi0 && t > epsilon) { + var theta = phi1 / phi0; + var u = (Math.sqrt(1.0 + 6.0 * theta) - 1.0) / (3.0 * theta); + t *= u; + } + else { + this.copyVariables(x, x_new); + break; + } + } + } + + // add -dx to x to get the new variables + // + this.getNewVariableValue = function (x, dx, t) { + var x_new = new Array(x.length); + var i = 0; + for (i = 0; i < x.length; i++) { + x_new[i] = x[i] - t*dx[i]; + } + + return x_new; + } + + // copy x_new to x + // + this.copyVariables = function (x, x_new) { + var i = 0; + for (i = 0; i < x.length; i++) { + x[i] = x_new[i] + } + } + + // evaluate the function value's residual + // + this.evaluate_residual = function (funcsVal) { + var i; + var residual = 0; + for (i = 0; i < funcsVal.length; i++) { + residual += Math.abs(funcsVal[i]); + } + return residual; + } + + // evaluate the Euclidean_norm_of_residual + // + this.evaluate_Euclidean_norm_of_residual = function (funcsVal) { + var i; + var residual2 = 0; + for (i = 0; i < funcsVal.length; i++) { + var fabs = Math.abs(funcsVal[i]); + residual2 += fabs*fabs; + } + return Math.sqrt(residual2); + } + + // main function start here + // + var residual_tol = 1e-7; + var max_iteration = 1000; + var epsilon = 2.22e-16; + var JS_GSL_SUCCESS = 0; + var JS_GSL_CONTINUE = 1; + + // evaluate none linear system of equations and its jacobian matrix + // + var funcs = F(x); + var jacobian = A(x); + + // iterate to get the solution + // + var iter = 0; + var status; + do { + iter++; + + this.newton_iterate(F, A, x); + + if (this.evaluate_residual(F(x)) < residual_tol) + status = JS_GSL_SUCCESS; + else + status = JS_GSL_CONTINUE; + + } while (status == JS_GSL_CONTINUE && iter < max_iteration) + +} + +/* unit test + +Rosenbrock Function + + double y0 = 1 - x0; + double y1 = 10 * (x1 - x0 * x0); + + x0 = -1.2 + x1 = 1.0 + +*/ + + +/** + * Searches the interval from lowerLimit to upperLimit + * for a root (i.e., zero) of the function func with respect to + * its first argument using Brent's method root-finding algorithm. + * + * @param {function} function for which the root is sought. + * @param {number} the lower point of the interval to be searched. + * @param {number} the upper point of the interval to be searched. + * @param {number} the desired accuracy (convergence tolerance). + * @param {number} the maximum number of iterations. + * @returns an estimate for the root within accuracy. + */ +// Translated from zeroin.c in http://www.netlib.org/c/brent.shar. +numeric.uniroot = function uniroot(func, lowerLimit, upperLimit, errorTol, maxIter) { + var a = lowerLimit + , b = upperLimit + , c = a + , fa = func(a) + , fb = func(b) + , fc = fa + , s = 0 + , fs = 0 + , tol_act // Actual tolerance + , new_step // Step at this iteration + , prev_step // Distance from the last but one to the last approximation + , p // Interpolation step is calculated in the form p/q; division is delayed until the last moment + , q + ; + + errorTol = errorTol || 0; + maxIter = maxIter || 1000; + + while ( maxIter-- > 0 ) { + + prev_step = b - a; + + if ( Math.abs(fc) < Math.abs(fb) ) { + // Swap data for b to be the best approximation + a = b, b = c, c = a; + fa = fb, fb = fc, fc = fa; + } + + tol_act = 1e-15 * Math.abs(b) + errorTol / 2; + new_step = ( c - b ) / 2; + + if ( Math.abs(new_step) <= tol_act || fb === 0 ) { + return b; // Acceptable approx. is found + } + + // Decide if the interpolation can be tried + if ( Math.abs(prev_step) >= tol_act && Math.abs(fa) > Math.abs(fb) ) { + // If prev_step was large enough and was in true direction, Interpolatiom may be tried + var t1, cb, t2; + cb = c - b; + if ( a === c ) { // If we have only two distinct points linear interpolation can only be applied + t1 = fb / fa; + p = cb * t1; + q = 1.0 - t1; + } + else { // Quadric inverse interpolation + q = fa / fc, t1 = fb / fc, t2 = fb / fa; + p = t2 * (cb * q * (q - t1) - (b - a) * (t1 - 1)); + q = (q - 1) * (t1 - 1) * (t2 - 1); + } + + if ( p > 0 ) { + q = -q; // p was calculated with the opposite sign; make p positive + } + else { + p = -p; // and assign possible minus to q + } + + if ( p < ( 0.75 * cb * q - Math.abs( tol_act * q ) / 2 ) && + p < Math.abs( prev_step * q / 2 ) ) { + // If (b + p / q) falls in [b,c] and isn't too large it is accepted + new_step = p / q; + } + + // If p/q is too large then the bissection procedure can reduce [b,c] range to more extent + } + + if ( Math.abs( new_step ) < tol_act ) { // Adjust the step to be not less than tolerance + new_step = ( new_step > 0 ) ? tol_act : -tol_act; + } + + a = b, fa = fb; // Save the previous approx. + b += new_step, fb = func(b); // Do step to a new approxim. + + if ( (fb > 0 && fc > 0) || (fb < 0 && fc < 0) ) { + c = a, fc = fa; // Adjust c for it to have a sign opposite to that of b + } + } + +}; + + +/* +var test_counter; +function f1 (x) { test_counter++; return (Math.pow(x,2)-1)*x - 5; } +function f2 (x) { test_counter++; return Math.cos(x)-x; } +function f3 (x) { test_counter++; return Math.sin(x)-x; } +function f4 (x) { test_counter++; return (x + 3) * Math.pow(x - 1, 2); } +[ + [f1, 2, 3], + [f2, 2, 3], + [f2, -1, 3], + [f3, -1, 3], + [f4, -4, 4/3] +].forEach(function (args) { + test_counter = 0; + var root = uniroot.apply( pv, args ); + ;;;console.log( 'uniroot:', args.slice(1), root, test_counter ); +}) +*/ +numeric.Sparse = function Sparse(p,v) { this.p = p; this.v = v; }; + +numeric.Sparse.scatter = function scatter(i,j,z) { + var n = numeric.sup(j)+1,m=i.length,jk; + var p = Array(n),v = Array(n),k; + for(k=n-1;k!==-1;--k) { p[k] = []; v[k] = []; } + for(k=0;k!==m;++k) { + jk = j[k]; + p[jk].push(i[k]); + v[jk].push(z[k]); + } + return new numeric.Sparse(p,v); +}; + +numeric.Sparse.identity = function identity(n) { + return numeric.Sparse.scatter(numeric.linspace(0,n-1),numeric.linspace(0,n-1),numeric.rep([n],1)); +}; + +numeric.Sparse.prototype.dim = function dim() { + var m = 0, i,j,p=this.p,k=p.length,pi,a,b; + for(i=k-1;i!==-1;--i) { + pi = p[i]; + a = pi.length; + for(j=a-1;j!==-1;--j) { + b = pi[j]; + if(b>m) m = b; + } + } + return [m+1,p.length]; +}; + +numeric.Sparse.prototype.Lsolve = function Lsolve(b,n) { + if(typeof n === "undefined") { n = b.length; } + var i,j,k,ret = Array(n), p = this.p, v = this.v, pj,vj,m; + for(i=0;ij && i=j) t[i-j] = vj[k]; + } + if(j!==0) { + for(k=n-1;k!==-1;--k) foo[k] = 0; + for(k=0;k3;i-=4) { f(); f(); f(); f(); } + while(i>0) { f(); i--; } + t2 = new Date(); + if(t2-t1 > interval) break; + } + for(i=n;i>3;i-=4) { f(); f(); f(); f(); } + while(i>0) { f(); i--; } + t2 = new Date(); + return 1000*(3*n-1)/(t2-t1); +}; + +numeric._myIndexOf = (function _myIndexOf(w) { + var n = this.length,k; + for(k=0;k numeric.largeArray) { ret.push('...Large Array...'); return true; } + var flag = false; + ret.push('['); + for(k=0;k0) { ret.push(','); if(flag) ret.push('\n '); } flag = foo(x[k]); } + ret.push(']'); + return true; + } + ret.push('{'); + var flag = false; + for(k in x) { if(x.hasOwnProperty(k)) { if(flag) ret.push(',\n'); flag = true; ret.push(k); ret.push(': \n'); foo(x[k]); } } + ret.push('}'); + return true; + } + foo(x); + return ret.join(''); +}; + +numeric.parseDate = function parseDate(d) { + function foo(d) { + if(typeof d === 'string') { return Date.parse(d.replace(/-/g,'/')); } + if(!(d instanceof Array)) { throw new Error("parseDate: parameter must be arrays of strings"); } + var ret = [],k; + for(k=0;k0) { + ret[count] = []; + for(j=0;j> 2; + q = ((x & 3) << 4) + (y >> 4); + r = ((y & 15) << 2) + (z >> 6); + s = z & 63; + if(i+1>=n) { r = s = 64; } + else if(i+2>=n) { s = 64; } + ret += key.charAt(p) + key.charAt(q) + key.charAt(r) + key.charAt(s); + } + return ret; + } + function crc32Array (a,from,to) { + if(typeof from === "undefined") { from = 0; } + if(typeof to === "undefined") { to = a.length; } + var table = [0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, + 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, + 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, + 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, + 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, + 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, + 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, + 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, + 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, + 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, + 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, + 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, + 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, + 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, + 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, + 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, + 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, + 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, + 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, + 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, + 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, + 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D]; + + var crc = -1, y = 0, n = a.length,i; + + for (i = from; i < to; i++) { + y = (crc ^ a[i]) & 0xFF; + crc = (crc >>> 8) ^ table[y]; + } + + return crc ^ (-1); + } + + var h = img[0].length, w = img[0][0].length, s1, s2, next,k,length,a,b,i,j,adler32,crc32; + var stream = [ + 137, 80, 78, 71, 13, 10, 26, 10, // 0: PNG signature + 0,0,0,13, // 8: IHDR Chunk length + 73, 72, 68, 82, // 12: "IHDR" + (w >> 24) & 255, (w >> 16) & 255, (w >> 8) & 255, w&255, // 16: Width + (h >> 24) & 255, (h >> 16) & 255, (h >> 8) & 255, h&255, // 20: Height + 8, // 24: bit depth + 2, // 25: RGB + 0, // 26: deflate + 0, // 27: no filter + 0, // 28: no interlace + -1,-2,-3,-4, // 29: CRC + -5,-6,-7,-8, // 33: IDAT Chunk length + 73, 68, 65, 84, // 37: "IDAT" + // RFC 1950 header starts here + 8, // 41: RFC1950 CMF + 29 // 42: RFC1950 FLG + ]; + crc32 = crc32Array(stream,12,29); + stream[29] = (crc32>>24)&255; + stream[30] = (crc32>>16)&255; + stream[31] = (crc32>>8)&255; + stream[32] = (crc32)&255; + s1 = 1; + s2 = 0; + for(i=0;i>8)&255; + stream.push(a); stream.push(b); + stream.push((~a)&255); stream.push((~b)&255); + if(i===0) stream.push(0); + for(j=0;j255) a = 255; + else if(a<0) a=0; + else a = Math.round(a); + s1 = (s1 + a )%65521; + s2 = (s2 + s1)%65521; + stream.push(a); + } + } + stream.push(0); + } + adler32 = (s2<<16)+s1; + stream.push((adler32>>24)&255); + stream.push((adler32>>16)&255); + stream.push((adler32>>8)&255); + stream.push((adler32)&255); + length = stream.length - 41; + stream[33] = (length>>24)&255; + stream[34] = (length>>16)&255; + stream[35] = (length>>8)&255; + stream[36] = (length)&255; + crc32 = crc32Array(stream,37); + stream.push((crc32>>24)&255); + stream.push((crc32>>16)&255); + stream.push((crc32>>8)&255); + stream.push((crc32)&255); + stream.push(0); + stream.push(0); + stream.push(0); + stream.push(0); +// a = stream.length; + stream.push(73); // I + stream.push(69); // E + stream.push(78); // N + stream.push(68); // D + stream.push(174); // CRC1 + stream.push(66); // CRC2 + stream.push(96); // CRC3 + stream.push(130); // CRC4 + return 'data:image/png;base64,'+base64(stream); +}; + +// 2. Linear algebra with Arrays. +numeric._dim = function _dim(x) { + var ret = []; + while(typeof x === "object") { ret.push(x.length); x = x[0]; } + return ret; +}; + +numeric.dim = function dim(x) { + var y,z; + if(typeof x === "object") { + y = x[0]; + if(typeof y === "object") { + z = y[0]; + if(typeof z === "object") { + return numeric._dim(x); + } + return [x.length,y.length]; + } + return [x.length]; + } + return []; +}; + +// mapreduce +numeric.mapreduce = function mapreduce(body, init) { + return numeric.compile('x','accum','_s','_k', + 'if(typeof accum === "undefined") accum = '+init+';\n'+ + 'if(typeof x === "number") { var xi = x; '+body+'; return accum; }\n'+ + 'if(typeof _s === "undefined") _s = numeric.dim(x);\n'+ + 'if(typeof _k === "undefined") _k = 0;\n'+ + 'var _n = _s[_k];\n'+ + 'var i,xi;\n'+ + 'if(_k < _s.length-1) {\n'+ + ' for(i=_n-1;i>=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.mapreduce2 = function mapreduce2(body, setup) { + return numeric.compile('x', + 'var n = x.length;\n'+ + 'var i,xi;\n'+setup+'\n'+ + 'for(i=n-1;i!==-1;--i) { \n'+ + ' xi = x[i];\n'+ + ' '+body+'\n'+ + '}\n'+ + 'return accum;' + ); +}; + +// compare arrays/tensors +numeric.same = function same(x,y) { + var i, n; + + if(!(x instanceof Array) || !(y instanceof Array)) { return false; } + + n = x.length; + + if(n !== y.length) { return false; } + + for(i = 0; i < n; i++) + { + if(x[i] === y[i]) { continue; } + if(typeof x[i] === "object") { if(!same(x[i], y[i])) return false; } + else { return false; } + } + 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; +}; + +// repeat +numeric.rep = function rep(s, v, k) +{ + // repeat value v over a tensor of size s = [s0, s1, s2, ...] + // k recursive index + 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; + } + + for(i = n - 1; i >= 0; i--) { ret[i] = numeric.rep(s, v, k+1); } + + return ret; +}; + +numeric.zeros = function zeros(s) { return numeric.rep(s,0); }; +numeric.ones = function ones(s) { return numeric.rep(s,1); }; + +// dot functions +numeric.dotMMsmall = function dotMMsmall(x,y) +{ + var i,j,k,p,q,r,ret,foo,bar,woo,i0,k0,p0,r0; + p = x.length; q = y.length; r = y[0].length; + ret = Array(p); + for(i=p-1;i>=0;i--) { + foo = Array(r); + bar = x[i]; + for(k=r-1;k>=0;k--) { + woo = bar[q-1]*y[q-1][k]; + for(j=q-2;j>=1;j-=2) { + i0 = j-1; + woo += bar[j]*y[j][k] + bar[i0]*y[i0][k]; + } + if(j===0) { woo += bar[0]*y[0][k]; } + foo[k] = woo; + } + ret[i] = foo; + } + return ret; +}; + +numeric._getCol = function _getCol(A,j,x) { + var n = A.length, i; + for(i=n-1;i>0;--i) { + x[i] = A[i][j]; + --i; + x[i] = A[i][j]; + } + 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; + var VV = numeric.dotVV; + var i,j,k,z; + --p; + --m; + for(i=m;i!==-1;--i) A[i] = Array(n); + --n; + for(i=n;i!==-1;--i) { + gc(y,i,v); + for(j=m;j!==-1;--j) { + z=0; + xj = x[j]; + A[j][i] = VV(xj,v); + } + } + return A; +}; + +numeric.dotMV = function dotMV(x,y) { + var p = x.length, q = y.length,i; + var ret = Array(p), dotVV = numeric.dotVV; + for(i=p-1;i>=0;i--) { ret[i] = dotVV(x[i],y); } + return ret; +}; + +numeric.dotVM = function dotVM(x,y) { + var i,j,k,p,q,r,ret,foo,bar,woo,i0,k0,p0,r0,s1,s2,s3,baz,accum; + p = x.length; q = y[0].length; + ret = Array(q); + for(k=q-1;k>=0;k--) { + woo = x[p-1]*y[p-1][k]; + for(j=p-2;j>=1;j-=2) { + i0 = j-1; + woo += x[j]*y[j][k] + x[i0]*y[i0][k]; + } + if(j===0) { woo += x[0]*y[0][k]; } + ret[k] = woo; + } + return ret; +}; + +numeric.dotVV = function dotVV(x,y) { + var i,n=x.length,i1,ret = x[n-1]*y[n-1]; + for(i=n-2;i>=1;i-=2) { + i1 = i-1; + ret += x[i]*y[i] + x[i1]*y[i1]; + } + if(i===0) { ret += x[0]*y[0]; } + return ret; +}; + +numeric.dot = function dot(x,y) { + var d = numeric.dim; + switch(d(x).length*1000+d(y).length) { + case 2002: + if(y.length < 10) return numeric.dotMMsmall(x,y); + else return numeric.dotMMbig(x,y); + case 2001: return numeric.dotMV(x,y); + case 1002: return numeric.dotVM(x,y); + case 1001: return numeric.dotVV(x,y); + case 1000: return numeric.mulVS(x,y); + case 1: return numeric.mulSV(x,y); + case 0: return x*y; + default: throw new Error('numeric.dot only works on vectors and matrices'); + } +}; + +// diag function + +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--) { + Ai = Array(n); + i1 = i+2; + for(j=n-1;j>=i1;j-=2) { + Ai[j] = 0; + Ai[j-1] = 0; + } + if(j>i) { Ai[j] = 0; } + Ai[i] = d[i]; + for(j=i-1;j>=1;j-=2) { + Ai[j] = 0; + Ai[j-1] = 0; + } + if(j===0) { Ai[0] = 0; } + A[i] = Ai; + } + 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) { + ret[i] = A[i][i]; + --i; + ret[i] = A[i][i]; + } + if(i===0) { + ret[0] = A[0][0]; + } + return ret; +}; + +numeric.identity = function identity(n) { return numeric.diag(numeric.rep([n],1)); }; + +numeric.pointwise = function pointwise(params,body,setup) +{ + if(typeof setup === "undefined") { setup = ""; } + var fun = []; + var k; + var avec = /\[i\]$/,p,thevec = ''; + var haveret = false; + for(k=0;k=0;i--) ret[i] = arguments.callee('+params.join(',')+',_s,_k+1);\n'+ + ' return ret;\n'+ + '}\n'+ + setup+'\n'+ + 'for(i=_n-1;i!==-1;--i) {\n'+ + ' '+body+'\n'+ + '}\n'+ + 'return ret;' + ); + return numeric.compile.apply(null,fun); +}; + +numeric.pointwise2 = function pointwise2(params,body,setup) +{ + if(typeof setup === "undefined") { setup = ""; } + var fun = []; + var k; + var avec = /\[i\]$/,p,thevec = ''; + var haveret = false; + for(k=0;k=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.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']; + +numeric.ops1 = { + neg: '-', + not: '!', + bnot: '~', + 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;'] +}; + +(function () { + var i,o; + for(i=0;iv0) { i0 = i; v0 = k; } } + Aj = A[i0]; A[i0] = A[j]; A[j] = Aj; + Ij = I[i0]; I[i0] = I[j]; I[j] = Ij; + x = Aj[j]; + for(k=j;k!==n;++k) Aj[k] /= x; + for(k=n-1;k!==-1;--k) Ij[k] /= x; + for(i=m-1;i!==-1;--i) { + if(i!==j) { + Ai = A[i]; + Ii = I[i]; + x = Ai[j]; + for(k=j+1;k!==n;++k) Ai[k] -= Aj[k]*x; + for(k=n-1;k>0;--k) { Ii[k] -= Ij[k]*x; --k; Ii[k] -= Ij[k]*x; } + if(k===0) Ii[0] -= Ij[0]*x; + } + } + } + return I; +}; + +numeric.det = function det(x) { + var s = numeric.dim(x); + if(s.length !== 2 || s[0] !== s[1]) { throw new Error('numeric: det() only works on square matrices'); } + var n = s[0], ret = 1,i,j,k,A = numeric.clone(x),Aj,Ai,alpha,temp,k1,k2,k3; + for(j=0;j Math.abs(A[k][j])) { k = i; } } + if(k !== j) { + temp = A[k]; A[k] = A[j]; A[j] = temp; + ret *= -1; + } + Aj = A[j]; + for(i=j+1;i=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]; + --j; + Bj = ret[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]; + } + } + if(i===0) { + A0 = x[0]; + for(j=n-1;j>=1;--j) { + ret[j][0] = A0[j]; + --j; + ret[j][0] = A0[j]; + } + if(j===0) { ret[0][0] = A0[0]; } + } + return ret; +}; + +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]; + --j; + Bj = ret[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]; + } + } + if(i===0) { + A0 = x[0]; + for(j=n-1;j>=1;--j) { + ret[j][0] = -A0[j]; + --j; + ret[j][0] = -A0[j]; + } + if(j===0) { ret[0][0] = -A0[0]; } + } + return ret; +}; + +numeric._random = function _random(s,k) { + var i,n=s[k],ret=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(); + } + if(i===0) { ret[0] = rnd(); } + return ret; + } + for(i=n-1;i>=0;i--) ret[i] = _random(s,k+1); + return ret; +}; + +numeric.random = function random(s) { return numeric._random(s,0); }; + +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); + n--; + for(i=n;i>=0;i--) { ret[i] = (i*b+(n-i)*a)/n; } + return ret; +}; + +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--) { ret[i] = foo(x[i+a],k+1); } + return ret; + } + return foo(x,0); +}; + +numeric.setBlock = function setBlock(x,from,to,B) { + var s = numeric.dim(x); + function foo(x,y,k) { + var i,a = from[k], n = to[k]-a; + if(k === s.length-1) { for(i=n;i>=0;i--) { x[i+a] = y[i]; } } + for(i=n;i>=0;i--) { foo(x[i+a],y[i],k+1); } + } + foo(x,B,0); + return x; +}; + +numeric.getRange = function getRange(A, I,J ) { + var m = I.length, n = J.length; + var i,j; + var B = Array(m), Bi, AI; + for(i=m-1;i!==-1;--i) { + B[i] = Array(n); + Bi = B[i]; + AI = A[I[i]]; + for(j=n-1;j!==-1;--j) Bi[j] = AI[J[j]]; + } + return B; +}; + +numeric.blockMatrix = function blockMatrix(X) { + var s = numeric.dim(X); + if(s.length<4) return numeric.blockMatrix([X]); + var m=s[0],n=s[1],M,N,i,j,Xij; + M = 0; N = 0; + for(i=0;i=0;i--) { + Ai = Array(n); + xi = x[i]; + for(j=n-1;j>=3;--j) { + Ai[j] = xi * y[j]; + --j; + Ai[j] = xi * y[j]; + --j; + Ai[j] = xi * y[j]; + --j; + Ai[j] = xi * y[j]; + } + while(j>=0) { Ai[j] = xi * y[j]; --j; } + A[i] = Ai; + } + return A; +}; + +// 3. The Tensor type T +numeric.T = function T(x,y) { this.x = x; this.y = y; }; +numeric.t = function t(x,y) { return new numeric.T(x,y); }; + +numeric.Tbinop = function Tbinop(rr,rc,cr,cc,setup) { + var io = numeric.indexOf; + if(typeof setup !== "string") { + var k; + setup = ''; + for(k in numeric) { + if(numeric.hasOwnProperty(k) && (rr.indexOf(k)>=0 || rc.indexOf(k)>=0 || cr.indexOf(k)>=0 || cc.indexOf(k)>=0) && k.length>1) { + setup += 'var '+k+' = numeric.'+k+';\n'; + } + } + } + return numeric.compile(['y'], + 'var x = this;\n'+ + 'if(!(y instanceof numeric.T)) { y = new numeric.T(y); }\n'+ + setup+'\n'+ + 'if(x.y) {'+ + ' if(y.y) {'+ + ' return new numeric.T('+cc+');\n'+ + ' }\n'+ + ' return new numeric.T('+cr+');\n'+ + '}\n'+ + 'if(y.y) {\n'+ + ' return new numeric.T('+rc+');\n'+ + '}\n'+ + 'return new numeric.T('+rr+');\n' + ); +}; + +numeric.T.prototype.add = numeric.Tbinop( + 'add(x.x,y.x)', + 'add(x.x,y.x),y.y', + 'add(x.x,y.x),x.y', + 'add(x.x,y.x),add(x.y,y.y)'); +numeric.T.prototype.sub = numeric.Tbinop( + 'sub(x.x,y.x)', + 'sub(x.x,y.x),neg(y.y)', + 'sub(x.x,y.x),x.y', + 'sub(x.x,y.x),sub(x.y,y.y)'); +numeric.T.prototype.mul = numeric.Tbinop( + 'mul(x.x,y.x)', + 'mul(x.x,y.x),mul(x.x,y.y)', + 'mul(x.x,y.x),mul(x.y,y.x)', + 'sub(mul(x.x,y.x),mul(x.y,y.y)),add(mul(x.x,y.y),mul(x.y,y.x))'); + +numeric.T.prototype.reciprocal = function reciprocal() { + var mul = numeric.mul, div = numeric.div; + if(this.y) { + 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 numeric.T(div(1,this.x), 0); +}; + +numeric.T.prototype.div = function div(y) { + if(!(y instanceof numeric.T)) y = new numeric.T(y); + if(y.y) { return this.mul(y.reciprocal()); } + var div = numeric.div; + if(this.y) { return new numeric.T(div(this.x,y.x),div(this.y,y.x)); } + return new numeric.T(div(this.x,y.x)); +}; + +numeric.T.prototype.dot = numeric.Tbinop( + 'dot(x.x,y.x)', + 'dot(x.x,y.x),dot(x.x,y.y)', + 'dot(x.x,y.x),dot(x.y,y.x)', + 'sub(dot(x.x,y.x),dot(x.y,y.y)),add(dot(x.x,y.y),dot(x.y,y.x))' + ); + +numeric.T.prototype.transpose = function transpose() { + var t = numeric.transpose, x = this.x, y = this.y; + if(y) { return new numeric.T(t(x),t(y)); } + return new numeric.T(t(x)); +}; + +numeric.T.prototype.transjugate = function transjugate() { + var t = numeric.transpose, x = this.x, y = this.y; + if(y) { return new numeric.T(t(x),numeric.negtranspose(y)); } + return new numeric.T(t(x)); +}; + +numeric.Tunop = function Tunop(r,c,s) { + if(typeof s !== "string") { s = ''; } + return numeric.compile( + 'var x = this;\n'+ + s+'\n'+ + 'if(x.y) {'+ + ' '+c+'\n'+ + '}\n'+ + r+'\n' + ); +}; + +numeric.T.prototype.exp = numeric.Tunop( + 'return new numeric.T(ex);', + 'return new numeric.T(mul(cos(x.y),ex),mul(sin(x.y),ex));', + 'var ex = numeric.exp(x.x), cos = numeric.cos, sin = numeric.sin, mul = numeric.mul;'); +numeric.T.prototype.conj = numeric.Tunop( + 'return new numeric.T(x.x);', + 'return new numeric.T(x.x,numeric.neg(x.y));'); +numeric.T.prototype.neg = numeric.Tunop( + 'return new numeric.T(neg(x.x));', + 'return new numeric.T(neg(x.x),neg(x.y));', + 'var neg = numeric.neg;'); +numeric.T.prototype.sin = numeric.Tunop( + 'return new numeric.T(numeric.sin(x.x));', + 'return x.exp().sub(x.neg().exp()).div(new numeric.T(0,2));'); +numeric.T.prototype.cos = numeric.Tunop( + 'return new numeric.T(numeric.cos(x.x));', + 'return x.exp().add(x.neg().exp()).div(2);'); +numeric.T.prototype.abs = numeric.Tunop( + 'return new numeric.T(numeric.abs(x.x));', + 'return new numeric.T(numeric.sqrt(numeric.add(mul(x.x,x.x),mul(x.y,x.y))));', + 'var mul = numeric.mul;'); +numeric.T.prototype.log = numeric.Tunop( + 'return new numeric.T(numeric.log(x.x));', + 'var theta = new numeric.T(numeric.atan2(x.y,x.x)), r = x.abs();\n'+ + 'return new numeric.T(numeric.log(r.x),theta.x);'); +numeric.T.prototype.norm2 = numeric.Tunop( + 'return numeric.norm2(x.x);', + 'var f = numeric.norm2Squared;\n'+ + 'return Math.sqrt(f(x.x)+f(x.y));'); + +numeric.T.prototype.inv = function inv() { + var A = this; + if(typeof A.y === "undefined") { return new numeric.T(numeric.inv(A.x)); } + var n = A.x.length, i, j, k; + var Rx = numeric.identity(n),Ry = numeric.rep([n,n],0); + var Ax = numeric.clone(A.x), Ay = numeric.clone(A.y); + var Aix, Aiy, Ajx, Ajy, Rix, Riy, Rjx, Rjy; + var i,j,k,d,d1,ax,ay,bx,by,temp; + for(i=0;i d) { k=j; d = d1; } + } + if(k!==i) { + temp = Ax[i]; Ax[i] = Ax[k]; Ax[k] = temp; + temp = Ay[i]; Ay[i] = Ay[k]; Ay[k] = temp; + temp = Rx[i]; Rx[i] = Rx[k]; Rx[k] = temp; + temp = Ry[i]; Ry[i] = Ry[k]; Ry[k] = temp; + } + Aix = Ax[i]; Aiy = Ay[i]; + Rix = Rx[i]; Riy = Ry[i]; + ax = Aix[i]; ay = Aiy[i]; + for(j=i+1;j0;i--) { + Rix = Rx[i]; Riy = Ry[i]; + for(j=i-1;j>=0;j--) { + Rjx = Rx[j]; Rjy = Ry[j]; + ax = Ax[j][i]; ay = Ay[j][i]; + for(k=n-1;k>=0;k--) { + bx = Rix[k]; by = Riy[k]; + Rjx[k] -= ax*bx - ay*by; + Rjy[k] -= ax*by + ay*bx; + } + } + } + return new numeric.T(Rx,Ry); +}; + +numeric.T.prototype.get = function get(i) { + var x = this.x, y = this.y, k = 0, ik, n = i.length; + if(y) { + while(k= 0 ? 1 : -1; + var alpha = s*numeric.norm2(x); + v[0] += alpha; + var foo = numeric.norm2(v); + if(foo === 0) { /* this should not happen */ throw new Error('eig: internal error'); } + return numeric.div(v,foo); +}; + +// upper hessenberg +numeric.toUpperHessenberg = function toUpperHessenberg(me) { + var s = numeric.dim(me); + if(s.length !== 2 || s[0] !== s[1]) { throw new Error('numeric: toUpperHessenberg() only works on square matrices'); } + var m = s[0], i,j,k,x,v,A = numeric.clone(me),B,C,Ai,Ci,Q = numeric.identity(m),Qi; + for(j=0;j0) { + v = numeric.house(x); + B = numeric.getBlock(A,[j+1,j],[m-1,m-1]); + C = numeric.tensor(v,numeric.dot(v,B)); + for(i=j+1;i=4*det) { + var s1,s2; + s1 = 0.5*(tr+Math.sqrt(tr*tr-4*det)); + s2 = 0.5*(tr-Math.sqrt(tr*tr-4*det)); + Hloc = numeric.add(numeric.sub(numeric.dot(Hloc,Hloc), + numeric.mul(Hloc,s1+s2)), + numeric.diag(numeric.rep([3],s1*s2))); + } else { + Hloc = numeric.add(numeric.sub(numeric.dot(Hloc,Hloc), + numeric.mul(Hloc,tr)), + numeric.diag(numeric.rep([3],det))); + } + x = [Hloc[0][0],Hloc[1][0],Hloc[2][0]]; + v = numeric.house(x); + B = [H[0],H[1],H[2]]; + C = numeric.tensor(v,numeric.dot(v,B)); + for(i=0;i<3;i++) { Hi = H[i]; Ci = C[i]; for(k=0;k 4 && termp == Math.abs(d[p]) && termq == Math.abs(d[q])) + { + // remove small elmts + A[p][q] = 0; + } + else + { + if (Math.abs(A[p][q]) >= tresh) + { + // apply rotation + h = d[q] - d[p]; + term = Math.abs(h) + gapq; + if (term == Math.abs(h)) + { + t = A[p][q]/h; + } + else + { + theta = 0.5 * h / A[p][q]; + t = 1/(Math.abs(theta) + Math.sqrt(1 + theta*theta)); + if (theta < 0) + { + t = -t; + } + } + c = 1/Math.sqrt(1 + t*t); + s = t * c; + tau = s/(1 + c); + h = t * A[p][q]; + zw[p] = zw[p] - h; + zw[q] = zw[q] + h; + d[p] = d[p] - h; + d[q] = d[q] + h; + A[p][q] = 0; + // rotate and use upper tria only + for (var j = 0; j < p; j++) + { + g = A[j][p]; + h = A[j][q]; + A[j][p] = g - s * (h + g * tau); + A[j][q] = h + s * (g - h * tau); + } + for (var j = p + 1; j < q; j++) + { + g = A[p][j]; + h = A[j][q]; + A[p][j] = g - s * (h + g * tau); + A[j][q] = h + s * (g - h * tau); + } + for (var j = q + 1; j < n; j++) + { + g = A[p][j]; + h = A[q][j]; + A[p][j] = g - s * (h + g * tau); + A[q][j] = h + s * (g - h * tau); + } + // eigenstates + for (var j = 0; j < n; j++) + { + g = v[j][p]; + h = v[j][q]; + v[j][p] = g - s * (h + g * tau); + v[j][q] = h + s * (g - h * tau); + } + nrot++; + } + } + } + } + bw = numeric.add(bw, zw); + d = numeric.clone(bw); + zw = numeric.rep([n], 0); + } + + return {E: {x: v}, lambda: {x: d}, iterations: iters, niter: niter, nrot: nrot}; +} + +numeric.jacobinorm = function(A) +{ + // used in numeric.jacobi + var n = A.length; + var s = 0; + for (var i = 0; i < n; i ++) + { + for (var j = i + 1; j < n; j ++) + { + s = s + Math.pow(A[i][j], 2) + } + } + return Math.sqrt(s); +} + +// eig function +numeric.eig = function eig(A,maxiter) { + var QH = numeric.toUpperHessenberg(A); + var QB = numeric.QRFrancis(QH.H,maxiter); + var T = numeric.T; + var n = A.length,i,k,flag = false,B = QB.B,H = numeric.dot(QB.Q,numeric.dot(QH.H,numeric.transpose(QB.Q))); + var Q = new T(numeric.dot(QB.Q,QH.Q)),Q0; + var m = B.length,j; + var a,b,c,d,p1,p2,disc,x,y,p,q,n1,n2; + var sqrt = Math.sqrt; + for(k=0;k=0) { + if(p1<0) x = -0.5*(p1-sqrt(disc)); + else x = -0.5*(p1+sqrt(disc)); + n1 = (a-x)*(a-x)+b*b; + n2 = c*c+(d-x)*(d-x); + if(n1>n2) { + n1 = sqrt(n1); + p = (a-x)/n1; + q = b/n1; + } else { + n2 = sqrt(n2); + p = c/n2; + q = (d-x)/n2; + } + Q0 = new T([[q,-p],[p,q]]); + Q.setRows(i,j,Q0.dot(Q.getRows(i,j))); + } else { + x = -0.5*p1; + y = 0.5*sqrt(-disc); + n1 = (a-x)*(a-x)+b*b; + n2 = c*c+(d-x)*(d-x); + if(n1>n2) { + n1 = sqrt(n1+y*y); + p = (a-x)/n1; + q = b/n1; + x = 0; + y /= n1; + } else { + n2 = sqrt(n2+y*y); + p = c/n2; + q = (d-x)/n2; + x = y/n2; + y = 0; + } + Q0 = new T([[q,-p],[p,q]],[[x,y],[y,-x]]); + Q.setRows(i,j,Q0.dot(Q.getRows(i,j))); + } + } + } + var R = Q.dot(A).dot(Q.transjugate()), n = A.length, E = numeric.T.identity(n); + for(j=0;j0) { + for(k=j-1;k>=0;k--) { + var Rk = R.get([k,k]), Rj = R.get([j,j]); + if(numeric.neq(Rk.x,Rj.x) || numeric.neq(Rk.y,Rj.y)) { + x = R.getRow(k).getBlock([k],[j-1]); + y = E.getRow(j).getBlock([k],[j-1]); + E.set([j,k],(R.get([k,j]).neg().sub(x.dot(y))).div(Rk.sub(Rj))); + } else { + E.setRow(j,E.getRow(k)); + continue; + } + } + } + } + for(j=0;j=counts.length) counts[counts.length] = 0; + if(foo[j]!==0) counts[j]++; + } + } + var n = counts.length; + var Ai = Array(n+1); + Ai[0] = 0; + for(i=0;i= k11) { + xj[n] = j[m]; + if(m===0) return; + ++n; + --m; + km = k[m]; + k11 = k1[m]; + } else { + foo = Pinv[Aj[km]]; + if(x[foo] === 0) { + x[foo] = 1; + k[m] = km; + ++m; + j[m] = foo; + km = Ai[foo]; + k1[m] = k11 = Ai[foo+1]; + } else ++km; + } + } +}; + +numeric.ccsLPSolve = function ccsLPSolve(A,B,x,xj,I,Pinv,dfs) { + var Ai = A[0], Aj = A[1], Av = A[2],m = Ai.length-1, n=0; + var Bi = B[0], Bj = B[1], Bv = B[2]; + + var i,i0,i1,j,J,j0,j1,k,l,l0,l1,a; + i0 = Bi[I]; + i1 = Bi[I+1]; + xj.length = 0; + for(i=i0;i a) { e = k; a = c; } + } + if(abs(x[i])= k11) { + xj[n] = Pinv[j[m]]; + if(m===0) return; + ++n; + --m; + km = k[m]; + k11 = k1[m]; + } else { + foo = Aj[km]; + if(x[foo] === 0) { + x[foo] = 1; + k[m] = km; + ++m; + j[m] = foo; + foo = Pinv[foo]; + km = Ai[foo]; + k1[m] = k11 = Ai[foo+1]; + } else ++km; + } + } +}; + +numeric.ccsLPSolve0 = function ccsLPSolve0(A,B,y,xj,I,Pinv,P,dfs) { + var Ai = A[0], Aj = A[1], Av = A[2],m = Ai.length-1, n=0; + var Bi = B[0], Bj = B[1], Bv = B[2]; + + var i,i0,i1,j,J,j0,j1,k,l,l0,l1,a; + i0 = Bi[I]; + i1 = Bi[I+1]; + xj.length = 0; + for(i=i0;i a) { e = k; a = c; } + } + if(abs(y[P[i]]) ret[k]) ret[k] = A.length; + var i; + for(i in A) { + if(A.hasOwnProperty(i)) dim(A[i],ret,k+1); + } + return ret; +}; + +numeric.sclone = function clone(A,k,n) { + if(typeof k === "undefined") { k=0; } + if(typeof n === "undefined") { n = numeric.sdim(A).length; } + var i,ret = Array(A.length); + if(k === n-1) { + for(i in A) { if(A.hasOwnProperty(i)) ret[i] = A[i]; } + return ret; + } + for(i in A) { + if(A.hasOwnProperty(i)) ret[i] = clone(A[i],k+1,n); + } + return ret; +}; + +numeric.sdiag = function diag(d) { + var n = d.length,i,ret = Array(n),i1,i2,i3; + for(i=n-1;i>=1;i-=2) { + i1 = i-1; + ret[i] = []; ret[i][i] = d[i]; + ret[i1] = []; ret[i1][i1] = d[i1]; + } + if(i===0) { ret[0] = []; ret[0][0] = d[i]; } + return ret; +}; + +numeric.sidentity = function identity(n) { return numeric.sdiag(numeric.rep([n],1)); }; + +numeric.stranspose = function transpose(A) { + var ret = [], n = A.length, i,j,Ai; + for(i in A) { + if(!(A.hasOwnProperty(i))) continue; + Ai = A[i]; + for(j in Ai) { + if(!(Ai.hasOwnProperty(j))) continue; + if(typeof ret[j] !== "object") { ret[j] = []; } + ret[j][i] = Ai[j]; + } + } + return ret; +}; + +numeric.sLUP = function LUP(A,tol) { + throw new Error("The function numeric.sLUP had a bug in it and has been removed. Please use the new numeric.ccsLUP function instead."); +}; + +numeric.sdotMM = function dotMM(A,B) { + var p = A.length, q = B.length, BT = numeric.stranspose(B), r = BT.length, Ai, BTk; + var i,j,k,accum; + var ret = Array(p),reti; + for(i=p-1;i>=0;i--) { + reti = []; + Ai = A[i]; + for(k=r-1;k>=0;k--) { + accum = 0; + BTk = BT[k]; + for(j in Ai) { + if(!(Ai.hasOwnProperty(j))) continue; + if(j in BTk) { accum += Ai[j]*BTk[j]; } + } + if(accum) reti[k] = accum; + } + ret[i] = reti; + } + return ret; +}; + +numeric.sdotMV = function dotMV(A,x) { + var p = A.length, Ai, i,j; + var ret = Array(p), accum; + for(i=p-1;i>=0;i--) { + Ai = A[i]; + accum = 0; + for(j in Ai) { + if(!(Ai.hasOwnProperty(j))) continue; + if(x[j]) accum += Ai[j]*x[j]; + } + if(accum) ret[i] = accum; + } + return ret; +}; + +numeric.sdotVM = function dotMV(x,A) { + var i,j,Ai,alpha; + var ret = [], 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]; + } + } + return ret; +}; + +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; +}; + +numeric.sdot = function dot(A,B) { + var m = numeric.sdim(A).length, n = numeric.sdim(B).length; + var k = m*1000+n; + switch(k) { + case 0: return A*B; + case 1001: return numeric.sdotVV(A,B); + case 2001: return numeric.sdotMV(A,B); + case 1002: return numeric.sdotVM(A,B); + case 2002: return numeric.sdotMM(A,B); + default: throw new Error('numeric.sdot not implemented for tensors of order '+m+' and '+n); + } +}; + +numeric.sscatter = function scatter(V) { + var n = V[0].length, Vij, i, j, m = V.length, A = [], Aj; + for(i=n-1;i>=0;--i) { + if(!V[m-1][i]) continue; + Aj = A; + for(j=0;j=0;--i) ret[i] = []; + } + for(i=n;i>=0;--i) ret[i].push(k[i]); + ret[n+1].push(Ai); + } + } else gather(Ai,ret,k); + } + } + if(k.length>n) k.pop(); + return ret; +}; + +// 6. Coordinate matrices +numeric.cLU = function LU(A) { + var I = A[0], J = A[1], V = A[2]; + var p = I.length, m=0, i,j,k,a,b,c; + for(i=0;im) m=I[i]; + m++; + var L = Array(m), U = Array(m), left = numeric.rep([m],Infinity), right = numeric.rep([m],-Infinity); + var Ui, Uj,alpha; + for(k=0;kright[i]) right[i] = j; + } + for(i=0;i right[i+1]) right[i+1] = right[i]; } + for(i=m-1;i>=1;i--) { if(left[i]=0;i--) { + while(Uj[k] > i) { + ret[i] -= Uv[k]*ret[Uj[k]]; + k--; + } + ret[i] /= Uv[k]; + k--; + } + return ret; +}; + +numeric.cgrid = function grid(n,shape) { + if(typeof n === "number") n = [n,n]; + var ret = numeric.rep(n,-1); + var i,j,count; + if(typeof shape !== "function") { + switch(shape) { + case 'L': + shape = function(i,j) { return (i>=n[0]/2 || jN) N = Ai[k]; } + N++; + ret = numeric.rep([N],0); + for(k=0;k1) { + mid = floor((p+q)/2); + if(x[mid] <= x0) p = mid; + else q = mid; + } + return this._at(x0,p); + } + var n = x0.length, i, ret = Array(n); + for(i=n-1;i!==-1;--i) ret[i] = this.at(x0[i]); + return ret; +}; + +numeric.Spline.prototype.diff = function diff() { + var x = this.x; + var yl = this.yl; + var yr = this.yr; + var kl = this.kl; + var kr = this.kr; + var n = yl.length; + var i,dx,dy; + var zl = kl, zr = kr, pl = Array(n), pr = Array(n); + var add = numeric.add, mul = numeric.mul, div = numeric.div, sub = numeric.sub; + for(i=n-1;i!==-1;--i) { + dx = x[i+1]-x[i]; + dy = sub(yr[i+1],yl[i]); + pl[i] = div(add(mul(dy, 6),mul(kl[i],-4*dx),mul(kr[i+1],-2*dx)),dx*dx); + pr[i+1] = div(add(mul(dy,-6),mul(kl[i], 2*dx),mul(kr[i+1], 4*dx)),dx*dx); + } + return new numeric.Spline(x,zl,zr,pl,pr); +}; + +numeric.Spline.prototype.roots = function roots() { + function sqr(x) { return x*x; } + function heval(y0,y1,k0,k1,x) { + var A = k0*2-(y1-y0); + var B = -k1*2+(y1-y0); + var t = (x+1)*0.5; + var s = t*(1-t); + return (1-t)*y0+t*y1+A*s*(1-t)+B*s*t; + } + var ret = []; + var x = this.x, yl = this.yl, yr = this.yr, kl = this.kl, kr = this.kr; + if(typeof yl[0] === "number") { + yl = [yl]; + yr = [yr]; + kl = [kl]; + kr = [kr]; + } + var m = yl.length,n=x.length-1,i,j,k,y,s,t; + var ai,bi,ci,di, ret = Array(m),ri,k0,k1,y0,y1,A,B,D,dx,cx,stops,z0,z1,zm,t0,t1,tm; + var sqrt = Math.sqrt; + for(i=0;i!==m;++i) { + ai = yl[i]; + bi = yr[i]; + ci = kl[i]; + di = kr[i]; + ri = []; + for(j=0;j!==n;j++) { + if(j>0 && bi[j]*ai[j]<0) ri.push(x[j]); + dx = (x[j+1]-x[j]); + cx = x[j]; + y0 = ai[j]; + y1 = bi[j+1]; + k0 = ci[j]/dx; + k1 = di[j+1]/dx; + D = sqr(k0-k1+3*(y0-y1)) + 12*k1*y0; + A = k1+3*y0+2*k0-3*y1; + B = 3*(k1+k0+2*(y0-y1)); + if(D<=0) { + z0 = A/B; + if(z0>x[j] && z0x[j] && z0x[j] && z10) { + t0 = t1; + z0 = z1; + continue; + } + var side = 0; + while(1) { + tm = (z0*t1-z1*t0)/(z0-z1); + if(tm <= t0 || tm >= t1) { break; } + zm = this._at(tm,j); + if(zm*z1>0) { + t1 = tm; + z1 = zm; + if(side === -1) z0*=0.5; + side = -1; + } else if(zm*z0>0) { + t0 = tm; + z0 = zm; + if(side === 1) z1*=0.5; + side = 1; + } else break; + } + ri.push(tm); + t0 = stops[k+1]; + z0 = this._at(t0, j); + } + if(z1 === 0) ri.push(t1); + } + ret[i] = ri; + } + if(typeof this.yl[0] === "number") return ret[0]; + return ret; +}; + +numeric.spline = function spline(x,y,k1,kn) { + var n = x.length, b = [], dx = [], dy = []; + var i; + var sub = numeric.sub,mul = numeric.mul,add = numeric.add; + for(i=n-2;i>=0;i--) { dx[i] = x[i+1]-x[i]; dy[i] = sub(y[i+1],y[i]); } + if(typeof k1 === "string" || typeof kn === "string") { + k1 = kn = "periodic"; + } + // Build sparse tridiagonal system + var T = [[],[],[]]; + switch(typeof k1) { + case "undefined": + b[0] = mul(3/(dx[0]*dx[0]),dy[0]); + T[0].push(0,0); + T[1].push(0,1); + T[2].push(2/dx[0],1/dx[0]); + break; + case "string": + b[0] = add(mul(3/(dx[n-2]*dx[n-2]),dy[n-2]),mul(3/(dx[0]*dx[0]),dy[0])); + T[0].push(0,0,0); + T[1].push(n-2,0,1); + T[2].push(1/dx[n-2],2/dx[n-2]+2/dx[0],1/dx[0]); + break; + default: + b[0] = k1; + T[0].push(0); + T[1].push(0); + T[2].push(1); + break; + } + for(i=1;i20) { throw new Error("Numerical gradient fails"); } + x0[i] = x[i]+h; + f1 = f(x0); + x0[i] = x[i]-h; + f2 = f(x0); + x0[i] = x[i]; + if(isNaN(f1) || isNaN(f2)) { h/=16; continue; } + J[i] = (f1-f2)/(2*h); + t0 = x[i]-h; + t1 = x[i]; + t2 = x[i]+h; + d1 = (f1-f0)/h; + d2 = (f0-f2)/h; + N = max(abs(J[i]),abs(f0),abs(f1),abs(f2),abs(t0),abs(t1),abs(t2),1e-8); + errest = min(max(abs(d1-J[i]),abs(d2-J[i]),abs(d1-d2))/N,h/N); + if(errest>eps) { h/=16; } + else break; + } + } + return J; +}; + +numeric.uncmin = function uncmin(f,x0,tol,gradient,maxit,callback,options) { + var grad = numeric.gradient; + if(typeof options === "undefined") { options = {}; } + if(typeof tol === "undefined") { tol = 1e-8; } + if(typeof gradient === "undefined") { gradient = function(x) { return grad(f,x); }; } + if(typeof maxit === "undefined") maxit = 1000; + x0 = numeric.clone(x0); + var n = x0.length; + var f0 = f(x0),f1,df0; + if(isNaN(f0)) throw new Error('uncmin: f(x0) is a NaN!'); + var max = Math.max, norm2 = numeric.norm2; + tol = max(tol,numeric.epsilon); + var step,g0,g1,H1 = options.Hinv || numeric.identity(n); + var dot = numeric.dot, inv = numeric.inv, sub = numeric.sub, add = numeric.add, ten = numeric.tensor, div = numeric.div, mul = numeric.mul; + var all = numeric.all, isfinite = numeric.isFinite, neg = numeric.neg; + var it=0,i,s,x1,y,Hy,Hs,ys,i0,t,nstep,t1,t2; + var msg = ""; + g0 = gradient(x0); + while(it= 0.1*t*df0 || isNaN(f1)) { + t *= 0.5; + ++it; + continue; + } + break; + } + if(t*nstep < tol) { msg = "Line search step size smaller than tol"; break; } + if(it === maxit) { msg = "maxit reached during line search"; break; } + g1 = gradient(x1); + y = sub(g1,g0); + ys = dot(y,s); + Hy = dot(H1,y); + H1 = sub(add(H1, + mul( + (ys+dot(y,Hy))/(ys*ys), + ten(s,s) )), + div(add(ten(Hy,s),ten(s,Hy)),ys)); + x0 = x1; + f0 = f1; + g0 = g1; + ++it; + } + return {solution: x0, f: f0, gradient: g0, invHessian: H1, iterations:it, message: msg}; +}; + +// 10. Ode solver (Dormand-Prince) +numeric.Dopri = function Dopri(x,y,f,ymid,iterations,msg,events) { + this.x = x; + this.y = y; + this.f = f; + this.ymid = ymid; + this.iterations = iterations; + this.events = events; + this.message = msg; +}; + +numeric.Dopri.prototype._at = function _at(xi,j) { + function sqr(x) { return x*x; } + var sol = this; + var xs = sol.x; + var ys = sol.y; + var k1 = sol.f; + var ymid = sol.ymid; + var n = xs.length; + var x0,x1,xh,y0,y1,yh,xi; + var floor = Math.floor,h; + var c = 0.5; + var add = numeric.add, mul = numeric.mul,sub = numeric.sub, p,q,w; + x0 = xs[j]; + x1 = xs[j+1]; + y0 = ys[j]; + y1 = ys[j+1]; + h = x1-x0; + xh = x0+c*h; + yh = ymid[j]; + p = sub(k1[j ],mul(y0,1/(x0-xh)+2/(x0-x1))); + q = sub(k1[j+1],mul(y1,1/(x1-xh)+2/(x1-x0))); + w = [sqr(xi - x1) * (xi - xh) / sqr(x0 - x1) / (x0 - xh), + sqr(xi - x0) * sqr(xi - x1) / sqr(x0 - xh) / sqr(x1 - xh), + sqr(xi - x0) * (xi - xh) / sqr(x1 - x0) / (x1 - xh), + (xi - x0) * sqr(xi - x1) * (xi - xh) / sqr(x0-x1) / (x0 - xh), + (xi - x1) * sqr(xi - x0) * (xi - xh) / sqr(x0-x1) / (x1 - xh)]; + return add(add(add(add(mul(y0,w[0]), + mul(yh,w[1])), + mul(y1,w[2])), + mul( p,w[3])), + mul( q,w[4])); +}; + +numeric.Dopri.prototype.at = function at(x) { + var i,j,k,floor = Math.floor; + if(typeof x !== "number") { + var n = x.length, ret = Array(n); + for(i=n-1;i!==-1;--i) { + ret[i] = this.at(x[i]); + } + return ret; + } + var x0 = this.x; + i = 0; j = x0.length-1; + while(j-i>1) { + k = floor(0.5*(i+j)); + if(x0[k] <= x) i = k; + else j = k; + } + return this._at(x,i); +}; + +numeric.dopri = function dopri(x0,x1,y0,f,tol,maxit,event) { + if(typeof tol === "undefined") { tol = 1e-6; } + if(typeof maxit === "undefined") { maxit = 1000; } + var xs = [x0], ys = [y0], k1 = [f(x0,y0)], k2,k3,k4,k5,k6,k7, ymid = []; + var A2 = 1/5; + var A3 = [3/40,9/40]; + var A4 = [44/45,-56/15,32/9]; + var A5 = [19372/6561,-25360/2187,64448/6561,-212/729]; + var A6 = [9017/3168,-355/33,46732/5247,49/176,-5103/18656]; + var b = [35/384,0,500/1113,125/192,-2187/6784,11/84]; + var bm = [0.5*6025192743/30085553152, + 0, + 0.5*51252292925/65400821598, + 0.5*-2691868925/45128329728, + 0.5*187940372067/1594534317056, + 0.5*-1776094331/19743644256, + 0.5*11237099/235043384]; + var c = [1/5,3/10,4/5,8/9,1,1]; + var e = [-71/57600,0,71/16695,-71/1920,17253/339200,-22/525,1/40]; + var i = 0,er,j; + var h = (x1-x0)/10; + var it = 0; + var add = numeric.add, mul = numeric.mul, y1,erinf; + var max = Math.max, min = Math.min, abs = Math.abs, norminf = numeric.norminf,pow = Math.pow; + var any = numeric.any, lt = numeric.lt, and = numeric.and, sub = numeric.sub; + var e0, e1, ev; + var ret = new numeric.Dopri(xs,ys,k1,ymid,-1,""); + if(typeof event === "function") e0 = event(x0,y0); + while(x0x1) h = x1-x0; + k2 = f(x0+c[0]*h, add(y0,mul( A2*h,k1[i]))); + k3 = f(x0+c[1]*h, add(add(y0,mul(A3[0]*h,k1[i])),mul(A3[1]*h,k2))); + k4 = f(x0+c[2]*h, add(add(add(y0,mul(A4[0]*h,k1[i])),mul(A4[1]*h,k2)),mul(A4[2]*h,k3))); + k5 = f(x0+c[3]*h, add(add(add(add(y0,mul(A5[0]*h,k1[i])),mul(A5[1]*h,k2)),mul(A5[2]*h,k3)),mul(A5[3]*h,k4))); + k6 = f(x0+c[4]*h,add(add(add(add(add(y0,mul(A6[0]*h,k1[i])),mul(A6[1]*h,k2)),mul(A6[2]*h,k3)),mul(A6[3]*h,k4)),mul(A6[4]*h,k5))); + y1 = add(add(add(add(add(y0,mul(k1[i],h*b[0])),mul(k3,h*b[2])),mul(k4,h*b[3])),mul(k5,h*b[4])),mul(k6,h*b[5])); + k7 = f(x0+h,y1); + er = add(add(add(add(add(mul(k1[i],h*e[0]),mul(k3,h*e[2])),mul(k4,h*e[3])),mul(k5,h*e[4])),mul(k6,h*e[5])),mul(k7,h*e[6])); + if(typeof er === "number") erinf = abs(er); + else erinf = norminf(er); + if(erinf > tol) { // reject + h = 0.2*h*pow(tol/erinf,0.25); + if(x0+h === x0) { + ret.msg = "Step size became too small"; + break; + } + continue; + } + ymid[i] = add(add(add(add(add(add(y0, + mul(k1[i],h*bm[0])), + mul(k3 ,h*bm[2])), + mul(k4 ,h*bm[3])), + mul(k5 ,h*bm[4])), + mul(k6 ,h*bm[5])), + mul(k7 ,h*bm[6])); + ++i; + xs[i] = x0+h; + ys[i] = y1; + k1[i] = k7; + if(typeof event === "function") { + var yi,xl = x0,xr = x0+0.5*h,xi; + e1 = event(xr,ymid[i-1]); + ev = and(lt(e0,0),lt(0,e1)); + if(!any(ev)) { xl = xr; xr = x0+h; e0 = e1; e1 = event(xr,y1); ev = and(lt(e0,0),lt(0,e1)); } + if(any(ev)) { + var xc, yc, en,ei; + var side=0, sl = 1.0, sr = 1.0; + while(1) { + if(typeof e0 === "number") xi = (sr*e1*xl-sl*e0*xr)/(sr*e1-sl*e0); + else { + xi = xr; + for(j=e0.length-1;j!==-1;--j) { + if(e0[j]<0 && e1[j]>0) xi = min(xi,(sr*e1[j]*xl-sl*e0[j]*xr)/(sr*e1[j]-sl*e0[j])); + } + } + if(xi <= xl || xi >= xr) break; + yi = ret._at(xi, i-1); + ei = event(xi,yi); + en = and(lt(e0,0),lt(0,ei)); + if(any(en)) { + xr = xi; + e1 = ei; + ev = en; + sr = 1.0; + if(side === -1) sl *= 0.5; + else sl = 1.0; + side = -1; + } else { + xl = xi; + e0 = ei; + sl = 1.0; + if(side === 1) sr *= 0.5; + else sr = 1.0; + side = 1; + } + } + y1 = ret._at(0.5*(x0+xi),i-1); + ret.f[i] = f(xi,yi); + ret.x[i] = xi; + ret.y[i] = yi; + ret.ymid[i-1] = y1; + ret.events = ev; + ret.iterations = it; + return ret; + } + } + x0 += h; + y0 = y1; + e0 = e1; + h = min(0.8*h*pow(tol/erinf,0.25),4*h); + } + ret.iterations = it; + return ret; +}; + +// 11. Ax = b +numeric.LU = function(A, fast) { + fast = fast || false; + + var abs = Math.abs; + var i, j, k, absAjk, Akk, Ak, Pk, Ai; + var max; + var n = A.length, n1 = n-1; + var P = new Array(n); + if(!fast) A = numeric.clone(A); + + for (k = 0; k < n; ++k) { + Pk = k; + Ak = A[k]; + max = abs(Ak[k]); + for (j = k + 1; j < n; ++j) { + absAjk = abs(A[j][k]); + if (max < absAjk) { + max = absAjk; + Pk = j; + } + } + P[k] = Pk; + + if (Pk != k) { + A[k] = A[Pk]; + A[Pk] = Ak; + Ak = A[k]; + } + + Akk = Ak[k]; + + for (i = k + 1; i < n; ++i) { + A[i][k] /= Akk; + } + + for (i = k + 1; i < n; ++i) { + Ai = A[i]; + for (j = k + 1; j < n1; ++j) { + Ai[j] -= Ai[k] * Ak[j]; + ++j; + Ai[j] -= Ai[k] * Ak[j]; + } + if(j===n1) Ai[j] -= Ai[k] * Ak[j]; + } + } + + return { + LU: A, + P: P + }; +}; + +numeric.LUsolve = function LUsolve(LUP, b) { + var i, j; + var LU = LUP.LU; + var n = LU.length; + var x = numeric.clone(b); + var P = LUP.P; + var Pi, LUi, LUii, tmp; + + for (i=n-1;i!==-1;--i) x[i] = b[i]; + for (i = 0; i < n; ++i) { + Pi = P[i]; + if (P[i] !== i) { + tmp = x[i]; + x[i] = x[Pi]; + x[Pi] = tmp; + } + + LUi = LU[i]; + for (j = 0; j < i; ++j) { + x[i] -= x[j] * LUi[j]; + } + } + + for (i = n - 1; i >= 0; --i) { + LUi = LU[i]; + for (j = i + 1; j < n; ++j) { + x[i] -= x[j] * LUi[j]; + } + + x[i] /= LUi[i]; + } + + return x; +}; + +numeric.solve = function solve(A,b,fast) { return numeric.LUsolve(numeric.LU(A,fast), b); }; + +// 12. Linear programming +numeric.echelonize = function echelonize(A) { + var s = numeric.dim(A), m = s[0], n = s[1]; + var I = numeric.identity(m); + var P = Array(m); + var i,j,k,l,Ai,Ii,Z,a; + var abs = Math.abs; + var diveq = numeric.diveq; + A = numeric.clone(A); + for(i=0;ia1) alpha = a1; + g = add(c,mul(alpha,p)); + H = dot(A1,A0); + for(i=m-1;i!==-1;--i) H[i][i] += 1; + d = solve(H,div(g,alpha),true); + var t0 = div(z,dot(A,d)); + var t = 1.0; + for(i=n-1;i!==-1;--i) if(t0[i]<0) t = min(t,-0.999*t0[i]); + y = sub(x,mul(d,t)); + z = sub(b,dot(A,y)); + if(!all(gt(z,0))) return { solution: x, message: "", iterations: count }; + x = y; + if(alpha=0) unbounded = false; + else unbounded = true; + } + if(unbounded) return { solution: y, message: "Unbounded", iterations: count }; + } + return { solution: x, message: "maximum iteration count exceeded", iterations:count }; +}; + +numeric._solveLP = function _solveLP(c,A,b,tol,maxit) { + var m = c.length, n = b.length,y; + var sum = numeric.sum, log = numeric.log, mul = numeric.mul, sub = numeric.sub, dot = numeric.dot, div = numeric.div, add = numeric.add; + var c0 = numeric.rep([m],0).concat([1]); + var J = numeric.rep([n,1],-1); + var A0 = numeric.blockMatrix([[A , J ]]); + var b0 = b; + var y = numeric.rep([m],0).concat(Math.max(0,numeric.sup(numeric.neg(b)))+1); + var x0 = numeric.__solveLP(c0,A0,b0,tol,maxit,y,false); + var x = numeric.clone(x0.solution); + x.length = m; + var foo = numeric.inf(sub(b,dot(A,x))); + if(foo<0) { return { solution: NaN, message: "Infeasible", iterations: x0.iterations }; } + var ret = numeric.__solveLP(c, A, b, tol, maxit-x0.iterations, x, true); + ret.iterations += x0.iterations; + return ret; +}; + +numeric.solveLP = function solveLP(c,A,b,Aeq,beq,tol,maxit) { + if(typeof maxit === "undefined") maxit = 1000; + if(typeof tol === "undefined") tol = numeric.epsilon; + if(typeof Aeq === "undefined") return numeric._solveLP(c,A,b,tol,maxit); + var m = Aeq.length, n = Aeq[0].length, o = A.length; + var B = numeric.echelonize(Aeq); + var flags = numeric.rep([n],0); + var P = B.P; + var Q = []; + var i; + for(i=P.length-1;i!==-1;--i) flags[P[i]] = 1; + for(i=n-1;i!==-1;--i) if(flags[i]===0) Q.push(i); + var g = numeric.getRange; + var I = numeric.linspace(0,m-1), J = numeric.linspace(0,o-1); + var Aeq2 = g(Aeq,I,Q), A1 = g(A,J,P), A2 = g(A,J,Q), dot = numeric.dot, sub = numeric.sub; + var A3 = dot(A1,B.I); + var A4 = sub(A2,dot(A3,Aeq2)), b4 = sub(b,dot(A3,beq)); + var c1 = Array(P.length), c2 = Array(Q.length); + for(i=P.length-1;i!==-1;--i) c1[i] = c[P[i]]; + for(i=Q.length-1;i!==-1;--i) c2[i] = c[Q[i]]; + var c4 = sub(c2,dot(c1,dot(B.I,Aeq2))); + var S = numeric._solveLP(c4,A4,b4,tol,maxit); + var x2 = S.solution; + if(x2!==x2) return S; + var x1 = dot(B.I,sub(beq,dot(Aeq2,x2))); + var x = Array(c.length); + for(i=P.length-1;i!==-1;--i) x[P[i]] = x1[i]; + for(i=Q.length-1;i!==-1;--i) x[Q[i]] = x2[i]; + return { solution: x, message:S.message, iterations: S.iterations }; +}; + +numeric.MPStoLP = function MPStoLP(MPS) { + if(MPS instanceof String) { MPS.split('\n'); } + var state = 0; + var states = ['Initial state','NAME','ROWS','COLUMNS','RHS','BOUNDS','ENDATA']; + var n = MPS.length; + var i,j,z,N=0,rows = {}, sign = [], rl = 0, vars = {}, nv = 0; + var name; + var c = [], A = [], b = []; + function err(e) { throw new Error('MPStoLP: '+e+'\nLine '+i+': '+MPS[i]+'\nCurrent state: '+states[state]+'\n'); } + for(i=0;i +// +// Math.seedrandom('yipee'); Sets Math.random to a function that is +// initialized using the given explicit seed. +// +// Math.seedrandom(); Sets Math.random to a function that is +// seeded using the current time, dom state, +// and other accumulated local entropy. +// The generated seed string is returned. +// +// Math.seedrandom('yowza', true); +// Seeds using the given explicit seed mixed +// together with accumulated entropy. +// +// +// Seeds using physical random bits downloaded +// from random.org. +// +// Seeds using urandom bits from call.jsonlib.com, +// which is faster than random.org. +// +// Examples: +// +// Math.seedrandom("hello"); // Use "hello" as the seed. +// document.write(Math.random()); // Always 0.5463663768140734 +// document.write(Math.random()); // Always 0.43973793770592234 +// var rng1 = Math.random; // Remember the current prng. +// +// var autoseed = Math.seedrandom(); // New prng with an automatic seed. +// document.write(Math.random()); // Pretty much unpredictable. +// +// Math.random = rng1; // Continue "hello" prng sequence. +// document.write(Math.random()); // Always 0.554769432473455 +// +// Math.seedrandom(autoseed); // Restart at the previous seed. +// document.write(Math.random()); // Repeat the 'unpredictable' value. +// +// Notes: +// +// Each time seedrandom('arg') is called, entropy from the passed seed +// is accumulated in a pool to help generate future seeds for the +// zero-argument form of Math.seedrandom, so entropy can be injected over +// time by calling seedrandom with explicit data repeatedly. +// +// On speed - This javascript implementation of Math.random() is about +// 3-10x slower than the built-in Math.random() because it is not native +// code, but this is typically fast enough anyway. Seeding is more expensive, +// especially if you use auto-seeding. Some details (timings on Chrome 4): +// +// Our Math.random() - avg less than 0.002 milliseconds per call +// seedrandom('explicit') - avg less than 0.5 milliseconds per call +// seedrandom('explicit', true) - avg less than 2 milliseconds per call +// seedrandom() - avg about 38 milliseconds per call +// +// LICENSE (BSD): +// +// Copyright 2010 David Bau, all rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of this module nor the names of its contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/** + * All code is in an anonymous closure to keep the global namespace clean. + * + * @param {number=} overflow + * @param {number=} startdenom + */ + +// Patched by Seb so that seedrandom.js does not pollute the Math object. +// My tests suggest that doing Math.trouble = 1 makes Math lookups about 5% +// slower. +numeric.seedrandom = { pow:Math.pow, random:Math.random }; + +(function (pool, math, width, chunks, significance, overflow, startdenom) { + + +// +// seedrandom() +// This is the seedrandom function described above. +// +math['seedrandom'] = function seedrandom(seed, use_entropy) { + var key = []; + var arc4; + + // Flatten the seed string or build one from local entropy if needed. + seed = mixkey(flatten( + use_entropy ? [seed, pool] : + arguments.length ? seed : + [new Date().getTime(), pool, window], 3), key); + + // Use the seed to initialize an ARC4 generator. + arc4 = new ARC4(key); + + // Mix the randomness into accumulated entropy. + mixkey(arc4.S, pool); + + // Override Math.random + + // This function returns a random double in [0, 1) that contains + // randomness in every bit of the mantissa of the IEEE 754 value. + + math['random'] = function random() { // Closure to return a random double: + var n = arc4.g(chunks); // Start with a numerator n < 2 ^ 48 + var d = startdenom; // and denominator d = 2 ^ 48. + var x = 0; // and no 'extra last byte'. + while (n < significance) { // Fill up all significant digits by + n = (n + x) * width; // shifting numerator and + d *= width; // denominator and generating a + x = arc4.g(1); // new least-significant-byte. + } + while (n >= overflow) { // To avoid rounding up, before adding + n /= 2; // last byte, shift everything + d /= 2; // right using integer math until + x >>>= 1; // we have exactly the desired bits. + } + return (n + x) / d; // Form the number within [0, 1). + }; + + // Return the seed that was used + return seed; +}; + +// +// ARC4 +// +// An ARC4 implementation. The constructor takes a key in the form of +// an array of at most (width) integers that should be 0 <= x < (width). +// +// The g(count) method returns a pseudorandom integer that concatenates +// the next (count) outputs from ARC4. Its return value is a number x +// that is in the range 0 <= x < (width ^ count). +// +/** @constructor */ +function ARC4(key) { + var t, u, me = this, keylen = key.length; + var i = 0, j = me.i = me.j = me.m = 0; + me.S = []; + me.c = []; + + // The empty key [] is treated as [0]. + if (!keylen) { key = [keylen++]; } + + // Set up S using the standard key scheduling algorithm. + while (i < width) { me.S[i] = i++; } + for (i = 0; i < width; i++) { + t = me.S[i]; + j = lowbits(j + t + key[i % keylen]); + u = me.S[j]; + me.S[i] = u; + me.S[j] = t; + } + + // The "g" method returns the next (count) outputs as one number. + me.g = function getnext(count) { + var s = me.S; + var i = lowbits(me.i + 1); var t = s[i]; + var j = lowbits(me.j + t); var u = s[j]; + s[i] = u; + s[j] = t; + var r = s[lowbits(t + u)]; + while (--count) { + i = lowbits(i + 1); t = s[i]; + j = lowbits(j + t); u = s[j]; + s[i] = u; + s[j] = t; + r = r * width + s[lowbits(t + u)]; + } + me.i = i; + me.j = j; + return r; + }; + // For robust unpredictability discard an initial batch of values. + // See http://www.rsa.com/rsalabs/node.asp?id=2009 + me.g(width); +} + +// +// flatten() +// Converts an object tree to nested arrays of strings. +// +/** @param {Object=} result + * @param {string=} prop + * @param {string=} typ */ +function flatten(obj, depth, result, prop, typ) { + result = []; + typ = typeof(obj); + if (depth && typ == 'object') { + for (prop in obj) { + if (prop.indexOf('S') < 5) { // Avoid FF3 bug (local/sessionStorage) + try { result.push(flatten(obj[prop], depth - 1)); } catch (e) {} + } + } + } + return (result.length ? result : obj + (typ != 'string' ? '\0' : '')); +} + +// +// mixkey() +// Mixes a string seed into a key that is an array of integers, and +// returns a shortened string seed that is equivalent to the result key. +// +/** @param {number=} smear + * @param {number=} j */ +function mixkey(seed, key, smear, j) { + seed += ''; // Ensure the seed is a string + smear = 0; + for (j = 0; j < seed.length; j++) { + key[lowbits(j)] = + lowbits((smear ^= key[lowbits(j)] * 19) + seed.charCodeAt(j)); + } + seed = ''; + for (j in key) { seed += String.fromCharCode(key[j]); } + return seed; +} + +// +// lowbits() +// A quick "n mod width" for width a power of 2. +// +function lowbits(n) { return n & (width - 1); } + +// +// The following constants are related to IEEE 754 limits. +// +startdenom = math.pow(width, chunks); +significance = math.pow(2, significance); +overflow = significance * 2; + +// +// When seedrandom.js is loaded, we immediately mix a few bits +// from the built-in RNG into the entropy pool. Because we do +// not want to intefere with determinstic PRNG state later, +// seedrandom will not call math.random on its own again after +// initialization. +// +mixkey(math.random(), pool); + +// End anonymous scope, and pass initial values. +}( + [], // pool: entropy pool starts empty + numeric.seedrandom, // math: package containing random, pow, and seedrandom + 256, // width: each RC4 output is 0 <= x < 256 + 6, // chunks: at least six RC4 outputs for each double + 52 // significance: there are 52 significant digits in a double + )); +/* This file is a slightly modified version of quadprog.js from Alberto Santini. + * It has been slightly modified by Sébastien Loisel to make sure that it handles + * 0-based Arrays instead of 1-based Arrays. + * License is in resources/LICENSE.quadprog */ + +function base0to1(A) { + if(typeof A !== "object") { return A; } + var ret = [], i,n=A.length; + for(i=0;i meq) { + work[l] = sum; + } else { + work[l] = -Math.abs(sum); + if (sum > 0) { + for (j = 1; j <= n; j = j + 1) { + amat[j][i] = -amat[j][i]; + } + bvec[i] = -bvec[i]; + } + } + } + + for (i = 1; i <= nact; i = i + 1) { + work[iwsv + iact[i]] = 0; + } + + nvl = 0; + temp = 0; + for (i = 1; i <= q; i = i + 1) { + if (work[iwsv + i] < temp * work[iwnbv + i]) { + nvl = i; + temp = work[iwsv + i] / work[iwnbv + i]; + } + } + if (nvl === 0) { + return 999; + } + + return 0; + } + + function fn_goto_55() { + for (i = 1; i <= n; i = i + 1) { + sum = 0; + for (j = 1; j <= n; j = j + 1) { + sum = sum + dmat[j][i] * amat[j][nvl]; + } + work[i] = sum; + } + + l1 = iwzv; + for (i = 1; i <= n; i = i + 1) { + work[l1 + i] = 0; + } + for (j = nact + 1; j <= n; j = j + 1) { + for (i = 1; i <= n; i = i + 1) { + work[l1 + i] = work[l1 + i] + dmat[i][j] * work[j]; + } + } + + t1inf = true; + for (i = nact; i >= 1; i = i - 1) { + sum = work[i]; + l = iwrm + (i * (i + 3)) / 2; + l1 = l - i; + for (j = i + 1; j <= nact; j = j + 1) { + sum = sum - work[l] * work[iwrv + j]; + l = l + j; + } + sum = sum / work[l1]; + work[iwrv + i] = sum; + if (iact[i] < meq) { + // continue; + break; + } + if (sum < 0) { + // continue; + break; + } + t1inf = false; + it1 = i; + } + + if (!t1inf) { + t1 = work[iwuv + it1] / work[iwrv + it1]; + for (i = 1; i <= nact; i = i + 1) { + if (iact[i] < meq) { + // continue; + break; + } + if (work[iwrv + i] < 0) { + // continue; + break; + } + temp = work[iwuv + i] / work[iwrv + i]; + if (temp < t1) { + t1 = temp; + it1 = i; + } + } + } + + sum = 0; + for (i = iwzv + 1; i <= iwzv + n; i = i + 1) { + sum = sum + work[i] * work[i]; + } + if (Math.abs(sum) <= vsmall) { + if (t1inf) { + ierr[1] = 1; + // GOTO 999 + return 999; + } else { + for (i = 1; i <= nact; i = i + 1) { + work[iwuv + i] = work[iwuv + i] - t1 * work[iwrv + i]; + } + work[iwuv + nact + 1] = work[iwuv + nact + 1] + t1; + // GOTO 700 + return 700; + } + } else { + sum = 0; + for (i = 1; i <= n; i = i + 1) { + sum = sum + work[iwzv + i] * amat[i][nvl]; + } + tt = -work[iwsv + nvl] / sum; + t2min = true; + if (!t1inf) { + if (t1 < tt) { + tt = t1; + t2min = false; + } + } + + for (i = 1; i <= n; i = i + 1) { + sol[i] = sol[i] + tt * work[iwzv + i]; + if (Math.abs(sol[i]) < vsmall) { + sol[i] = 0; + } + } + + crval[1] = crval[1] + tt * sum * (tt / 2 + work[iwuv + nact + 1]); + for (i = 1; i <= nact; i = i + 1) { + work[iwuv + i] = work[iwuv + i] - tt * work[iwrv + i]; + } + work[iwuv + nact + 1] = work[iwuv + nact + 1] + tt; + + if (t2min) { + nact = nact + 1; + iact[nact] = nvl; + + l = iwrm + ((nact - 1) * nact) / 2 + 1; + for (i = 1; i <= nact - 1; i = i + 1) { + work[l] = work[i]; + l = l + 1; + } + + if (nact === n) { + work[l] = work[n]; + } else { + for (i = n; i >= nact + 1; i = i - 1) { + if (work[i] === 0) { + // continue; + break; + } + gc = Math.max(Math.abs(work[i - 1]), Math.abs(work[i])); + gs = Math.min(Math.abs(work[i - 1]), Math.abs(work[i])); + if (work[i - 1] >= 0) { + temp = Math.abs(gc * Math.sqrt(1 + gs * gs / (gc * gc))); + } else { + temp = -Math.abs(gc * Math.sqrt(1 + gs * gs / (gc * gc))); + } + gc = work[i - 1] / temp; + gs = work[i] / temp; + + if (gc === 1) { + // continue; + break; + } + if (gc === 0) { + work[i - 1] = gs * temp; + for (j = 1; j <= n; j = j + 1) { + temp = dmat[j][i - 1]; + dmat[j][i - 1] = dmat[j][i]; + dmat[j][i] = temp; + } + } else { + work[i - 1] = temp; + nu = gs / (1 + gc); + for (j = 1; j <= n; j = j + 1) { + temp = gc * dmat[j][i - 1] + gs * dmat[j][i]; + dmat[j][i] = nu * (dmat[j][i - 1] + temp) - dmat[j][i]; + dmat[j][i - 1] = temp; + + } + } + } + work[l] = work[nact]; + } + } else { + sum = -bvec[nvl]; + for (j = 1; j <= n; j = j + 1) { + sum = sum + sol[j] * amat[j][nvl]; + } + if (nvl > meq) { + work[iwsv + nvl] = sum; + } else { + work[iwsv + nvl] = -Math.abs(sum); + if (sum > 0) { + for (j = 1; j <= n; j = j + 1) { + amat[j][nvl] = -amat[j][nvl]; + } + bvec[nvl] = -bvec[nvl]; + } + } + // GOTO 700 + return 700; + } + } + + return 0; + } + + function fn_goto_797() { + l = iwrm + (it1 * (it1 + 1)) / 2 + 1; + l1 = l + it1; + if (work[l1] === 0) { + // GOTO 798 + return 798; + } + gc = Math.max(Math.abs(work[l1 - 1]), Math.abs(work[l1])); + gs = Math.min(Math.abs(work[l1 - 1]), Math.abs(work[l1])); + if (work[l1 - 1] >= 0) { + temp = Math.abs(gc * Math.sqrt(1 + gs * gs / (gc * gc))); + } else { + temp = -Math.abs(gc * Math.sqrt(1 + gs * gs / (gc * gc))); + } + gc = work[l1 - 1] / temp; + gs = work[l1] / temp; + + if (gc === 1) { + // GOTO 798 + return 798; + } + if (gc === 0) { + for (i = it1 + 1; i <= nact; i = i + 1) { + temp = work[l1 - 1]; + work[l1 - 1] = work[l1]; + work[l1] = temp; + l1 = l1 + i; + } + for (i = 1; i <= n; i = i + 1) { + temp = dmat[i][it1]; + dmat[i][it1] = dmat[i][it1 + 1]; + dmat[i][it1 + 1] = temp; + } + } else { + nu = gs / (1 + gc); + for (i = it1 + 1; i <= nact; i = i + 1) { + temp = gc * work[l1 - 1] + gs * work[l1]; + work[l1] = nu * (work[l1 - 1] + temp) - work[l1]; + work[l1 - 1] = temp; + l1 = l1 + i; + } + for (i = 1; i <= n; i = i + 1) { + temp = gc * dmat[i][it1] + gs * dmat[i][it1 + 1]; + dmat[i][it1 + 1] = nu * (dmat[i][it1] + temp) - dmat[i][it1 + 1]; + dmat[i][it1] = temp; + } + } + + return 0; + } + + function fn_goto_798() { + l1 = l - it1; + for (i = 1; i <= it1; i = i + 1) { + work[l1] = work[l]; + l = l + 1; + l1 = l1 + 1; + } + + work[iwuv + it1] = work[iwuv + it1 + 1]; + iact[it1] = iact[it1 + 1]; + it1 = it1 + 1; + if (it1 < nact) { + // GOTO 797 + return 797; + } + + return 0; + } + + function fn_goto_799() { + work[iwuv + nact] = work[iwuv + nact + 1]; + work[iwuv + nact + 1] = 0; + iact[nact] = 0; + nact = nact - 1; + iter[2] = iter[2] + 1; + + return 0; + } + + go = 0; + while (true) { + go = fn_goto_50(); + if (go === 999) { + return; + } + while (true) { + go = fn_goto_55(); + if (go === 0) { + break; + } + if (go === 999) { + return; + } + if (go === 700) { + if (it1 === nact) { + fn_goto_799(); + } else { + while (true) { + fn_goto_797(); + go = fn_goto_798(); + if (go !== 797) { + break; + } + } + fn_goto_799(); + } + } + } + } + +} + +function solveQP(Dmat, dvec, Amat, bvec, meq, factorized) { + Dmat = base0to1(Dmat); + dvec = base0to1(dvec); + Amat = base0to1(Amat); + var i, n, q, + nact, r, + crval = [], iact = [], sol = [], work = [], iter = [], + message; + + meq = meq || 0; + factorized = factorized ? base0to1(factorized) : [undefined, 0]; + bvec = bvec ? base0to1(bvec) : []; + + // In Fortran the array index starts from 1 + n = Dmat.length - 1; + q = Amat[1].length - 1; + + if (!bvec) { + for (i = 1; i <= q; i = i + 1) { + bvec[i] = 0; + } + } + for (i = 1; i <= q; i = i + 1) { + iact[i] = 0; + } + nact = 0; + r = Math.min(n, q); + for (i = 1; i <= n; i = i + 1) { + sol[i] = 0; + } + crval[1] = 0; + for (i = 1; i <= (2 * n + (r * (r + 5)) / 2 + 2 * q + 1); i = i + 1) { + work[i] = 0; + } + for (i = 1; i <= 2; i = i + 1) { + iter[i] = 0; + } + + qpgen2(Dmat, dvec, n, n, sol, crval, Amat, + bvec, n, q, meq, iact, nact, iter, work, factorized); + + message = ""; + if (factorized[1] === 1) { + message = "constraints are inconsistent, no solution!"; + } + if (factorized[1] === 2) { + message = "matrix D in quadratic function is not positive definite!"; + } + + return { + solution: base1to0(sol), + value: base1to0(crval), + unconstrained_solution: base1to0(dvec), + iterations: base1to0(iter), + iact: base1to0(iact), + message: message + }; +} + +numeric.solveQP = solveQP; +/* +Shanti Rao sent me this routine by private email. I had to modify it +slightly to work on Arrays instead of using a Matrix object. +It is apparently translated from http://stitchpanorama.sourceforge.net/Python/svd.py +*/ + +numeric.svd= function svd(A) { + var temp; +//Compute the thin SVD from G. H. Golub and C. Reinsch, Numer. Math. 14, 403-420 (1970) + var prec= numeric.epsilon; //Math.pow(2,-52) // assumes double prec + var tolerance= 1.e-64/prec; + var itmax= 50; + var c=0; + var i=0; + var j=0; + var k=0; + var l=0; + + var u= numeric.clone(A); + var m= u.length; + + var n= u[0].length; + + if (m < n) throw "Need more rows than columns"; + + var e = new Array(n); + var q = new Array(n); + for (i=0; i b) + return a*Math.sqrt(1.0+(b*b/a/a)); + else if (b == 0.0) + return a; + return b*Math.sqrt(1.0+(a*a/b/b)); + } + + //Householder's reduction to bidiagonal form + + var f= 0.0; + var g= 0.0; + var h= 0.0; + var x= 0.0; + var y= 0.0; + var z= 0.0; + var s= 0.0; + + for (i=0; i < n; i++) + { + e[i]= g; + s= 0.0; + l= i+1; + for (j=i; j < m; j++) + s += (u[j][i]*u[j][i]); + if (s <= tolerance) + g= 0.0; + else + { + f= u[i][i]; + g= Math.sqrt(s); + if (f >= 0.0) g= -g; + h= f*g-s; + u[i][i]=f-g; + for (j=l; j < n; j++) + { + s= 0.0; + for (k=i; k < m; k++) + s += u[k][i]*u[k][j]; + f= s/h; + for (k=i; k < m; k++) + u[k][j]+=f*u[k][i]; + } + } + q[i]= g; + s= 0.0; + for (j=l; j < n; j++) + s= s + u[i][j]*u[i][j]; + if (s <= tolerance) + g= 0.0; + else + { + f= u[i][i+1]; + g= Math.sqrt(s); + if (f >= 0.0) g= -g; + h= f*g - s; + u[i][i+1] = f-g; + for (j=l; j < n; j++) e[j]= u[i][j]/h; + for (j=l; j < m; j++) + { + s=0.0; + for (k=l; k < n; k++) + s += (u[j][k]*u[i][k]); + for (k=l; k < n; k++) + u[j][k]+=s*e[k]; + } + } + y= Math.abs(q[i])+Math.abs(e[i]); + if (y>x) + x=y; + } + + // accumulation of right hand gtransformations + for (i=n-1; i != -1; i+= -1) + { + if (g != 0.0) + { + h= g*u[i][i+1]; + for (j=l; j < n; j++) + v[j][i]=u[i][j]/h; + for (j=l; j < n; j++) + { + s=0.0; + for (k=l; k < n; k++) + s += u[i][k]*v[k][j]; + for (k=l; k < n; k++) + v[k][j]+=(s*v[k][i]); + } + } + for (j=l; j < n; j++) + { + v[i][j] = 0; + v[j][i] = 0; + } + v[i][i] = 1; + g= e[i]; + l= i; + } + + // accumulation of left hand transformations + for (i=n-1; i != -1; i+= -1) + { + l= i+1; + g= q[i]; + for (j=l; j < n; j++) + u[i][j] = 0; + if (g != 0.0) + { + h= u[i][i]*g; + for (j=l; j < n; j++) + { + s=0.0; + for (k=l; k < m; k++) s += u[k][i]*u[k][j]; + f= s/h; + for (k=i; k < m; k++) u[k][j]+=f*u[k][i]; + } + for (j=i; j < m; j++) u[j][i] = u[j][i]/g; + } + else + for (j=i; j < m; j++) u[j][i] = 0; + u[i][i] += 1; + } + + // diagonalization of the bidiagonal form + prec= prec*x; + for (k=n-1; k != -1; k+= -1) + { + for (var iteration=0; iteration < itmax; iteration++) + { // test f splitting + var test_convergence = false; + for (l=k; l != -1; l+= -1) + { + if (Math.abs(e[l]) <= prec) + { test_convergence= true; + break; + } + if (Math.abs(q[l-1]) <= prec) + break; + } + if (!test_convergence) + { // cancellation of e[l] if l>0 + c= 0.0; + s= 1.0; + var l1= l-1; + for (i =l; i= itmax-1) + throw 'Error: no convergence.'; + // shift from bottom 2x2 minor + x= q[l]; + y= q[k-1]; + g= e[k-1]; + h= e[k]; + f= ((y-z)*(y+z)+(g-h)*(g+h))/(2.0*h*y); + g= pythag(f,1.0); + if (f < 0.0) + f= ((x-z)*(x+z)+h*(y/(f-g)-h))/x; + else + f= ((x-z)*(x+z)+h*(y/(f+g)-h))/x; + // next QR transformation + c= 1.0; + s= 1.0; + for (i=l+1; i< k+1; i++) + { + g= e[i]; + y= q[i]; + h= s*g; + g= c*g; + z= pythag(f,h); + e[i-1]= z; + c= f/z; + s= h/z; + f= x*c+g*s; + g= -x*s+g*c; + h= y*s; + y= y*c; + for (j=0; j < n; j++) + { + x= v[j][i-1]; + z= v[j][i]; + v[j][i-1] = x*c+z*s; + v[j][i] = -x*s+z*c; + } + z= pythag(f,h); + q[i-1]= z; + c= f/z; + s= h/z; + f= c*g+s*y; + x= -s*g+c*y; + for (j=0; j < m; j++) + { + y= u[j][i-1]; + z= u[j][i]; + u[j][i-1] = y*c+z*s; + u[j][i] = -y*s+z*c; + } + } + e[l]= 0.0; + e[k]= f; + q[k]= x; + } + } + + //vt= transpose(v) + //return (u,q,vt) + for (i=0;i= 0; j--) + { + if (q[j] < q[i]) + { + // writeln(i,'-',j) + c = q[j]; + q[j] = q[i]; + q[i] = c; + for(k=0;k phi0 && t > epsilon) { + var theta = phi1 / phi0; + var u = (Math.sqrt(1.0 + 6.0 * theta) - 1.0) / (3.0 * theta); + t *= u; + } + else { + this.copyVariables(x, x_new); + break; + } + } + } + + // add -dx to x to get the new variables + // + this.getNewVariableValue = function (x, dx, t) { + var x_new = new Array(x.length); + var i = 0; + for (i = 0; i < x.length; i++) { + x_new[i] = x[i] - t*dx[i]; + } + + return x_new; + } + + // copy x_new to x + // + this.copyVariables = function (x, x_new) { + var i = 0; + for (i = 0; i < x.length; i++) { + x[i] = x_new[i] + } + } + + // evaluate the function value's residual + // + this.evaluate_residual = function (funcsVal) { + var i; + var residual = 0; + for (i = 0; i < funcsVal.length; i++) { + residual += Math.abs(funcsVal[i]); + } + return residual; + } + + // evaluate the Euclidean_norm_of_residual + // + this.evaluate_Euclidean_norm_of_residual = function (funcsVal) { + var i; + var residual2 = 0; + for (i = 0; i < funcsVal.length; i++) { + var fabs = Math.abs(funcsVal[i]); + residual2 += fabs*fabs; + } + return Math.sqrt(residual2); + } + + // main function start here + // + var residual_tol = 1e-7; + var max_iteration = 1000; + var epsilon = 2.22e-16; + var JS_GSL_SUCCESS = 0; + var JS_GSL_CONTINUE = 1; + + // evaluate none linear system of equations and its jacobian matrix + // + var funcs = F(x); + var jacobian = A(x); + + // iterate to get the solution + // + var iter = 0; + var status; + do { + iter++; + + this.newton_iterate(F, A, x); + + if (this.evaluate_residual(F(x)) < residual_tol) + status = JS_GSL_SUCCESS; + else + status = JS_GSL_CONTINUE; + + } while (status == JS_GSL_CONTINUE && iter < max_iteration) + +} + +/* unit test + +Rosenbrock Function + + double y0 = 1 - x0; + double y1 = 10 * (x1 - x0 * x0); + + x0 = -1.2 + x1 = 1.0 + +*/ + + +/** + * Searches the interval from lowerLimit to upperLimit + * for a root (i.e., zero) of the function func with respect to + * its first argument using Brent's method root-finding algorithm. + * + * @param {function} function for which the root is sought. + * @param {number} the lower point of the interval to be searched. + * @param {number} the upper point of the interval to be searched. + * @param {number} the desired accuracy (convergence tolerance). + * @param {number} the maximum number of iterations. + * @returns an estimate for the root within accuracy. + */ +// Translated from zeroin.c in http://www.netlib.org/c/brent.shar. +numeric.uniroot = function uniroot(func, lowerLimit, upperLimit, errorTol, maxIter) { + var a = lowerLimit + , b = upperLimit + , c = a + , fa = func(a) + , fb = func(b) + , fc = fa + , s = 0 + , fs = 0 + , tol_act // Actual tolerance + , new_step // Step at this iteration + , prev_step // Distance from the last but one to the last approximation + , p // Interpolation step is calculated in the form p/q; division is delayed until the last moment + , q + ; + + errorTol = errorTol || 0; + maxIter = maxIter || 1000; + + while ( maxIter-- > 0 ) { + + prev_step = b - a; + + if ( Math.abs(fc) < Math.abs(fb) ) { + // Swap data for b to be the best approximation + a = b, b = c, c = a; + fa = fb, fb = fc, fc = fa; + } + + tol_act = 1e-15 * Math.abs(b) + errorTol / 2; + new_step = ( c - b ) / 2; + + if ( Math.abs(new_step) <= tol_act || fb === 0 ) { + return b; // Acceptable approx. is found + } + + // Decide if the interpolation can be tried + if ( Math.abs(prev_step) >= tol_act && Math.abs(fa) > Math.abs(fb) ) { + // If prev_step was large enough and was in true direction, Interpolatiom may be tried + var t1, cb, t2; + cb = c - b; + if ( a === c ) { // If we have only two distinct points linear interpolation can only be applied + t1 = fb / fa; + p = cb * t1; + q = 1.0 - t1; + } + else { // Quadric inverse interpolation + q = fa / fc, t1 = fb / fc, t2 = fb / fa; + p = t2 * (cb * q * (q - t1) - (b - a) * (t1 - 1)); + q = (q - 1) * (t1 - 1) * (t2 - 1); + } + + if ( p > 0 ) { + q = -q; // p was calculated with the opposite sign; make p positive + } + else { + p = -p; // and assign possible minus to q + } + + if ( p < ( 0.75 * cb * q - Math.abs( tol_act * q ) / 2 ) && + p < Math.abs( prev_step * q / 2 ) ) { + // If (b + p / q) falls in [b,c] and isn't too large it is accepted + new_step = p / q; + } + + // If p/q is too large then the bissection procedure can reduce [b,c] range to more extent + } + + if ( Math.abs( new_step ) < tol_act ) { // Adjust the step to be not less than tolerance + new_step = ( new_step > 0 ) ? tol_act : -tol_act; + } + + a = b, fa = fb; // Save the previous approx. + b += new_step, fb = func(b); // Do step to a new approxim. + + if ( (fb > 0 && fc > 0) || (fb < 0 && fc < 0) ) { + c = a, fc = fa; // Adjust c for it to have a sign opposite to that of b + } + } + +}; + + +/* +var test_counter; +function f1 (x) { test_counter++; return (Math.pow(x,2)-1)*x - 5; } +function f2 (x) { test_counter++; return Math.cos(x)-x; } +function f3 (x) { test_counter++; return Math.sin(x)-x; } +function f4 (x) { test_counter++; return (x + 3) * Math.pow(x - 1, 2); } +[ + [f1, 2, 3], + [f2, 2, 3], + [f2, -1, 3], + [f3, -1, 3], + [f4, -4, 4/3] +].forEach(function (args) { + test_counter = 0; + var root = uniroot.apply( pv, args ); + ;;;console.log( 'uniroot:', args.slice(1), root, test_counter ); +}) +*/ +numeric.Sparse = function Sparse(p,v) { this.p = p; this.v = v; }; + +numeric.Sparse.scatter = function scatter(i,j,z) { + var n = numeric.sup(j)+1,m=i.length,jk; + var p = Array(n),v = Array(n),k; + for(k=n-1;k!==-1;--k) { p[k] = []; v[k] = []; } + for(k=0;k!==m;++k) { + jk = j[k]; + p[jk].push(i[k]); + v[jk].push(z[k]); + } + return new numeric.Sparse(p,v); +}; + +numeric.Sparse.identity = function identity(n) { + return numeric.Sparse.scatter(numeric.linspace(0,n-1),numeric.linspace(0,n-1),numeric.rep([n],1)); +}; + +numeric.Sparse.prototype.dim = function dim() { + var m = 0, i,j,p=this.p,k=p.length,pi,a,b; + for(i=k-1;i!==-1;--i) { + pi = p[i]; + a = pi.length; + for(j=a-1;j!==-1;--j) { + b = pi[j]; + if(b>m) m = b; + } + } + return [m+1,p.length]; +}; + +numeric.Sparse.prototype.Lsolve = function Lsolve(b,n) { + if(typeof n === "undefined") { n = b.length; } + var i,j,k,ret = Array(n), p = this.p, v = this.v, pj,vj,m; + for(i=0;ij && i=j) t[i-j] = vj[k]; + } + if(j!==0) { + for(k=n-1;k!==-1;--k) foo[k] = 0; + for(k=0;k3;i-=4) { f(); f(); f(); f(); } + while(i>0) { f(); i--; } + t2 = new Date(); + if(t2-t1 > interval) break; + } + for(i=n;i>3;i-=4) { f(); f(); f(); f(); } + while(i>0) { f(); i--; } + t2 = new Date(); + return 1000*(3*n-1)/(t2-t1); +}; + +numeric._myIndexOf = (function _myIndexOf(w) { + var n = this.length,k; + for(k=0;k numeric.largeArray) { ret.push('...Large Array...'); return true; } + var flag = false; + ret.push('['); + for(k=0;k0) { ret.push(','); if(flag) ret.push('\n '); } flag = foo(x[k]); } + ret.push(']'); + return true; + } + ret.push('{'); + var flag = false; + for(k in x) { if(x.hasOwnProperty(k)) { if(flag) ret.push(',\n'); flag = true; ret.push(k); ret.push(': \n'); foo(x[k]); } } + ret.push('}'); + return true; + } + foo(x); + return ret.join(''); +}; + +numeric.parseDate = function parseDate(d) { + function foo(d) { + if(typeof d === 'string') { return Date.parse(d.replace(/-/g,'/')); } + if(!(d instanceof Array)) { throw new Error("parseDate: parameter must be arrays of strings"); } + var ret = [],k; + for(k=0;k0) { + ret[count] = []; + for(j=0;j> 2; + q = ((x & 3) << 4) + (y >> 4); + r = ((y & 15) << 2) + (z >> 6); + s = z & 63; + if(i+1>=n) { r = s = 64; } + else if(i+2>=n) { s = 64; } + ret += key.charAt(p) + key.charAt(q) + key.charAt(r) + key.charAt(s); + } + return ret; + } + function crc32Array (a,from,to) { + if(typeof from === "undefined") { from = 0; } + if(typeof to === "undefined") { to = a.length; } + var table = [0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, + 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, + 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, + 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, + 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, + 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, + 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, + 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, + 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, + 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, + 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, + 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, + 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, + 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, + 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, + 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, + 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, + 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, + 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, + 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, + 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, + 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D]; + + var crc = -1, y = 0, n = a.length,i; + + for (i = from; i < to; i++) { + y = (crc ^ a[i]) & 0xFF; + crc = (crc >>> 8) ^ table[y]; + } + + return crc ^ (-1); + } + + var h = img[0].length, w = img[0][0].length, s1, s2, next,k,length,a,b,i,j,adler32,crc32; + var stream = [ + 137, 80, 78, 71, 13, 10, 26, 10, // 0: PNG signature + 0,0,0,13, // 8: IHDR Chunk length + 73, 72, 68, 82, // 12: "IHDR" + (w >> 24) & 255, (w >> 16) & 255, (w >> 8) & 255, w&255, // 16: Width + (h >> 24) & 255, (h >> 16) & 255, (h >> 8) & 255, h&255, // 20: Height + 8, // 24: bit depth + 2, // 25: RGB + 0, // 26: deflate + 0, // 27: no filter + 0, // 28: no interlace + -1,-2,-3,-4, // 29: CRC + -5,-6,-7,-8, // 33: IDAT Chunk length + 73, 68, 65, 84, // 37: "IDAT" + // RFC 1950 header starts here + 8, // 41: RFC1950 CMF + 29 // 42: RFC1950 FLG + ]; + crc32 = crc32Array(stream,12,29); + stream[29] = (crc32>>24)&255; + stream[30] = (crc32>>16)&255; + stream[31] = (crc32>>8)&255; + stream[32] = (crc32)&255; + s1 = 1; + s2 = 0; + for(i=0;i>8)&255; + stream.push(a); stream.push(b); + stream.push((~a)&255); stream.push((~b)&255); + if(i===0) stream.push(0); + for(j=0;j255) a = 255; + else if(a<0) a=0; + else a = Math.round(a); + s1 = (s1 + a )%65521; + s2 = (s2 + s1)%65521; + stream.push(a); + } + } + stream.push(0); + } + adler32 = (s2<<16)+s1; + stream.push((adler32>>24)&255); + stream.push((adler32>>16)&255); + stream.push((adler32>>8)&255); + stream.push((adler32)&255); + length = stream.length - 41; + stream[33] = (length>>24)&255; + stream[34] = (length>>16)&255; + stream[35] = (length>>8)&255; + stream[36] = (length)&255; + crc32 = crc32Array(stream,37); + stream.push((crc32>>24)&255); + stream.push((crc32>>16)&255); + stream.push((crc32>>8)&255); + stream.push((crc32)&255); + stream.push(0); + stream.push(0); + stream.push(0); + stream.push(0); +// a = stream.length; + stream.push(73); // I + stream.push(69); // E + stream.push(78); // N + stream.push(68); // D + stream.push(174); // CRC1 + stream.push(66); // CRC2 + stream.push(96); // CRC3 + stream.push(130); // CRC4 + return 'data:image/png;base64,'+base64(stream); +}; + +// 2. Linear algebra with Arrays. +numeric._dim = function _dim(x) { + var ret = []; + while(typeof x === "object") { ret.push(x.length); x = x[0]; } + return ret; +}; + +numeric.dim = function dim(x) { + var y,z; + if(typeof x === "object") { + y = x[0]; + if(typeof y === "object") { + z = y[0]; + if(typeof z === "object") { + return numeric._dim(x); + } + return [x.length,y.length]; + } + return [x.length]; + } + return []; +}; + +// mapreduce +numeric.mapreduce = function mapreduce(body, init) { + return numeric.compile('x','accum','_s','_k', + 'if(typeof accum === "undefined") accum = '+init+';\n'+ + 'if(typeof x === "number") { var xi = x; '+body+'; return accum; }\n'+ + 'if(typeof _s === "undefined") _s = numeric.dim(x);\n'+ + 'if(typeof _k === "undefined") _k = 0;\n'+ + 'var _n = _s[_k];\n'+ + 'var i,xi;\n'+ + 'if(_k < _s.length-1) {\n'+ + ' for(i=_n-1;i>=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.mapreduce2 = function mapreduce2(body, setup) { + return numeric.compile('x', + 'var n = x.length;\n'+ + 'var i,xi;\n'+setup+'\n'+ + 'for(i=n-1;i!==-1;--i) { \n'+ + ' xi = x[i];\n'+ + ' '+body+'\n'+ + '}\n'+ + 'return accum;' + ); +}; + +// compare arrays/tensors +numeric.same = function same(x,y) { + var i, n; + + if(!(x instanceof Array) || !(y instanceof Array)) { return false; } + + n = x.length; + + if(n !== y.length) { return false; } + + for(i = 0; i < n; i++) + { + if(x[i] === y[i]) { continue; } + if(typeof x[i] === "object") { if(!same(x[i], y[i])) return false; } + else { return false; } + } + 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; +}; + +// repeat +numeric.rep = function rep(s, v, k) +{ + // repeat value v over a tensor of size s = [s0, s1, s2, ...] + // k recursive index + 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; + } + + for(i = n - 1; i >= 0; i--) { ret[i] = numeric.rep(s, v, k+1); } + + return ret; +}; + +numeric.zeros = function zeros(s) { return numeric.rep(s,0); }; +numeric.ones = function ones(s) { return numeric.rep(s,1); }; + +// dot functions +numeric.dotMMsmall = function dotMMsmall(x,y) +{ + var i,j,k,p,q,r,ret,foo,bar,woo,i0,k0,p0,r0; + p = x.length; q = y.length; r = y[0].length; + ret = Array(p); + for(i=p-1;i>=0;i--) { + foo = Array(r); + bar = x[i]; + for(k=r-1;k>=0;k--) { + woo = bar[q-1]*y[q-1][k]; + for(j=q-2;j>=1;j-=2) { + i0 = j-1; + woo += bar[j]*y[j][k] + bar[i0]*y[i0][k]; + } + if(j===0) { woo += bar[0]*y[0][k]; } + foo[k] = woo; + } + ret[i] = foo; + } + return ret; +}; + +numeric._getCol = function _getCol(A,j,x) { + var n = A.length, i; + for(i=n-1;i>0;--i) { + x[i] = A[i][j]; + --i; + x[i] = A[i][j]; + } + 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; + var VV = numeric.dotVV; + var i,j,k,z; + --p; + --m; + for(i=m;i!==-1;--i) A[i] = Array(n); + --n; + for(i=n;i!==-1;--i) { + gc(y,i,v); + for(j=m;j!==-1;--j) { + z=0; + xj = x[j]; + A[j][i] = VV(xj,v); + } + } + return A; +}; + +numeric.dotMV = function dotMV(x,y) { + var p = x.length, q = y.length,i; + var ret = Array(p), dotVV = numeric.dotVV; + for(i=p-1;i>=0;i--) { ret[i] = dotVV(x[i],y); } + return ret; +}; + +numeric.dotVM = function dotVM(x,y) { + var i,j,k,p,q,r,ret,foo,bar,woo,i0,k0,p0,r0,s1,s2,s3,baz,accum; + p = x.length; q = y[0].length; + ret = Array(q); + for(k=q-1;k>=0;k--) { + woo = x[p-1]*y[p-1][k]; + for(j=p-2;j>=1;j-=2) { + i0 = j-1; + woo += x[j]*y[j][k] + x[i0]*y[i0][k]; + } + if(j===0) { woo += x[0]*y[0][k]; } + ret[k] = woo; + } + return ret; +}; + +numeric.dotVV = function dotVV(x,y) { + var i,n=x.length,i1,ret = x[n-1]*y[n-1]; + for(i=n-2;i>=1;i-=2) { + i1 = i-1; + ret += x[i]*y[i] + x[i1]*y[i1]; + } + if(i===0) { ret += x[0]*y[0]; } + return ret; +}; + +numeric.dot = function dot(x,y) { + var d = numeric.dim; + switch(d(x).length*1000+d(y).length) { + case 2002: + if(y.length < 10) return numeric.dotMMsmall(x,y); + else return numeric.dotMMbig(x,y); + case 2001: return numeric.dotMV(x,y); + case 1002: return numeric.dotVM(x,y); + case 1001: return numeric.dotVV(x,y); + case 1000: return numeric.mulVS(x,y); + case 1: return numeric.mulSV(x,y); + case 0: return x*y; + default: throw new Error('numeric.dot only works on vectors and matrices'); + } +}; + +// diag function + +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--) { + Ai = Array(n); + i1 = i+2; + for(j=n-1;j>=i1;j-=2) { + Ai[j] = 0; + Ai[j-1] = 0; + } + if(j>i) { Ai[j] = 0; } + Ai[i] = d[i]; + for(j=i-1;j>=1;j-=2) { + Ai[j] = 0; + Ai[j-1] = 0; + } + if(j===0) { Ai[0] = 0; } + A[i] = Ai; + } + 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) { + ret[i] = A[i][i]; + --i; + ret[i] = A[i][i]; + } + if(i===0) { + ret[0] = A[0][0]; + } + return ret; +}; + +numeric.identity = function identity(n) { return numeric.diag(numeric.rep([n],1)); }; + +numeric.pointwise = function pointwise(params,body,setup) +{ + if(typeof setup === "undefined") { setup = ""; } + var fun = []; + var k; + var avec = /\[i\]$/,p,thevec = ''; + var haveret = false; + for(k=0;k=0;i--) ret[i] = arguments.callee('+params.join(',')+',_s,_k+1);\n'+ + ' return ret;\n'+ + '}\n'+ + setup+'\n'+ + 'for(i=_n-1;i!==-1;--i) {\n'+ + ' '+body+'\n'+ + '}\n'+ + 'return ret;' + ); + return numeric.compile.apply(null,fun); +}; + +numeric.pointwise2 = function pointwise2(params,body,setup) +{ + if(typeof setup === "undefined") { setup = ""; } + var fun = []; + var k; + var avec = /\[i\]$/,p,thevec = ''; + var haveret = false; + for(k=0;k=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.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']; + +numeric.ops1 = { + neg: '-', + not: '!', + bnot: '~', + 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;'] +}; + +(function () { + var i,o; + for(i=0;iv0) { i0 = i; v0 = k; } } + Aj = A[i0]; A[i0] = A[j]; A[j] = Aj; + Ij = I[i0]; I[i0] = I[j]; I[j] = Ij; + x = Aj[j]; + for(k=j;k!==n;++k) Aj[k] /= x; + for(k=n-1;k!==-1;--k) Ij[k] /= x; + for(i=m-1;i!==-1;--i) { + if(i!==j) { + Ai = A[i]; + Ii = I[i]; + x = Ai[j]; + for(k=j+1;k!==n;++k) Ai[k] -= Aj[k]*x; + for(k=n-1;k>0;--k) { Ii[k] -= Ij[k]*x; --k; Ii[k] -= Ij[k]*x; } + if(k===0) Ii[0] -= Ij[0]*x; + } + } + } + return I; +}; + +numeric.det = function det(x) { + var s = numeric.dim(x); + if(s.length !== 2 || s[0] !== s[1]) { throw new Error('numeric: det() only works on square matrices'); } + var n = s[0], ret = 1,i,j,k,A = numeric.clone(x),Aj,Ai,alpha,temp,k1,k2,k3; + for(j=0;j Math.abs(A[k][j])) { k = i; } } + if(k !== j) { + temp = A[k]; A[k] = A[j]; A[j] = temp; + ret *= -1; + } + Aj = A[j]; + for(i=j+1;i=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]; + --j; + Bj = ret[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]; + } + } + if(i===0) { + A0 = x[0]; + for(j=n-1;j>=1;--j) { + ret[j][0] = A0[j]; + --j; + ret[j][0] = A0[j]; + } + if(j===0) { ret[0][0] = A0[0]; } + } + return ret; +}; + +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]; + --j; + Bj = ret[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]; + } + } + if(i===0) { + A0 = x[0]; + for(j=n-1;j>=1;--j) { + ret[j][0] = -A0[j]; + --j; + ret[j][0] = -A0[j]; + } + if(j===0) { ret[0][0] = -A0[0]; } + } + return ret; +}; + +numeric._random = function _random(s,k) { + var i,n=s[k],ret=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(); + } + if(i===0) { ret[0] = rnd(); } + return ret; + } + for(i=n-1;i>=0;i--) ret[i] = _random(s,k+1); + return ret; +}; + +numeric.random = function random(s) { return numeric._random(s,0); }; + +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); + n--; + for(i=n;i>=0;i--) { ret[i] = (i*b+(n-i)*a)/n; } + return ret; +}; + +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--) { ret[i] = foo(x[i+a],k+1); } + return ret; + } + return foo(x,0); +}; + +numeric.setBlock = function setBlock(x,from,to,B) { + var s = numeric.dim(x); + function foo(x,y,k) { + var i,a = from[k], n = to[k]-a; + if(k === s.length-1) { for(i=n;i>=0;i--) { x[i+a] = y[i]; } } + for(i=n;i>=0;i--) { foo(x[i+a],y[i],k+1); } + } + foo(x,B,0); + return x; +}; + +numeric.getRange = function getRange(A, I,J ) { + var m = I.length, n = J.length; + var i,j; + var B = Array(m), Bi, AI; + for(i=m-1;i!==-1;--i) { + B[i] = Array(n); + Bi = B[i]; + AI = A[I[i]]; + for(j=n-1;j!==-1;--j) Bi[j] = AI[J[j]]; + } + return B; +}; + +numeric.blockMatrix = function blockMatrix(X) { + var s = numeric.dim(X); + if(s.length<4) return numeric.blockMatrix([X]); + var m=s[0],n=s[1],M,N,i,j,Xij; + M = 0; N = 0; + for(i=0;i=0;i--) { + Ai = Array(n); + xi = x[i]; + for(j=n-1;j>=3;--j) { + Ai[j] = xi * y[j]; + --j; + Ai[j] = xi * y[j]; + --j; + Ai[j] = xi * y[j]; + --j; + Ai[j] = xi * y[j]; + } + while(j>=0) { Ai[j] = xi * y[j]; --j; } + A[i] = Ai; + } + return A; +}; + +// 3. The Tensor type T +numeric.T = function T(x,y) { this.x = x; this.y = y; }; +numeric.t = function t(x,y) { return new numeric.T(x,y); }; + +numeric.Tbinop = function Tbinop(rr,rc,cr,cc,setup) { + var io = numeric.indexOf; + if(typeof setup !== "string") { + var k; + setup = ''; + for(k in numeric) { + if(numeric.hasOwnProperty(k) && (rr.indexOf(k)>=0 || rc.indexOf(k)>=0 || cr.indexOf(k)>=0 || cc.indexOf(k)>=0) && k.length>1) { + setup += 'var '+k+' = numeric.'+k+';\n'; + } + } + } + return numeric.compile(['y'], + 'var x = this;\n'+ + 'if(!(y instanceof numeric.T)) { y = new numeric.T(y); }\n'+ + setup+'\n'+ + 'if(x.y) {'+ + ' if(y.y) {'+ + ' return new numeric.T('+cc+');\n'+ + ' }\n'+ + ' return new numeric.T('+cr+');\n'+ + '}\n'+ + 'if(y.y) {\n'+ + ' return new numeric.T('+rc+');\n'+ + '}\n'+ + 'return new numeric.T('+rr+');\n' + ); +}; + +numeric.T.prototype.add = numeric.Tbinop( + 'add(x.x,y.x)', + 'add(x.x,y.x),y.y', + 'add(x.x,y.x),x.y', + 'add(x.x,y.x),add(x.y,y.y)'); +numeric.T.prototype.sub = numeric.Tbinop( + 'sub(x.x,y.x)', + 'sub(x.x,y.x),neg(y.y)', + 'sub(x.x,y.x),x.y', + 'sub(x.x,y.x),sub(x.y,y.y)'); +numeric.T.prototype.mul = numeric.Tbinop( + 'mul(x.x,y.x)', + 'mul(x.x,y.x),mul(x.x,y.y)', + 'mul(x.x,y.x),mul(x.y,y.x)', + 'sub(mul(x.x,y.x),mul(x.y,y.y)),add(mul(x.x,y.y),mul(x.y,y.x))'); + +numeric.T.prototype.reciprocal = function reciprocal() { + var mul = numeric.mul, div = numeric.div; + if(this.y) { + 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 numeric.T(div(1,this.x), 0); +}; + +numeric.T.prototype.div = function div(y) { + if(!(y instanceof numeric.T)) y = new numeric.T(y); + if(y.y) { return this.mul(y.reciprocal()); } + var div = numeric.div; + if(this.y) { return new numeric.T(div(this.x,y.x),div(this.y,y.x)); } + return new numeric.T(div(this.x,y.x)); +}; + +numeric.T.prototype.dot = numeric.Tbinop( + 'dot(x.x,y.x)', + 'dot(x.x,y.x),dot(x.x,y.y)', + 'dot(x.x,y.x),dot(x.y,y.x)', + 'sub(dot(x.x,y.x),dot(x.y,y.y)),add(dot(x.x,y.y),dot(x.y,y.x))' + ); + +numeric.T.prototype.transpose = function transpose() { + var t = numeric.transpose, x = this.x, y = this.y; + if(y) { return new numeric.T(t(x),t(y)); } + return new numeric.T(t(x)); +}; + +numeric.T.prototype.transjugate = function transjugate() { + var t = numeric.transpose, x = this.x, y = this.y; + if(y) { return new numeric.T(t(x),numeric.negtranspose(y)); } + return new numeric.T(t(x)); +}; + +numeric.Tunop = function Tunop(r,c,s) { + if(typeof s !== "string") { s = ''; } + return numeric.compile( + 'var x = this;\n'+ + s+'\n'+ + 'if(x.y) {'+ + ' '+c+'\n'+ + '}\n'+ + r+'\n' + ); +}; + +numeric.T.prototype.exp = numeric.Tunop( + 'return new numeric.T(ex);', + 'return new numeric.T(mul(cos(x.y),ex),mul(sin(x.y),ex));', + 'var ex = numeric.exp(x.x), cos = numeric.cos, sin = numeric.sin, mul = numeric.mul;'); +numeric.T.prototype.conj = numeric.Tunop( + 'return new numeric.T(x.x);', + 'return new numeric.T(x.x,numeric.neg(x.y));'); +numeric.T.prototype.neg = numeric.Tunop( + 'return new numeric.T(neg(x.x));', + 'return new numeric.T(neg(x.x),neg(x.y));', + 'var neg = numeric.neg;'); +numeric.T.prototype.sin = numeric.Tunop( + 'return new numeric.T(numeric.sin(x.x));', + 'return x.exp().sub(x.neg().exp()).div(new numeric.T(0,2));'); +numeric.T.prototype.cos = numeric.Tunop( + 'return new numeric.T(numeric.cos(x.x));', + 'return x.exp().add(x.neg().exp()).div(2);'); +numeric.T.prototype.abs = numeric.Tunop( + 'return new numeric.T(numeric.abs(x.x));', + 'return new numeric.T(numeric.sqrt(numeric.add(mul(x.x,x.x),mul(x.y,x.y))));', + 'var mul = numeric.mul;'); +numeric.T.prototype.log = numeric.Tunop( + 'return new numeric.T(numeric.log(x.x));', + 'var theta = new numeric.T(numeric.atan2(x.y,x.x)), r = x.abs();\n'+ + 'return new numeric.T(numeric.log(r.x),theta.x);'); +numeric.T.prototype.norm2 = numeric.Tunop( + 'return numeric.norm2(x.x);', + 'var f = numeric.norm2Squared;\n'+ + 'return Math.sqrt(f(x.x)+f(x.y));'); + +numeric.T.prototype.inv = function inv() { + var A = this; + if(typeof A.y === "undefined") { return new numeric.T(numeric.inv(A.x)); } + var n = A.x.length, i, j, k; + var Rx = numeric.identity(n),Ry = numeric.rep([n,n],0); + var Ax = numeric.clone(A.x), Ay = numeric.clone(A.y); + var Aix, Aiy, Ajx, Ajy, Rix, Riy, Rjx, Rjy; + var i,j,k,d,d1,ax,ay,bx,by,temp; + for(i=0;i d) { k=j; d = d1; } + } + if(k!==i) { + temp = Ax[i]; Ax[i] = Ax[k]; Ax[k] = temp; + temp = Ay[i]; Ay[i] = Ay[k]; Ay[k] = temp; + temp = Rx[i]; Rx[i] = Rx[k]; Rx[k] = temp; + temp = Ry[i]; Ry[i] = Ry[k]; Ry[k] = temp; + } + Aix = Ax[i]; Aiy = Ay[i]; + Rix = Rx[i]; Riy = Ry[i]; + ax = Aix[i]; ay = Aiy[i]; + for(j=i+1;j0;i--) { + Rix = Rx[i]; Riy = Ry[i]; + for(j=i-1;j>=0;j--) { + Rjx = Rx[j]; Rjy = Ry[j]; + ax = Ax[j][i]; ay = Ay[j][i]; + for(k=n-1;k>=0;k--) { + bx = Rix[k]; by = Riy[k]; + Rjx[k] -= ax*bx - ay*by; + Rjy[k] -= ax*by + ay*bx; + } + } + } + return new numeric.T(Rx,Ry); +}; + +numeric.T.prototype.get = function get(i) { + var x = this.x, y = this.y, k = 0, ik, n = i.length; + if(y) { + while(k= 0 ? 1 : -1; + var alpha = s*numeric.norm2(x); + v[0] += alpha; + var foo = numeric.norm2(v); + if(foo === 0) { /* this should not happen */ throw new Error('eig: internal error'); } + return numeric.div(v,foo); +}; + +// upper hessenberg +numeric.toUpperHessenberg = function toUpperHessenberg(me) { + var s = numeric.dim(me); + if(s.length !== 2 || s[0] !== s[1]) { throw new Error('numeric: toUpperHessenberg() only works on square matrices'); } + var m = s[0], i,j,k,x,v,A = numeric.clone(me),B,C,Ai,Ci,Q = numeric.identity(m),Qi; + for(j=0;j0) { + v = numeric.house(x); + B = numeric.getBlock(A,[j+1,j],[m-1,m-1]); + C = numeric.tensor(v,numeric.dot(v,B)); + for(i=j+1;i=4*det) { + var s1,s2; + s1 = 0.5*(tr+Math.sqrt(tr*tr-4*det)); + s2 = 0.5*(tr-Math.sqrt(tr*tr-4*det)); + Hloc = numeric.add(numeric.sub(numeric.dot(Hloc,Hloc), + numeric.mul(Hloc,s1+s2)), + numeric.diag(numeric.rep([3],s1*s2))); + } else { + Hloc = numeric.add(numeric.sub(numeric.dot(Hloc,Hloc), + numeric.mul(Hloc,tr)), + numeric.diag(numeric.rep([3],det))); + } + x = [Hloc[0][0],Hloc[1][0],Hloc[2][0]]; + v = numeric.house(x); + B = [H[0],H[1],H[2]]; + C = numeric.tensor(v,numeric.dot(v,B)); + for(i=0;i<3;i++) { Hi = H[i]; Ci = C[i]; for(k=0;k 4 && termp == Math.abs(d[p]) && termq == Math.abs(d[q])) + { + // remove small elmts + A[p][q] = 0; + } + else + { + if (Math.abs(A[p][q]) >= tresh) + { + // apply rotation + h = d[q] - d[p]; + term = Math.abs(h) + gapq; + if (term == Math.abs(h)) + { + t = A[p][q]/h; + } + else + { + theta = 0.5 * h / A[p][q]; + t = 1/(Math.abs(theta) + Math.sqrt(1 + theta*theta)); + if (theta < 0) + { + t = -t; + } + } + c = 1/Math.sqrt(1 + t*t); + s = t * c; + tau = s/(1 + c); + h = t * A[p][q]; + zw[p] = zw[p] - h; + zw[q] = zw[q] + h; + d[p] = d[p] - h; + d[q] = d[q] + h; + A[p][q] = 0; + // rotate and use upper tria only + for (var j = 0; j < p; j++) + { + g = A[j][p]; + h = A[j][q]; + A[j][p] = g - s * (h + g * tau); + A[j][q] = h + s * (g - h * tau); + } + for (var j = p + 1; j < q; j++) + { + g = A[p][j]; + h = A[j][q]; + A[p][j] = g - s * (h + g * tau); + A[j][q] = h + s * (g - h * tau); + } + for (var j = q + 1; j < n; j++) + { + g = A[p][j]; + h = A[q][j]; + A[p][j] = g - s * (h + g * tau); + A[q][j] = h + s * (g - h * tau); + } + // eigenstates + for (var j = 0; j < n; j++) + { + g = v[j][p]; + h = v[j][q]; + v[j][p] = g - s * (h + g * tau); + v[j][q] = h + s * (g - h * tau); + } + nrot++; + } + } + } + } + bw = numeric.add(bw, zw); + d = numeric.clone(bw); + zw = numeric.rep([n], 0); + } + + return {E: {x: v}, lambda: {x: d}, iterations: iters, niter: niter, nrot: nrot}; +} + +numeric.jacobinorm = function(A) +{ + // used in numeric.jacobi + var n = A.length; + var s = 0; + for (var i = 0; i < n; i ++) + { + for (var j = i + 1; j < n; j ++) + { + s = s + Math.pow(A[i][j], 2) + } + } + return Math.sqrt(s); +} + +// eig function +numeric.eig = function eig(A,maxiter) { + var QH = numeric.toUpperHessenberg(A); + var QB = numeric.QRFrancis(QH.H,maxiter); + var T = numeric.T; + var n = A.length,i,k,flag = false,B = QB.B,H = numeric.dot(QB.Q,numeric.dot(QH.H,numeric.transpose(QB.Q))); + var Q = new T(numeric.dot(QB.Q,QH.Q)),Q0; + var m = B.length,j; + var a,b,c,d,p1,p2,disc,x,y,p,q,n1,n2; + var sqrt = Math.sqrt; + for(k=0;k=0) { + if(p1<0) x = -0.5*(p1-sqrt(disc)); + else x = -0.5*(p1+sqrt(disc)); + n1 = (a-x)*(a-x)+b*b; + n2 = c*c+(d-x)*(d-x); + if(n1>n2) { + n1 = sqrt(n1); + p = (a-x)/n1; + q = b/n1; + } else { + n2 = sqrt(n2); + p = c/n2; + q = (d-x)/n2; + } + Q0 = new T([[q,-p],[p,q]]); + Q.setRows(i,j,Q0.dot(Q.getRows(i,j))); + } else { + x = -0.5*p1; + y = 0.5*sqrt(-disc); + n1 = (a-x)*(a-x)+b*b; + n2 = c*c+(d-x)*(d-x); + if(n1>n2) { + n1 = sqrt(n1+y*y); + p = (a-x)/n1; + q = b/n1; + x = 0; + y /= n1; + } else { + n2 = sqrt(n2+y*y); + p = c/n2; + q = (d-x)/n2; + x = y/n2; + y = 0; + } + Q0 = new T([[q,-p],[p,q]],[[x,y],[y,-x]]); + Q.setRows(i,j,Q0.dot(Q.getRows(i,j))); + } + } + } + var R = Q.dot(A).dot(Q.transjugate()), n = A.length, E = numeric.T.identity(n); + for(j=0;j0) { + for(k=j-1;k>=0;k--) { + var Rk = R.get([k,k]), Rj = R.get([j,j]); + if(numeric.neq(Rk.x,Rj.x) || numeric.neq(Rk.y,Rj.y)) { + x = R.getRow(k).getBlock([k],[j-1]); + y = E.getRow(j).getBlock([k],[j-1]); + E.set([j,k],(R.get([k,j]).neg().sub(x.dot(y))).div(Rk.sub(Rj))); + } else { + E.setRow(j,E.getRow(k)); + continue; + } + } + } + } + for(j=0;j=counts.length) counts[counts.length] = 0; + if(foo[j]!==0) counts[j]++; + } + } + var n = counts.length; + var Ai = Array(n+1); + Ai[0] = 0; + for(i=0;i= k11) { + xj[n] = j[m]; + if(m===0) return; + ++n; + --m; + km = k[m]; + k11 = k1[m]; + } else { + foo = Pinv[Aj[km]]; + if(x[foo] === 0) { + x[foo] = 1; + k[m] = km; + ++m; + j[m] = foo; + km = Ai[foo]; + k1[m] = k11 = Ai[foo+1]; + } else ++km; + } + } +}; + +numeric.ccsLPSolve = function ccsLPSolve(A,B,x,xj,I,Pinv,dfs) { + var Ai = A[0], Aj = A[1], Av = A[2],m = Ai.length-1, n=0; + var Bi = B[0], Bj = B[1], Bv = B[2]; + + var i,i0,i1,j,J,j0,j1,k,l,l0,l1,a; + i0 = Bi[I]; + i1 = Bi[I+1]; + xj.length = 0; + for(i=i0;i a) { e = k; a = c; } + } + if(abs(x[i])= k11) { + xj[n] = Pinv[j[m]]; + if(m===0) return; + ++n; + --m; + km = k[m]; + k11 = k1[m]; + } else { + foo = Aj[km]; + if(x[foo] === 0) { + x[foo] = 1; + k[m] = km; + ++m; + j[m] = foo; + foo = Pinv[foo]; + km = Ai[foo]; + k1[m] = k11 = Ai[foo+1]; + } else ++km; + } + } +}; + +numeric.ccsLPSolve0 = function ccsLPSolve0(A,B,y,xj,I,Pinv,P,dfs) { + var Ai = A[0], Aj = A[1], Av = A[2],m = Ai.length-1, n=0; + var Bi = B[0], Bj = B[1], Bv = B[2]; + + var i,i0,i1,j,J,j0,j1,k,l,l0,l1,a; + i0 = Bi[I]; + i1 = Bi[I+1]; + xj.length = 0; + for(i=i0;i a) { e = k; a = c; } + } + if(abs(y[P[i]]) ret[k]) ret[k] = A.length; + var i; + for(i in A) { + if(A.hasOwnProperty(i)) dim(A[i],ret,k+1); + } + return ret; +}; + +numeric.sclone = function clone(A,k,n) { + if(typeof k === "undefined") { k=0; } + if(typeof n === "undefined") { n = numeric.sdim(A).length; } + var i,ret = Array(A.length); + if(k === n-1) { + for(i in A) { if(A.hasOwnProperty(i)) ret[i] = A[i]; } + return ret; + } + for(i in A) { + if(A.hasOwnProperty(i)) ret[i] = clone(A[i],k+1,n); + } + return ret; +}; + +numeric.sdiag = function diag(d) { + var n = d.length,i,ret = Array(n),i1,i2,i3; + for(i=n-1;i>=1;i-=2) { + i1 = i-1; + ret[i] = []; ret[i][i] = d[i]; + ret[i1] = []; ret[i1][i1] = d[i1]; + } + if(i===0) { ret[0] = []; ret[0][0] = d[i]; } + return ret; +}; + +numeric.sidentity = function identity(n) { return numeric.sdiag(numeric.rep([n],1)); }; + +numeric.stranspose = function transpose(A) { + var ret = [], n = A.length, i,j,Ai; + for(i in A) { + if(!(A.hasOwnProperty(i))) continue; + Ai = A[i]; + for(j in Ai) { + if(!(Ai.hasOwnProperty(j))) continue; + if(typeof ret[j] !== "object") { ret[j] = []; } + ret[j][i] = Ai[j]; + } + } + return ret; +}; + +numeric.sLUP = function LUP(A,tol) { + throw new Error("The function numeric.sLUP had a bug in it and has been removed. Please use the new numeric.ccsLUP function instead."); +}; + +numeric.sdotMM = function dotMM(A,B) { + var p = A.length, q = B.length, BT = numeric.stranspose(B), r = BT.length, Ai, BTk; + var i,j,k,accum; + var ret = Array(p),reti; + for(i=p-1;i>=0;i--) { + reti = []; + Ai = A[i]; + for(k=r-1;k>=0;k--) { + accum = 0; + BTk = BT[k]; + for(j in Ai) { + if(!(Ai.hasOwnProperty(j))) continue; + if(j in BTk) { accum += Ai[j]*BTk[j]; } + } + if(accum) reti[k] = accum; + } + ret[i] = reti; + } + return ret; +}; + +numeric.sdotMV = function dotMV(A,x) { + var p = A.length, Ai, i,j; + var ret = Array(p), accum; + for(i=p-1;i>=0;i--) { + Ai = A[i]; + accum = 0; + for(j in Ai) { + if(!(Ai.hasOwnProperty(j))) continue; + if(x[j]) accum += Ai[j]*x[j]; + } + if(accum) ret[i] = accum; + } + return ret; +}; + +numeric.sdotVM = function dotMV(x,A) { + var i,j,Ai,alpha; + var ret = [], 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]; + } + } + return ret; +}; + +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; +}; + +numeric.sdot = function dot(A,B) { + var m = numeric.sdim(A).length, n = numeric.sdim(B).length; + var k = m*1000+n; + switch(k) { + case 0: return A*B; + case 1001: return numeric.sdotVV(A,B); + case 2001: return numeric.sdotMV(A,B); + case 1002: return numeric.sdotVM(A,B); + case 2002: return numeric.sdotMM(A,B); + default: throw new Error('numeric.sdot not implemented for tensors of order '+m+' and '+n); + } +}; + +numeric.sscatter = function scatter(V) { + var n = V[0].length, Vij, i, j, m = V.length, A = [], Aj; + for(i=n-1;i>=0;--i) { + if(!V[m-1][i]) continue; + Aj = A; + for(j=0;j=0;--i) ret[i] = []; + } + for(i=n;i>=0;--i) ret[i].push(k[i]); + ret[n+1].push(Ai); + } + } else gather(Ai,ret,k); + } + } + if(k.length>n) k.pop(); + return ret; +}; + +// 6. Coordinate matrices +numeric.cLU = function LU(A) { + var I = A[0], J = A[1], V = A[2]; + var p = I.length, m=0, i,j,k,a,b,c; + for(i=0;im) m=I[i]; + m++; + var L = Array(m), U = Array(m), left = numeric.rep([m],Infinity), right = numeric.rep([m],-Infinity); + var Ui, Uj,alpha; + for(k=0;kright[i]) right[i] = j; + } + for(i=0;i right[i+1]) right[i+1] = right[i]; } + for(i=m-1;i>=1;i--) { if(left[i]=0;i--) { + while(Uj[k] > i) { + ret[i] -= Uv[k]*ret[Uj[k]]; + k--; + } + ret[i] /= Uv[k]; + k--; + } + return ret; +}; + +numeric.cgrid = function grid(n,shape) { + if(typeof n === "number") n = [n,n]; + var ret = numeric.rep(n,-1); + var i,j,count; + if(typeof shape !== "function") { + switch(shape) { + case 'L': + shape = function(i,j) { return (i>=n[0]/2 || jN) N = Ai[k]; } + N++; + ret = numeric.rep([N],0); + for(k=0;k1) { + mid = floor((p+q)/2); + if(x[mid] <= x0) p = mid; + else q = mid; + } + return this._at(x0,p); + } + var n = x0.length, i, ret = Array(n); + for(i=n-1;i!==-1;--i) ret[i] = this.at(x0[i]); + return ret; +}; + +numeric.Spline.prototype.diff = function diff() { + var x = this.x; + var yl = this.yl; + var yr = this.yr; + var kl = this.kl; + var kr = this.kr; + var n = yl.length; + var i,dx,dy; + var zl = kl, zr = kr, pl = Array(n), pr = Array(n); + var add = numeric.add, mul = numeric.mul, div = numeric.div, sub = numeric.sub; + for(i=n-1;i!==-1;--i) { + dx = x[i+1]-x[i]; + dy = sub(yr[i+1],yl[i]); + pl[i] = div(add(mul(dy, 6),mul(kl[i],-4*dx),mul(kr[i+1],-2*dx)),dx*dx); + pr[i+1] = div(add(mul(dy,-6),mul(kl[i], 2*dx),mul(kr[i+1], 4*dx)),dx*dx); + } + return new numeric.Spline(x,zl,zr,pl,pr); +}; + +numeric.Spline.prototype.roots = function roots() { + function sqr(x) { return x*x; } + function heval(y0,y1,k0,k1,x) { + var A = k0*2-(y1-y0); + var B = -k1*2+(y1-y0); + var t = (x+1)*0.5; + var s = t*(1-t); + return (1-t)*y0+t*y1+A*s*(1-t)+B*s*t; + } + var ret = []; + var x = this.x, yl = this.yl, yr = this.yr, kl = this.kl, kr = this.kr; + if(typeof yl[0] === "number") { + yl = [yl]; + yr = [yr]; + kl = [kl]; + kr = [kr]; + } + var m = yl.length,n=x.length-1,i,j,k,y,s,t; + var ai,bi,ci,di, ret = Array(m),ri,k0,k1,y0,y1,A,B,D,dx,cx,stops,z0,z1,zm,t0,t1,tm; + var sqrt = Math.sqrt; + for(i=0;i!==m;++i) { + ai = yl[i]; + bi = yr[i]; + ci = kl[i]; + di = kr[i]; + ri = []; + for(j=0;j!==n;j++) { + if(j>0 && bi[j]*ai[j]<0) ri.push(x[j]); + dx = (x[j+1]-x[j]); + cx = x[j]; + y0 = ai[j]; + y1 = bi[j+1]; + k0 = ci[j]/dx; + k1 = di[j+1]/dx; + D = sqr(k0-k1+3*(y0-y1)) + 12*k1*y0; + A = k1+3*y0+2*k0-3*y1; + B = 3*(k1+k0+2*(y0-y1)); + if(D<=0) { + z0 = A/B; + if(z0>x[j] && z0x[j] && z0x[j] && z10) { + t0 = t1; + z0 = z1; + continue; + } + var side = 0; + while(1) { + tm = (z0*t1-z1*t0)/(z0-z1); + if(tm <= t0 || tm >= t1) { break; } + zm = this._at(tm,j); + if(zm*z1>0) { + t1 = tm; + z1 = zm; + if(side === -1) z0*=0.5; + side = -1; + } else if(zm*z0>0) { + t0 = tm; + z0 = zm; + if(side === 1) z1*=0.5; + side = 1; + } else break; + } + ri.push(tm); + t0 = stops[k+1]; + z0 = this._at(t0, j); + } + if(z1 === 0) ri.push(t1); + } + ret[i] = ri; + } + if(typeof this.yl[0] === "number") return ret[0]; + return ret; +}; + +numeric.spline = function spline(x,y,k1,kn) { + var n = x.length, b = [], dx = [], dy = []; + var i; + var sub = numeric.sub,mul = numeric.mul,add = numeric.add; + for(i=n-2;i>=0;i--) { dx[i] = x[i+1]-x[i]; dy[i] = sub(y[i+1],y[i]); } + if(typeof k1 === "string" || typeof kn === "string") { + k1 = kn = "periodic"; + } + // Build sparse tridiagonal system + var T = [[],[],[]]; + switch(typeof k1) { + case "undefined": + b[0] = mul(3/(dx[0]*dx[0]),dy[0]); + T[0].push(0,0); + T[1].push(0,1); + T[2].push(2/dx[0],1/dx[0]); + break; + case "string": + b[0] = add(mul(3/(dx[n-2]*dx[n-2]),dy[n-2]),mul(3/(dx[0]*dx[0]),dy[0])); + T[0].push(0,0,0); + T[1].push(n-2,0,1); + T[2].push(1/dx[n-2],2/dx[n-2]+2/dx[0],1/dx[0]); + break; + default: + b[0] = k1; + T[0].push(0); + T[1].push(0); + T[2].push(1); + break; + } + for(i=1;i20) { throw new Error("Numerical gradient fails"); } + x0[i] = x[i]+h; + f1 = f(x0); + x0[i] = x[i]-h; + f2 = f(x0); + x0[i] = x[i]; + if(isNaN(f1) || isNaN(f2)) { h/=16; continue; } + J[i] = (f1-f2)/(2*h); + t0 = x[i]-h; + t1 = x[i]; + t2 = x[i]+h; + d1 = (f1-f0)/h; + d2 = (f0-f2)/h; + N = max(abs(J[i]),abs(f0),abs(f1),abs(f2),abs(t0),abs(t1),abs(t2),1e-8); + errest = min(max(abs(d1-J[i]),abs(d2-J[i]),abs(d1-d2))/N,h/N); + if(errest>eps) { h/=16; } + else break; + } + } + return J; +}; + +numeric.uncmin = function uncmin(f,x0,tol,gradient,maxit,callback,options) { + var grad = numeric.gradient; + if(typeof options === "undefined") { options = {}; } + if(typeof tol === "undefined") { tol = 1e-8; } + if(typeof gradient === "undefined") { gradient = function(x) { return grad(f,x); }; } + if(typeof maxit === "undefined") maxit = 1000; + x0 = numeric.clone(x0); + var n = x0.length; + var f0 = f(x0),f1,df0; + if(isNaN(f0)) throw new Error('uncmin: f(x0) is a NaN!'); + var max = Math.max, norm2 = numeric.norm2; + tol = max(tol,numeric.epsilon); + var step,g0,g1,H1 = options.Hinv || numeric.identity(n); + var dot = numeric.dot, inv = numeric.inv, sub = numeric.sub, add = numeric.add, ten = numeric.tensor, div = numeric.div, mul = numeric.mul; + var all = numeric.all, isfinite = numeric.isFinite, neg = numeric.neg; + var it=0,i,s,x1,y,Hy,Hs,ys,i0,t,nstep,t1,t2; + var msg = ""; + g0 = gradient(x0); + while(it= 0.1*t*df0 || isNaN(f1)) { + t *= 0.5; + ++it; + continue; + } + break; + } + if(t*nstep < tol) { msg = "Line search step size smaller than tol"; break; } + if(it === maxit) { msg = "maxit reached during line search"; break; } + g1 = gradient(x1); + y = sub(g1,g0); + ys = dot(y,s); + Hy = dot(H1,y); + H1 = sub(add(H1, + mul( + (ys+dot(y,Hy))/(ys*ys), + ten(s,s) )), + div(add(ten(Hy,s),ten(s,Hy)),ys)); + x0 = x1; + f0 = f1; + g0 = g1; + ++it; + } + return {solution: x0, f: f0, gradient: g0, invHessian: H1, iterations:it, message: msg}; +}; + +// 10. Ode solver (Dormand-Prince) +numeric.Dopri = function Dopri(x,y,f,ymid,iterations,msg,events) { + this.x = x; + this.y = y; + this.f = f; + this.ymid = ymid; + this.iterations = iterations; + this.events = events; + this.message = msg; +}; + +numeric.Dopri.prototype._at = function _at(xi,j) { + function sqr(x) { return x*x; } + var sol = this; + var xs = sol.x; + var ys = sol.y; + var k1 = sol.f; + var ymid = sol.ymid; + var n = xs.length; + var x0,x1,xh,y0,y1,yh,xi; + var floor = Math.floor,h; + var c = 0.5; + var add = numeric.add, mul = numeric.mul,sub = numeric.sub, p,q,w; + x0 = xs[j]; + x1 = xs[j+1]; + y0 = ys[j]; + y1 = ys[j+1]; + h = x1-x0; + xh = x0+c*h; + yh = ymid[j]; + p = sub(k1[j ],mul(y0,1/(x0-xh)+2/(x0-x1))); + q = sub(k1[j+1],mul(y1,1/(x1-xh)+2/(x1-x0))); + w = [sqr(xi - x1) * (xi - xh) / sqr(x0 - x1) / (x0 - xh), + sqr(xi - x0) * sqr(xi - x1) / sqr(x0 - xh) / sqr(x1 - xh), + sqr(xi - x0) * (xi - xh) / sqr(x1 - x0) / (x1 - xh), + (xi - x0) * sqr(xi - x1) * (xi - xh) / sqr(x0-x1) / (x0 - xh), + (xi - x1) * sqr(xi - x0) * (xi - xh) / sqr(x0-x1) / (x1 - xh)]; + return add(add(add(add(mul(y0,w[0]), + mul(yh,w[1])), + mul(y1,w[2])), + mul( p,w[3])), + mul( q,w[4])); +}; + +numeric.Dopri.prototype.at = function at(x) { + var i,j,k,floor = Math.floor; + if(typeof x !== "number") { + var n = x.length, ret = Array(n); + for(i=n-1;i!==-1;--i) { + ret[i] = this.at(x[i]); + } + return ret; + } + var x0 = this.x; + i = 0; j = x0.length-1; + while(j-i>1) { + k = floor(0.5*(i+j)); + if(x0[k] <= x) i = k; + else j = k; + } + return this._at(x,i); +}; + +numeric.dopri = function dopri(x0,x1,y0,f,tol,maxit,event) { + if(typeof tol === "undefined") { tol = 1e-6; } + if(typeof maxit === "undefined") { maxit = 1000; } + var xs = [x0], ys = [y0], k1 = [f(x0,y0)], k2,k3,k4,k5,k6,k7, ymid = []; + var A2 = 1/5; + var A3 = [3/40,9/40]; + var A4 = [44/45,-56/15,32/9]; + var A5 = [19372/6561,-25360/2187,64448/6561,-212/729]; + var A6 = [9017/3168,-355/33,46732/5247,49/176,-5103/18656]; + var b = [35/384,0,500/1113,125/192,-2187/6784,11/84]; + var bm = [0.5*6025192743/30085553152, + 0, + 0.5*51252292925/65400821598, + 0.5*-2691868925/45128329728, + 0.5*187940372067/1594534317056, + 0.5*-1776094331/19743644256, + 0.5*11237099/235043384]; + var c = [1/5,3/10,4/5,8/9,1,1]; + var e = [-71/57600,0,71/16695,-71/1920,17253/339200,-22/525,1/40]; + var i = 0,er,j; + var h = (x1-x0)/10; + var it = 0; + var add = numeric.add, mul = numeric.mul, y1,erinf; + var max = Math.max, min = Math.min, abs = Math.abs, norminf = numeric.norminf,pow = Math.pow; + var any = numeric.any, lt = numeric.lt, and = numeric.and, sub = numeric.sub; + var e0, e1, ev; + var ret = new numeric.Dopri(xs,ys,k1,ymid,-1,""); + if(typeof event === "function") e0 = event(x0,y0); + while(x0x1) h = x1-x0; + k2 = f(x0+c[0]*h, add(y0,mul( A2*h,k1[i]))); + k3 = f(x0+c[1]*h, add(add(y0,mul(A3[0]*h,k1[i])),mul(A3[1]*h,k2))); + k4 = f(x0+c[2]*h, add(add(add(y0,mul(A4[0]*h,k1[i])),mul(A4[1]*h,k2)),mul(A4[2]*h,k3))); + k5 = f(x0+c[3]*h, add(add(add(add(y0,mul(A5[0]*h,k1[i])),mul(A5[1]*h,k2)),mul(A5[2]*h,k3)),mul(A5[3]*h,k4))); + k6 = f(x0+c[4]*h,add(add(add(add(add(y0,mul(A6[0]*h,k1[i])),mul(A6[1]*h,k2)),mul(A6[2]*h,k3)),mul(A6[3]*h,k4)),mul(A6[4]*h,k5))); + y1 = add(add(add(add(add(y0,mul(k1[i],h*b[0])),mul(k3,h*b[2])),mul(k4,h*b[3])),mul(k5,h*b[4])),mul(k6,h*b[5])); + k7 = f(x0+h,y1); + er = add(add(add(add(add(mul(k1[i],h*e[0]),mul(k3,h*e[2])),mul(k4,h*e[3])),mul(k5,h*e[4])),mul(k6,h*e[5])),mul(k7,h*e[6])); + if(typeof er === "number") erinf = abs(er); + else erinf = norminf(er); + if(erinf > tol) { // reject + h = 0.2*h*pow(tol/erinf,0.25); + if(x0+h === x0) { + ret.msg = "Step size became too small"; + break; + } + continue; + } + ymid[i] = add(add(add(add(add(add(y0, + mul(k1[i],h*bm[0])), + mul(k3 ,h*bm[2])), + mul(k4 ,h*bm[3])), + mul(k5 ,h*bm[4])), + mul(k6 ,h*bm[5])), + mul(k7 ,h*bm[6])); + ++i; + xs[i] = x0+h; + ys[i] = y1; + k1[i] = k7; + if(typeof event === "function") { + var yi,xl = x0,xr = x0+0.5*h,xi; + e1 = event(xr,ymid[i-1]); + ev = and(lt(e0,0),lt(0,e1)); + if(!any(ev)) { xl = xr; xr = x0+h; e0 = e1; e1 = event(xr,y1); ev = and(lt(e0,0),lt(0,e1)); } + if(any(ev)) { + var xc, yc, en,ei; + var side=0, sl = 1.0, sr = 1.0; + while(1) { + if(typeof e0 === "number") xi = (sr*e1*xl-sl*e0*xr)/(sr*e1-sl*e0); + else { + xi = xr; + for(j=e0.length-1;j!==-1;--j) { + if(e0[j]<0 && e1[j]>0) xi = min(xi,(sr*e1[j]*xl-sl*e0[j]*xr)/(sr*e1[j]-sl*e0[j])); + } + } + if(xi <= xl || xi >= xr) break; + yi = ret._at(xi, i-1); + ei = event(xi,yi); + en = and(lt(e0,0),lt(0,ei)); + if(any(en)) { + xr = xi; + e1 = ei; + ev = en; + sr = 1.0; + if(side === -1) sl *= 0.5; + else sl = 1.0; + side = -1; + } else { + xl = xi; + e0 = ei; + sl = 1.0; + if(side === 1) sr *= 0.5; + else sr = 1.0; + side = 1; + } + } + y1 = ret._at(0.5*(x0+xi),i-1); + ret.f[i] = f(xi,yi); + ret.x[i] = xi; + ret.y[i] = yi; + ret.ymid[i-1] = y1; + ret.events = ev; + ret.iterations = it; + return ret; + } + } + x0 += h; + y0 = y1; + e0 = e1; + h = min(0.8*h*pow(tol/erinf,0.25),4*h); + } + ret.iterations = it; + return ret; +}; + +// 11. Ax = b +numeric.LU = function(A, fast) { + fast = fast || false; + + var abs = Math.abs; + var i, j, k, absAjk, Akk, Ak, Pk, Ai; + var max; + var n = A.length, n1 = n-1; + var P = new Array(n); + if(!fast) A = numeric.clone(A); + + for (k = 0; k < n; ++k) { + Pk = k; + Ak = A[k]; + max = abs(Ak[k]); + for (j = k + 1; j < n; ++j) { + absAjk = abs(A[j][k]); + if (max < absAjk) { + max = absAjk; + Pk = j; + } + } + P[k] = Pk; + + if (Pk != k) { + A[k] = A[Pk]; + A[Pk] = Ak; + Ak = A[k]; + } + + Akk = Ak[k]; + + for (i = k + 1; i < n; ++i) { + A[i][k] /= Akk; + } + + for (i = k + 1; i < n; ++i) { + Ai = A[i]; + for (j = k + 1; j < n1; ++j) { + Ai[j] -= Ai[k] * Ak[j]; + ++j; + Ai[j] -= Ai[k] * Ak[j]; + } + if(j===n1) Ai[j] -= Ai[k] * Ak[j]; + } + } + + return { + LU: A, + P: P + }; +}; + +numeric.LUsolve = function LUsolve(LUP, b) { + var i, j; + var LU = LUP.LU; + var n = LU.length; + var x = numeric.clone(b); + var P = LUP.P; + var Pi, LUi, LUii, tmp; + + for (i=n-1;i!==-1;--i) x[i] = b[i]; + for (i = 0; i < n; ++i) { + Pi = P[i]; + if (P[i] !== i) { + tmp = x[i]; + x[i] = x[Pi]; + x[Pi] = tmp; + } + + LUi = LU[i]; + for (j = 0; j < i; ++j) { + x[i] -= x[j] * LUi[j]; + } + } + + for (i = n - 1; i >= 0; --i) { + LUi = LU[i]; + for (j = i + 1; j < n; ++j) { + x[i] -= x[j] * LUi[j]; + } + + x[i] /= LUi[i]; + } + + return x; +}; + +numeric.solve = function solve(A,b,fast) { return numeric.LUsolve(numeric.LU(A,fast), b); }; + +// 12. Linear programming +numeric.echelonize = function echelonize(A) { + var s = numeric.dim(A), m = s[0], n = s[1]; + var I = numeric.identity(m); + var P = Array(m); + var i,j,k,l,Ai,Ii,Z,a; + var abs = Math.abs; + var diveq = numeric.diveq; + A = numeric.clone(A); + for(i=0;ia1) alpha = a1; + g = add(c,mul(alpha,p)); + H = dot(A1,A0); + for(i=m-1;i!==-1;--i) H[i][i] += 1; + d = solve(H,div(g,alpha),true); + var t0 = div(z,dot(A,d)); + var t = 1.0; + for(i=n-1;i!==-1;--i) if(t0[i]<0) t = min(t,-0.999*t0[i]); + y = sub(x,mul(d,t)); + z = sub(b,dot(A,y)); + if(!all(gt(z,0))) return { solution: x, message: "", iterations: count }; + x = y; + if(alpha=0) unbounded = false; + else unbounded = true; + } + if(unbounded) return { solution: y, message: "Unbounded", iterations: count }; + } + return { solution: x, message: "maximum iteration count exceeded", iterations:count }; +}; + +numeric._solveLP = function _solveLP(c,A,b,tol,maxit) { + var m = c.length, n = b.length,y; + var sum = numeric.sum, log = numeric.log, mul = numeric.mul, sub = numeric.sub, dot = numeric.dot, div = numeric.div, add = numeric.add; + var c0 = numeric.rep([m],0).concat([1]); + var J = numeric.rep([n,1],-1); + var A0 = numeric.blockMatrix([[A , J ]]); + var b0 = b; + var y = numeric.rep([m],0).concat(Math.max(0,numeric.sup(numeric.neg(b)))+1); + var x0 = numeric.__solveLP(c0,A0,b0,tol,maxit,y,false); + var x = numeric.clone(x0.solution); + x.length = m; + var foo = numeric.inf(sub(b,dot(A,x))); + if(foo<0) { return { solution: NaN, message: "Infeasible", iterations: x0.iterations }; } + var ret = numeric.__solveLP(c, A, b, tol, maxit-x0.iterations, x, true); + ret.iterations += x0.iterations; + return ret; +}; + +numeric.solveLP = function solveLP(c,A,b,Aeq,beq,tol,maxit) { + if(typeof maxit === "undefined") maxit = 1000; + if(typeof tol === "undefined") tol = numeric.epsilon; + if(typeof Aeq === "undefined") return numeric._solveLP(c,A,b,tol,maxit); + var m = Aeq.length, n = Aeq[0].length, o = A.length; + var B = numeric.echelonize(Aeq); + var flags = numeric.rep([n],0); + var P = B.P; + var Q = []; + var i; + for(i=P.length-1;i!==-1;--i) flags[P[i]] = 1; + for(i=n-1;i!==-1;--i) if(flags[i]===0) Q.push(i); + var g = numeric.getRange; + var I = numeric.linspace(0,m-1), J = numeric.linspace(0,o-1); + var Aeq2 = g(Aeq,I,Q), A1 = g(A,J,P), A2 = g(A,J,Q), dot = numeric.dot, sub = numeric.sub; + var A3 = dot(A1,B.I); + var A4 = sub(A2,dot(A3,Aeq2)), b4 = sub(b,dot(A3,beq)); + var c1 = Array(P.length), c2 = Array(Q.length); + for(i=P.length-1;i!==-1;--i) c1[i] = c[P[i]]; + for(i=Q.length-1;i!==-1;--i) c2[i] = c[Q[i]]; + var c4 = sub(c2,dot(c1,dot(B.I,Aeq2))); + var S = numeric._solveLP(c4,A4,b4,tol,maxit); + var x2 = S.solution; + if(x2!==x2) return S; + var x1 = dot(B.I,sub(beq,dot(Aeq2,x2))); + var x = Array(c.length); + for(i=P.length-1;i!==-1;--i) x[P[i]] = x1[i]; + for(i=Q.length-1;i!==-1;--i) x[Q[i]] = x2[i]; + return { solution: x, message:S.message, iterations: S.iterations }; +}; + +numeric.MPStoLP = function MPStoLP(MPS) { + if(MPS instanceof String) { MPS.split('\n'); } + var state = 0; + var states = ['Initial state','NAME','ROWS','COLUMNS','RHS','BOUNDS','ENDATA']; + var n = MPS.length; + var i,j,z,N=0,rows = {}, sign = [], rl = 0, vars = {}, nv = 0; + var name; + var c = [], A = [], b = []; + function err(e) { throw new Error('MPStoLP: '+e+'\nLine '+i+': '+MPS[i]+'\nCurrent state: '+states[state]+'\n'); } + for(i=0;i +// +// Math.seedrandom('yipee'); Sets Math.random to a function that is +// initialized using the given explicit seed. +// +// Math.seedrandom(); Sets Math.random to a function that is +// seeded using the current time, dom state, +// and other accumulated local entropy. +// The generated seed string is returned. +// +// Math.seedrandom('yowza', true); +// Seeds using the given explicit seed mixed +// together with accumulated entropy. +// +// +// Seeds using physical random bits downloaded +// from random.org. +// +// Seeds using urandom bits from call.jsonlib.com, +// which is faster than random.org. +// +// Examples: +// +// Math.seedrandom("hello"); // Use "hello" as the seed. +// document.write(Math.random()); // Always 0.5463663768140734 +// document.write(Math.random()); // Always 0.43973793770592234 +// var rng1 = Math.random; // Remember the current prng. +// +// var autoseed = Math.seedrandom(); // New prng with an automatic seed. +// document.write(Math.random()); // Pretty much unpredictable. +// +// Math.random = rng1; // Continue "hello" prng sequence. +// document.write(Math.random()); // Always 0.554769432473455 +// +// Math.seedrandom(autoseed); // Restart at the previous seed. +// document.write(Math.random()); // Repeat the 'unpredictable' value. +// +// Notes: +// +// Each time seedrandom('arg') is called, entropy from the passed seed +// is accumulated in a pool to help generate future seeds for the +// zero-argument form of Math.seedrandom, so entropy can be injected over +// time by calling seedrandom with explicit data repeatedly. +// +// On speed - This javascript implementation of Math.random() is about +// 3-10x slower than the built-in Math.random() because it is not native +// code, but this is typically fast enough anyway. Seeding is more expensive, +// especially if you use auto-seeding. Some details (timings on Chrome 4): +// +// Our Math.random() - avg less than 0.002 milliseconds per call +// seedrandom('explicit') - avg less than 0.5 milliseconds per call +// seedrandom('explicit', true) - avg less than 2 milliseconds per call +// seedrandom() - avg about 38 milliseconds per call +// +// LICENSE (BSD): +// +// Copyright 2010 David Bau, all rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of this module nor the names of its contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/** + * All code is in an anonymous closure to keep the global namespace clean. + * + * @param {number=} overflow + * @param {number=} startdenom + */ + +// Patched by Seb so that seedrandom.js does not pollute the Math object. +// My tests suggest that doing Math.trouble = 1 makes Math lookups about 5% +// slower. +numeric.seedrandom = { pow:Math.pow, random:Math.random }; + +(function (pool, math, width, chunks, significance, overflow, startdenom) { + + +// +// seedrandom() +// This is the seedrandom function described above. +// +math['seedrandom'] = function seedrandom(seed, use_entropy) { + var key = []; + var arc4; + + // Flatten the seed string or build one from local entropy if needed. + seed = mixkey(flatten( + use_entropy ? [seed, pool] : + arguments.length ? seed : + [new Date().getTime(), pool, window], 3), key); + + // Use the seed to initialize an ARC4 generator. + arc4 = new ARC4(key); + + // Mix the randomness into accumulated entropy. + mixkey(arc4.S, pool); + + // Override Math.random + + // This function returns a random double in [0, 1) that contains + // randomness in every bit of the mantissa of the IEEE 754 value. + + math['random'] = function random() { // Closure to return a random double: + var n = arc4.g(chunks); // Start with a numerator n < 2 ^ 48 + var d = startdenom; // and denominator d = 2 ^ 48. + var x = 0; // and no 'extra last byte'. + while (n < significance) { // Fill up all significant digits by + n = (n + x) * width; // shifting numerator and + d *= width; // denominator and generating a + x = arc4.g(1); // new least-significant-byte. + } + while (n >= overflow) { // To avoid rounding up, before adding + n /= 2; // last byte, shift everything + d /= 2; // right using integer math until + x >>>= 1; // we have exactly the desired bits. + } + return (n + x) / d; // Form the number within [0, 1). + }; + + // Return the seed that was used + return seed; +}; + +// +// ARC4 +// +// An ARC4 implementation. The constructor takes a key in the form of +// an array of at most (width) integers that should be 0 <= x < (width). +// +// The g(count) method returns a pseudorandom integer that concatenates +// the next (count) outputs from ARC4. Its return value is a number x +// that is in the range 0 <= x < (width ^ count). +// +/** @constructor */ +function ARC4(key) { + var t, u, me = this, keylen = key.length; + var i = 0, j = me.i = me.j = me.m = 0; + me.S = []; + me.c = []; + + // The empty key [] is treated as [0]. + if (!keylen) { key = [keylen++]; } + + // Set up S using the standard key scheduling algorithm. + while (i < width) { me.S[i] = i++; } + for (i = 0; i < width; i++) { + t = me.S[i]; + j = lowbits(j + t + key[i % keylen]); + u = me.S[j]; + me.S[i] = u; + me.S[j] = t; + } + + // The "g" method returns the next (count) outputs as one number. + me.g = function getnext(count) { + var s = me.S; + var i = lowbits(me.i + 1); var t = s[i]; + var j = lowbits(me.j + t); var u = s[j]; + s[i] = u; + s[j] = t; + var r = s[lowbits(t + u)]; + while (--count) { + i = lowbits(i + 1); t = s[i]; + j = lowbits(j + t); u = s[j]; + s[i] = u; + s[j] = t; + r = r * width + s[lowbits(t + u)]; + } + me.i = i; + me.j = j; + return r; + }; + // For robust unpredictability discard an initial batch of values. + // See http://www.rsa.com/rsalabs/node.asp?id=2009 + me.g(width); +} + +// +// flatten() +// Converts an object tree to nested arrays of strings. +// +/** @param {Object=} result + * @param {string=} prop + * @param {string=} typ */ +function flatten(obj, depth, result, prop, typ) { + result = []; + typ = typeof(obj); + if (depth && typ == 'object') { + for (prop in obj) { + if (prop.indexOf('S') < 5) { // Avoid FF3 bug (local/sessionStorage) + try { result.push(flatten(obj[prop], depth - 1)); } catch (e) {} + } + } + } + return (result.length ? result : obj + (typ != 'string' ? '\0' : '')); +} + +// +// mixkey() +// Mixes a string seed into a key that is an array of integers, and +// returns a shortened string seed that is equivalent to the result key. +// +/** @param {number=} smear + * @param {number=} j */ +function mixkey(seed, key, smear, j) { + seed += ''; // Ensure the seed is a string + smear = 0; + for (j = 0; j < seed.length; j++) { + key[lowbits(j)] = + lowbits((smear ^= key[lowbits(j)] * 19) + seed.charCodeAt(j)); + } + seed = ''; + for (j in key) { seed += String.fromCharCode(key[j]); } + return seed; +} + +// +// lowbits() +// A quick "n mod width" for width a power of 2. +// +function lowbits(n) { return n & (width - 1); } + +// +// The following constants are related to IEEE 754 limits. +// +startdenom = math.pow(width, chunks); +significance = math.pow(2, significance); +overflow = significance * 2; + +// +// When seedrandom.js is loaded, we immediately mix a few bits +// from the built-in RNG into the entropy pool. Because we do +// not want to intefere with determinstic PRNG state later, +// seedrandom will not call math.random on its own again after +// initialization. +// +mixkey(math.random(), pool); + +// End anonymous scope, and pass initial values. +}( + [], // pool: entropy pool starts empty + numeric.seedrandom, // math: package containing random, pow, and seedrandom + 256, // width: each RC4 output is 0 <= x < 256 + 6, // chunks: at least six RC4 outputs for each double + 52 // significance: there are 52 significant digits in a double + )); +/* This file is a slightly modified version of quadprog.js from Alberto Santini. + * It has been slightly modified by Sébastien Loisel to make sure that it handles + * 0-based Arrays instead of 1-based Arrays. + * License is in resources/LICENSE.quadprog */ + +function base0to1(A) { + if(typeof A !== "object") { return A; } + var ret = [], i,n=A.length; + for(i=0;i meq) { + work[l] = sum; + } else { + work[l] = -Math.abs(sum); + if (sum > 0) { + for (j = 1; j <= n; j = j + 1) { + amat[j][i] = -amat[j][i]; + } + bvec[i] = -bvec[i]; + } + } + } + + for (i = 1; i <= nact; i = i + 1) { + work[iwsv + iact[i]] = 0; + } + + nvl = 0; + temp = 0; + for (i = 1; i <= q; i = i + 1) { + if (work[iwsv + i] < temp * work[iwnbv + i]) { + nvl = i; + temp = work[iwsv + i] / work[iwnbv + i]; + } + } + if (nvl === 0) { + return 999; + } + + return 0; + } + + function fn_goto_55() { + for (i = 1; i <= n; i = i + 1) { + sum = 0; + for (j = 1; j <= n; j = j + 1) { + sum = sum + dmat[j][i] * amat[j][nvl]; + } + work[i] = sum; + } + + l1 = iwzv; + for (i = 1; i <= n; i = i + 1) { + work[l1 + i] = 0; + } + for (j = nact + 1; j <= n; j = j + 1) { + for (i = 1; i <= n; i = i + 1) { + work[l1 + i] = work[l1 + i] + dmat[i][j] * work[j]; + } + } + + t1inf = true; + for (i = nact; i >= 1; i = i - 1) { + sum = work[i]; + l = iwrm + (i * (i + 3)) / 2; + l1 = l - i; + for (j = i + 1; j <= nact; j = j + 1) { + sum = sum - work[l] * work[iwrv + j]; + l = l + j; + } + sum = sum / work[l1]; + work[iwrv + i] = sum; + if (iact[i] < meq) { + // continue; + break; + } + if (sum < 0) { + // continue; + break; + } + t1inf = false; + it1 = i; + } + + if (!t1inf) { + t1 = work[iwuv + it1] / work[iwrv + it1]; + for (i = 1; i <= nact; i = i + 1) { + if (iact[i] < meq) { + // continue; + break; + } + if (work[iwrv + i] < 0) { + // continue; + break; + } + temp = work[iwuv + i] / work[iwrv + i]; + if (temp < t1) { + t1 = temp; + it1 = i; + } + } + } + + sum = 0; + for (i = iwzv + 1; i <= iwzv + n; i = i + 1) { + sum = sum + work[i] * work[i]; + } + if (Math.abs(sum) <= vsmall) { + if (t1inf) { + ierr[1] = 1; + // GOTO 999 + return 999; + } else { + for (i = 1; i <= nact; i = i + 1) { + work[iwuv + i] = work[iwuv + i] - t1 * work[iwrv + i]; + } + work[iwuv + nact + 1] = work[iwuv + nact + 1] + t1; + // GOTO 700 + return 700; + } + } else { + sum = 0; + for (i = 1; i <= n; i = i + 1) { + sum = sum + work[iwzv + i] * amat[i][nvl]; + } + tt = -work[iwsv + nvl] / sum; + t2min = true; + if (!t1inf) { + if (t1 < tt) { + tt = t1; + t2min = false; + } + } + + for (i = 1; i <= n; i = i + 1) { + sol[i] = sol[i] + tt * work[iwzv + i]; + if (Math.abs(sol[i]) < vsmall) { + sol[i] = 0; + } + } + + crval[1] = crval[1] + tt * sum * (tt / 2 + work[iwuv + nact + 1]); + for (i = 1; i <= nact; i = i + 1) { + work[iwuv + i] = work[iwuv + i] - tt * work[iwrv + i]; + } + work[iwuv + nact + 1] = work[iwuv + nact + 1] + tt; + + if (t2min) { + nact = nact + 1; + iact[nact] = nvl; + + l = iwrm + ((nact - 1) * nact) / 2 + 1; + for (i = 1; i <= nact - 1; i = i + 1) { + work[l] = work[i]; + l = l + 1; + } + + if (nact === n) { + work[l] = work[n]; + } else { + for (i = n; i >= nact + 1; i = i - 1) { + if (work[i] === 0) { + // continue; + break; + } + gc = Math.max(Math.abs(work[i - 1]), Math.abs(work[i])); + gs = Math.min(Math.abs(work[i - 1]), Math.abs(work[i])); + if (work[i - 1] >= 0) { + temp = Math.abs(gc * Math.sqrt(1 + gs * gs / (gc * gc))); + } else { + temp = -Math.abs(gc * Math.sqrt(1 + gs * gs / (gc * gc))); + } + gc = work[i - 1] / temp; + gs = work[i] / temp; + + if (gc === 1) { + // continue; + break; + } + if (gc === 0) { + work[i - 1] = gs * temp; + for (j = 1; j <= n; j = j + 1) { + temp = dmat[j][i - 1]; + dmat[j][i - 1] = dmat[j][i]; + dmat[j][i] = temp; + } + } else { + work[i - 1] = temp; + nu = gs / (1 + gc); + for (j = 1; j <= n; j = j + 1) { + temp = gc * dmat[j][i - 1] + gs * dmat[j][i]; + dmat[j][i] = nu * (dmat[j][i - 1] + temp) - dmat[j][i]; + dmat[j][i - 1] = temp; + + } + } + } + work[l] = work[nact]; + } + } else { + sum = -bvec[nvl]; + for (j = 1; j <= n; j = j + 1) { + sum = sum + sol[j] * amat[j][nvl]; + } + if (nvl > meq) { + work[iwsv + nvl] = sum; + } else { + work[iwsv + nvl] = -Math.abs(sum); + if (sum > 0) { + for (j = 1; j <= n; j = j + 1) { + amat[j][nvl] = -amat[j][nvl]; + } + bvec[nvl] = -bvec[nvl]; + } + } + // GOTO 700 + return 700; + } + } + + return 0; + } + + function fn_goto_797() { + l = iwrm + (it1 * (it1 + 1)) / 2 + 1; + l1 = l + it1; + if (work[l1] === 0) { + // GOTO 798 + return 798; + } + gc = Math.max(Math.abs(work[l1 - 1]), Math.abs(work[l1])); + gs = Math.min(Math.abs(work[l1 - 1]), Math.abs(work[l1])); + if (work[l1 - 1] >= 0) { + temp = Math.abs(gc * Math.sqrt(1 + gs * gs / (gc * gc))); + } else { + temp = -Math.abs(gc * Math.sqrt(1 + gs * gs / (gc * gc))); + } + gc = work[l1 - 1] / temp; + gs = work[l1] / temp; + + if (gc === 1) { + // GOTO 798 + return 798; + } + if (gc === 0) { + for (i = it1 + 1; i <= nact; i = i + 1) { + temp = work[l1 - 1]; + work[l1 - 1] = work[l1]; + work[l1] = temp; + l1 = l1 + i; + } + for (i = 1; i <= n; i = i + 1) { + temp = dmat[i][it1]; + dmat[i][it1] = dmat[i][it1 + 1]; + dmat[i][it1 + 1] = temp; + } + } else { + nu = gs / (1 + gc); + for (i = it1 + 1; i <= nact; i = i + 1) { + temp = gc * work[l1 - 1] + gs * work[l1]; + work[l1] = nu * (work[l1 - 1] + temp) - work[l1]; + work[l1 - 1] = temp; + l1 = l1 + i; + } + for (i = 1; i <= n; i = i + 1) { + temp = gc * dmat[i][it1] + gs * dmat[i][it1 + 1]; + dmat[i][it1 + 1] = nu * (dmat[i][it1] + temp) - dmat[i][it1 + 1]; + dmat[i][it1] = temp; + } + } + + return 0; + } + + function fn_goto_798() { + l1 = l - it1; + for (i = 1; i <= it1; i = i + 1) { + work[l1] = work[l]; + l = l + 1; + l1 = l1 + 1; + } + + work[iwuv + it1] = work[iwuv + it1 + 1]; + iact[it1] = iact[it1 + 1]; + it1 = it1 + 1; + if (it1 < nact) { + // GOTO 797 + return 797; + } + + return 0; + } + + function fn_goto_799() { + work[iwuv + nact] = work[iwuv + nact + 1]; + work[iwuv + nact + 1] = 0; + iact[nact] = 0; + nact = nact - 1; + iter[2] = iter[2] + 1; + + return 0; + } + + go = 0; + while (true) { + go = fn_goto_50(); + if (go === 999) { + return; + } + while (true) { + go = fn_goto_55(); + if (go === 0) { + break; + } + if (go === 999) { + return; + } + if (go === 700) { + if (it1 === nact) { + fn_goto_799(); + } else { + while (true) { + fn_goto_797(); + go = fn_goto_798(); + if (go !== 797) { + break; + } + } + fn_goto_799(); + } + } + } + } + +} + +function solveQP(Dmat, dvec, Amat, bvec, meq, factorized) { + Dmat = base0to1(Dmat); + dvec = base0to1(dvec); + Amat = base0to1(Amat); + var i, n, q, + nact, r, + crval = [], iact = [], sol = [], work = [], iter = [], + message; + + meq = meq || 0; + factorized = factorized ? base0to1(factorized) : [undefined, 0]; + bvec = bvec ? base0to1(bvec) : []; + + // In Fortran the array index starts from 1 + n = Dmat.length - 1; + q = Amat[1].length - 1; + + if (!bvec) { + for (i = 1; i <= q; i = i + 1) { + bvec[i] = 0; + } + } + for (i = 1; i <= q; i = i + 1) { + iact[i] = 0; + } + nact = 0; + r = Math.min(n, q); + for (i = 1; i <= n; i = i + 1) { + sol[i] = 0; + } + crval[1] = 0; + for (i = 1; i <= (2 * n + (r * (r + 5)) / 2 + 2 * q + 1); i = i + 1) { + work[i] = 0; + } + for (i = 1; i <= 2; i = i + 1) { + iter[i] = 0; + } + + qpgen2(Dmat, dvec, n, n, sol, crval, Amat, + bvec, n, q, meq, iact, nact, iter, work, factorized); + + message = ""; + if (factorized[1] === 1) { + message = "constraints are inconsistent, no solution!"; + } + if (factorized[1] === 2) { + message = "matrix D in quadratic function is not positive definite!"; + } + + return { + solution: base1to0(sol), + value: base1to0(crval), + unconstrained_solution: base1to0(dvec), + iterations: base1to0(iter), + iact: base1to0(iact), + message: message + }; +} + +numeric.solveQP = solveQP; +/* +Shanti Rao sent me this routine by private email. I had to modify it +slightly to work on Arrays instead of using a Matrix object. +It is apparently translated from http://stitchpanorama.sourceforge.net/Python/svd.py +*/ + +numeric.svd= function svd(A) { + var temp; +//Compute the thin SVD from G. H. Golub and C. Reinsch, Numer. Math. 14, 403-420 (1970) + var prec= numeric.epsilon; //Math.pow(2,-52) // assumes double prec + var tolerance= 1.e-64/prec; + var itmax= 50; + var c=0; + var i=0; + var j=0; + var k=0; + var l=0; + + var u= numeric.clone(A); + var m= u.length; + + var n= u[0].length; + + if (m < n) throw "Need more rows than columns"; + + var e = new Array(n); + var q = new Array(n); + for (i=0; i b) + return a*Math.sqrt(1.0+(b*b/a/a)); + else if (b == 0.0) + return a; + return b*Math.sqrt(1.0+(a*a/b/b)); + } + + //Householder's reduction to bidiagonal form + + var f= 0.0; + var g= 0.0; + var h= 0.0; + var x= 0.0; + var y= 0.0; + var z= 0.0; + var s= 0.0; + + for (i=0; i < n; i++) + { + e[i]= g; + s= 0.0; + l= i+1; + for (j=i; j < m; j++) + s += (u[j][i]*u[j][i]); + if (s <= tolerance) + g= 0.0; + else + { + f= u[i][i]; + g= Math.sqrt(s); + if (f >= 0.0) g= -g; + h= f*g-s; + u[i][i]=f-g; + for (j=l; j < n; j++) + { + s= 0.0; + for (k=i; k < m; k++) + s += u[k][i]*u[k][j]; + f= s/h; + for (k=i; k < m; k++) + u[k][j]+=f*u[k][i]; + } + } + q[i]= g; + s= 0.0; + for (j=l; j < n; j++) + s= s + u[i][j]*u[i][j]; + if (s <= tolerance) + g= 0.0; + else + { + f= u[i][i+1]; + g= Math.sqrt(s); + if (f >= 0.0) g= -g; + h= f*g - s; + u[i][i+1] = f-g; + for (j=l; j < n; j++) e[j]= u[i][j]/h; + for (j=l; j < m; j++) + { + s=0.0; + for (k=l; k < n; k++) + s += (u[j][k]*u[i][k]); + for (k=l; k < n; k++) + u[j][k]+=s*e[k]; + } + } + y= Math.abs(q[i])+Math.abs(e[i]); + if (y>x) + x=y; + } + + // accumulation of right hand gtransformations + for (i=n-1; i != -1; i+= -1) + { + if (g != 0.0) + { + h= g*u[i][i+1]; + for (j=l; j < n; j++) + v[j][i]=u[i][j]/h; + for (j=l; j < n; j++) + { + s=0.0; + for (k=l; k < n; k++) + s += u[i][k]*v[k][j]; + for (k=l; k < n; k++) + v[k][j]+=(s*v[k][i]); + } + } + for (j=l; j < n; j++) + { + v[i][j] = 0; + v[j][i] = 0; + } + v[i][i] = 1; + g= e[i]; + l= i; + } + + // accumulation of left hand transformations + for (i=n-1; i != -1; i+= -1) + { + l= i+1; + g= q[i]; + for (j=l; j < n; j++) + u[i][j] = 0; + if (g != 0.0) + { + h= u[i][i]*g; + for (j=l; j < n; j++) + { + s=0.0; + for (k=l; k < m; k++) s += u[k][i]*u[k][j]; + f= s/h; + for (k=i; k < m; k++) u[k][j]+=f*u[k][i]; + } + for (j=i; j < m; j++) u[j][i] = u[j][i]/g; + } + else + for (j=i; j < m; j++) u[j][i] = 0; + u[i][i] += 1; + } + + // diagonalization of the bidiagonal form + prec= prec*x; + for (k=n-1; k != -1; k+= -1) + { + for (var iteration=0; iteration < itmax; iteration++) + { // test f splitting + var test_convergence = false; + for (l=k; l != -1; l+= -1) + { + if (Math.abs(e[l]) <= prec) + { test_convergence= true; + break; + } + if (Math.abs(q[l-1]) <= prec) + break; + } + if (!test_convergence) + { // cancellation of e[l] if l>0 + c= 0.0; + s= 1.0; + var l1= l-1; + for (i =l; i= itmax-1) + throw 'Error: no convergence.'; + // shift from bottom 2x2 minor + x= q[l]; + y= q[k-1]; + g= e[k-1]; + h= e[k]; + f= ((y-z)*(y+z)+(g-h)*(g+h))/(2.0*h*y); + g= pythag(f,1.0); + if (f < 0.0) + f= ((x-z)*(x+z)+h*(y/(f-g)-h))/x; + else + f= ((x-z)*(x+z)+h*(y/(f+g)-h))/x; + // next QR transformation + c= 1.0; + s= 1.0; + for (i=l+1; i< k+1; i++) + { + g= e[i]; + y= q[i]; + h= s*g; + g= c*g; + z= pythag(f,h); + e[i-1]= z; + c= f/z; + s= h/z; + f= x*c+g*s; + g= -x*s+g*c; + h= y*s; + y= y*c; + for (j=0; j < n; j++) + { + x= v[j][i-1]; + z= v[j][i]; + v[j][i-1] = x*c+z*s; + v[j][i] = -x*s+z*c; + } + z= pythag(f,h); + q[i-1]= z; + c= f/z; + s= h/z; + f= c*g+s*y; + x= -s*g+c*y; + for (j=0; j < m; j++) + { + y= u[j][i-1]; + z= u[j][i]; + u[j][i-1] = y*c+z*s; + u[j][i] = -y*s+z*c; + } + } + e[l]= 0.0; + e[k]= f; + q[k]= x; + } + } + + //vt= transpose(v) + //return (u,q,vt) + for (i=0;i= 0; j--) + { + if (q[j] < q[i]) + { + // writeln(i,'-',j) + c = q[j]; + q[j] = q[i]; + q[i] = c; + for(k=0;k phi0 && t > epsilon) { + var theta = phi1 / phi0; + var u = (Math.sqrt(1.0 + 6.0 * theta) - 1.0) / (3.0 * theta); + t *= u; + } + else { + this.copyVariables(x, x_new); + break; + } + } + } + + // add -dx to x to get the new variables + // + this.getNewVariableValue = function (x, dx, t) { + var x_new = new Array(x.length); + var i = 0; + for (i = 0; i < x.length; i++) { + x_new[i] = x[i] - t*dx[i]; + } + + return x_new; + } + + // copy x_new to x + // + this.copyVariables = function (x, x_new) { + var i = 0; + for (i = 0; i < x.length; i++) { + x[i] = x_new[i] + } + } + + // evaluate the function value's residual + // + this.evaluate_residual = function (funcsVal) { + var i; + var residual = 0; + for (i = 0; i < funcsVal.length; i++) { + residual += Math.abs(funcsVal[i]); + } + return residual; + } + + // evaluate the Euclidean_norm_of_residual + // + this.evaluate_Euclidean_norm_of_residual = function (funcsVal) { + var i; + var residual2 = 0; + for (i = 0; i < funcsVal.length; i++) { + var fabs = Math.abs(funcsVal[i]); + residual2 += fabs*fabs; + } + return Math.sqrt(residual2); + } + + // main function start here + // + var residual_tol = 1e-7; + var max_iteration = 1000; + var epsilon = 2.22e-16; + var JS_GSL_SUCCESS = 0; + var JS_GSL_CONTINUE = 1; + + // evaluate none linear system of equations and its jacobian matrix + // + var funcs = F(x); + var jacobian = A(x); + + // iterate to get the solution + // + var iter = 0; + var status; + do { + iter++; + + this.newton_iterate(F, A, x); + + if (this.evaluate_residual(F(x)) < residual_tol) + status = JS_GSL_SUCCESS; + else + status = JS_GSL_CONTINUE; + + } while (status == JS_GSL_CONTINUE && iter < max_iteration) + +} + +/* unit test + +Rosenbrock Function + + double y0 = 1 - x0; + double y1 = 10 * (x1 - x0 * x0); + + x0 = -1.2 + x1 = 1.0 + +*/ + + +/** + * Searches the interval from lowerLimit to upperLimit + * for a root (i.e., zero) of the function func with respect to + * its first argument using Brent's method root-finding algorithm. + * + * @param {function} function for which the root is sought. + * @param {number} the lower point of the interval to be searched. + * @param {number} the upper point of the interval to be searched. + * @param {number} the desired accuracy (convergence tolerance). + * @param {number} the maximum number of iterations. + * @returns an estimate for the root within accuracy. + */ +// Translated from zeroin.c in http://www.netlib.org/c/brent.shar. +numeric.uniroot = function uniroot(func, lowerLimit, upperLimit, errorTol, maxIter) { + var a = lowerLimit + , b = upperLimit + , c = a + , fa = func(a) + , fb = func(b) + , fc = fa + , s = 0 + , fs = 0 + , tol_act // Actual tolerance + , new_step // Step at this iteration + , prev_step // Distance from the last but one to the last approximation + , p // Interpolation step is calculated in the form p/q; division is delayed until the last moment + , q + ; + + errorTol = errorTol || 0; + maxIter = maxIter || 1000; + + while ( maxIter-- > 0 ) { + + prev_step = b - a; + + if ( Math.abs(fc) < Math.abs(fb) ) { + // Swap data for b to be the best approximation + a = b, b = c, c = a; + fa = fb, fb = fc, fc = fa; + } + + tol_act = 1e-15 * Math.abs(b) + errorTol / 2; + new_step = ( c - b ) / 2; + + if ( Math.abs(new_step) <= tol_act || fb === 0 ) { + return b; // Acceptable approx. is found + } + + // Decide if the interpolation can be tried + if ( Math.abs(prev_step) >= tol_act && Math.abs(fa) > Math.abs(fb) ) { + // If prev_step was large enough and was in true direction, Interpolatiom may be tried + var t1, cb, t2; + cb = c - b; + if ( a === c ) { // If we have only two distinct points linear interpolation can only be applied + t1 = fb / fa; + p = cb * t1; + q = 1.0 - t1; + } + else { // Quadric inverse interpolation + q = fa / fc, t1 = fb / fc, t2 = fb / fa; + p = t2 * (cb * q * (q - t1) - (b - a) * (t1 - 1)); + q = (q - 1) * (t1 - 1) * (t2 - 1); + } + + if ( p > 0 ) { + q = -q; // p was calculated with the opposite sign; make p positive + } + else { + p = -p; // and assign possible minus to q + } + + if ( p < ( 0.75 * cb * q - Math.abs( tol_act * q ) / 2 ) && + p < Math.abs( prev_step * q / 2 ) ) { + // If (b + p / q) falls in [b,c] and isn't too large it is accepted + new_step = p / q; + } + + // If p/q is too large then the bissection procedure can reduce [b,c] range to more extent + } + + if ( Math.abs( new_step ) < tol_act ) { // Adjust the step to be not less than tolerance + new_step = ( new_step > 0 ) ? tol_act : -tol_act; + } + + a = b, fa = fb; // Save the previous approx. + b += new_step, fb = func(b); // Do step to a new approxim. + + if ( (fb > 0 && fc > 0) || (fb < 0 && fc < 0) ) { + c = a, fc = fa; // Adjust c for it to have a sign opposite to that of b + } + } + +}; + + +/* +var test_counter; +function f1 (x) { test_counter++; return (Math.pow(x,2)-1)*x - 5; } +function f2 (x) { test_counter++; return Math.cos(x)-x; } +function f3 (x) { test_counter++; return Math.sin(x)-x; } +function f4 (x) { test_counter++; return (x + 3) * Math.pow(x - 1, 2); } +[ + [f1, 2, 3], + [f2, 2, 3], + [f2, -1, 3], + [f3, -1, 3], + [f4, -4, 4/3] +].forEach(function (args) { + test_counter = 0; + var root = uniroot.apply( pv, args ); + ;;;console.log( 'uniroot:', args.slice(1), root, test_counter ); +}) +*/ +numeric.Sparse = function Sparse(p,v) { this.p = p; this.v = v; }; + +numeric.Sparse.scatter = function scatter(i,j,z) { + var n = numeric.sup(j)+1,m=i.length,jk; + var p = Array(n),v = Array(n),k; + for(k=n-1;k!==-1;--k) { p[k] = []; v[k] = []; } + for(k=0;k!==m;++k) { + jk = j[k]; + p[jk].push(i[k]); + v[jk].push(z[k]); + } + return new numeric.Sparse(p,v); +}; + +numeric.Sparse.identity = function identity(n) { + return numeric.Sparse.scatter(numeric.linspace(0,n-1),numeric.linspace(0,n-1),numeric.rep([n],1)); +}; + +numeric.Sparse.prototype.dim = function dim() { + var m = 0, i,j,p=this.p,k=p.length,pi,a,b; + for(i=k-1;i!==-1;--i) { + pi = p[i]; + a = pi.length; + for(j=a-1;j!==-1;--j) { + b = pi[j]; + if(b>m) m = b; + } + } + return [m+1,p.length]; +}; + +numeric.Sparse.prototype.Lsolve = function Lsolve(b,n) { + if(typeof n === "undefined") { n = b.length; } + var i,j,k,ret = Array(n), p = this.p, v = this.v, pj,vj,m; + for(i=0;ij && i=j) t[i-j] = vj[k]; + } + if(j!==0) { + for(k=n-1;k!==-1;--k) foo[k] = 0; + for(k=0;k + + + + + @@ -49,6 +53,7 @@ bnotBinary negation ~x borBinary or x|y bxorBinary xor x^y +ccsDiagCreate sparse diagonal matrix ccsDimDimensions of sparse matrix ccsDotSparse matrix-matrix product ccsFullConvert sparse to full @@ -58,6 +63,7 @@ ccsLUPSolveSolve Ax=b using LUP decomp ccsScatterScatter entries of sparse matrix ccsSparseConvert from full to sparse +ccsTransposeSparse matrix transpose ccsTSolveSolve upper/lower triangular system ccs<op>Supported ops include: add/div/mul/geq/etc... cLUCoordinate matrix LU decomposition @@ -81,10 +87,15 @@ FunctionDescription
dotMatrix-Matrix, Matrix-Vector and Vector-Matrix product +e2.71828182845904... eigEigenvalues and eigenvectors +emptyCreate an empty Array epsilon2.220446049250313e-16 eqPointwise comparison x === y expPointwise Math.exp(x) +flipFlip an Array on a given axis +fliplrFlip an Array on the innermost axis +flipudFlip an Array on the second innermost axis floorPoinwise Math.floor(x) geqPointwise x>=y getBlockExtract a block from a matrix @@ -95,9 +106,11 @@ invMatrix inverse isFinitePointwise isFinite(x) isNaNPointwise isNaN(x) +kronKronecker product of two matrices largeArrayDon't prettyPrint Arrays larger than this leqPointwise x<=y linspaceGenerate evenly spaced values +logspaceGenerate logarithmically spaced values logPointwise Math.log(x) lshiftPointwise x<<y lshifteqPointwise x<<=y @@ -110,26 +123,31 @@ mulPointwise x*y negPointwise -x neqPointwise x!==y -norm2Square root of the sum of the square of the entries of x +norm2Square root of the sum of the squares of an Array norm2SquaredSum of squares of entries of x norminfLargest modulus entry of x notPointwise logical negation !x +onesCreate an Array of ones orPointwise logical or x||y oreqPointwise x|=y parseCSVParse a CSV file into an Array parseDatePointwise parseDate(x) parseFloatPointwise parseFloat(x) +pi3.14159265358979... pointwiseCreate a pointwise function -powPointwise Math.pow(x) +powPointwise Math.pow(x,y) precisionNumber of digits to prettyPrint prettyPrintPretty-prints x randomCreate an Array of random numbers +rangeCreate an Array from a range repCreate an Array by duplicating values
FunctionDescription

+
rollRoll an Array on a given axis +
rot90Rotate an Array 90 degrees counter clockwise
roundPointwise Math.round(x)
rrshiftPointwise x>>>y
rrshifteqPointwise x>>>=y @@ -172,6 +190,7 @@
versionVersion string for the numeric library
xorPointwise x^y
xoreqPointwise x^=y +
zerosCreate an Array of zeros

@@ -246,7 +265,7 @@

Numerical analysis in Javascript

 IN> numeric.identity(100)
 OUT> ...Large Array...
-
+
By default, this happens with the Array's length is more than 50. This can be controlled by setting the variable numeric.largeArray to an appropriate value:
@@ -336,6 +355,19 @@ 

Utility functions

[0,0,0]]
+You can create a multidimensional Array of zeros or ones using the functions numeric.zeros() and +numeric.ones(), and empty Arrays using numeric.empty(). + +
+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> [[,,],[,,]]
+
+ 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 @@ -366,6 +398,7 @@

Utility functions

You can create a diagonal matrix using numeric.diag() +
 IN> numeric.diag([1,2,3])
 OUT> [[1,0,0],
@@ -373,6 +406,23 @@ 

Utility functions

[0,0,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]]
+
+ The function numeric.identity() returns the identity matrix.
 IN> numeric.identity(3)
@@ -397,6 +447,28 @@ 

Utility functions

OUT> [1,1.5,2,2.5,3]
+Or a vector of logarithmically spaced values between Math.pow(exp,a) and Math.pow(exp,b), where the default exp exponent is 10: + +
+IN> numeric.logspace(0,1,5);
+OUT> [1, 1.7782794100389228, 3.1622776601683795, 5.623413251903491, 10]
+IN> numeric.logspace(1,3,5,10);
+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]
+
+ @@ -842,6 +928,20 @@

Sparse linear algebra

IN> numeric.ccsDot(M,[[0,3],[0,1,2],x]) OUT> [[0,3],[0,1,2],[9,3,2]]
+Create a sparse diangoal matrix +
+IN> SA = numeric.ccsDiag([1,2,3]);
+OUT> [[ 0, 1, 2, 3],
+      [ 0, 1, 2],
+      [ 1, 2, 3]]
+
+Tranpose a sparse matrix +
+IN> numeric.ccsTranspose(numeric.ccsScatter([[0,1,2],[2,1,0],[1,2,4]]));
+OUT> [[ 0, 1, 2, 3],
+      [ 2, 1, 0],
+      [ 1, 2, 4]]  
+
We provide an LU=PA decomposition:
 IN> A = [[0,5,10,15,20,25],
@@ -887,8 +987,8 @@ 

Sparse linear algebra

foo = numeric.ccsFull(numeric.ccsDot(LUP.L,LUP.U)); PA = numeric.ccsFull(numeric.ccsGetBlock(A,LUP.P)); res = numeric.norminf(numeric.sub(foo,PA)); - if(!isFinite(res) || res>1e-6) { - result = { + if(!isFinite(res) || res>1e-6) { + result = { code: "Failed during 1000 sparse LUP", k:k,A:A,LUP:LUP,res:res }; @@ -948,19 +1048,19 @@

Solving PDEs

 IN> g = numeric.cgrid(5)
-OUT> 
+OUT>
 [[-1,-1,-1,-1,-1],
  [-1, 0, 1, 2,-1],
  [-1, 3, 4, 5,-1],
  [-1, 6, 7, 8,-1],
  [-1,-1,-1,-1,-1]]
 IN> coordL = numeric.cdelsq(g)
-OUT> 
+OUT>
 [[ 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8],
  [ 1, 3, 0, 0, 2, 4, 1, 1, 5, 2, 0, 4, 6, 3, 1, 3, 5, 7, 4, 2, 4, 8, 5, 3, 7, 6, 4, 6, 8, 7, 5, 7, 8],
  [-1,-1, 4,-1,-1,-1, 4,-1,-1, 4,-1,-1,-1, 4,-1,-1,-1,-1, 4,-1,-1,-1, 4,-1,-1, 4,-1,-1,-1, 4,-1,-1, 4]]
 IN> L = numeric.sscatter(coordL); // Just to see what it looks like
-OUT> 
+OUT>
 [[          4,         -1,           ,         -1],
  [         -1,          4,         -1,           ,         -1],
  [           ,         -1,          4,           ,           ,         -1],
@@ -975,21 +1075,21 @@ 

Solving PDEs

IN> numeric.cdotMV(coordL,x) OUT> [1,1,1,1,1,1,1,1,1] IN> G = numeric.rep([5,5],0); for(i=0;i<5;i++) for(j=0;j<5;j++) if(g[i][j]>=0) G[i][j] = x[g[i][j]]; G -OUT> +OUT> [[ 0 , 0 , 0 , 0 , 0 ], [ 0 , 0.6875, 0.875 , 0.6875, 0 ], [ 0 , 0.875 , 1.125 , 0.875 , 0 ], [ 0 , 0.6875, 0.875 , 0.6875, 0 ], [ 0 , 0 , 0 , 0 , 0 ]] IN> workshop.html('<img src="'+numeric.imageURL(numeric.mul([G,G,G],200))+'" width=100 />'); -OUT> +OUT>
You can also work on an L-shaped or arbitrary-shape domain:
 IN> numeric.cgrid(6,'L')
-OUT> 
+OUT>
 [[-1,-1,-1,-1,-1,-1],
  [-1, 0, 1,-1,-1,-1],
  [-1, 2, 3,-1,-1,-1],
@@ -997,7 +1097,7 @@ 

Solving PDEs

[-1, 8, 9,10,11,-1], [-1,-1,-1,-1,-1,-1]] IN> numeric.cgrid(5,function(i,j) { return i!==2 || j!==2; }) -OUT> +OUT> [[-1,-1,-1,-1,-1], [-1, 0, 1, 2,-1], [-1, 3,-1, 4,-1], @@ -1076,84 +1176,84 @@

Unconstrained optimization

Here are some demos from from Moré et al., 1981:
-IN> sqr = function(x) { return x*x; }; 
+IN> sqr = function(x) { return x*x; };
     numeric.uncmin(function(x) { return sqr(10*(x[1]-x[0]*x[0])) + sqr(1-x[0]); },[-1.2,1]).solution
 OUT> [1,1]
-IN> f = function(x) { return sqr(-13+x[0]+((5-x[1])*x[1]-2)*x[1])+sqr(-29+x[0]+((x[1]+1)*x[1]-14)*x[1]); }; 
+IN> f = function(x) { return sqr(-13+x[0]+((5-x[1])*x[1]-2)*x[1])+sqr(-29+x[0]+((x[1]+1)*x[1]-14)*x[1]); };
     x0 = numeric.uncmin(f,[0.5,-2]).solution
 OUT> [11.41,-0.8968]
-IN> f = function(x) { return sqr(1e4*x[0]*x[1]-1)+sqr(Math.exp(-x[0])+Math.exp(-x[1])-1.0001); }; 
+IN> f = function(x) { return sqr(1e4*x[0]*x[1]-1)+sqr(Math.exp(-x[0])+Math.exp(-x[1])-1.0001); };
     x0 = numeric.uncmin(f,[0,1]).solution
 OUT> [1.098e-5,9.106]
-IN> f = function(x) { return sqr(x[0]-1e6)+sqr(x[1]-2e-6)+sqr(x[0]*x[1]-2)}; 
+IN> f = function(x) { return sqr(x[0]-1e6)+sqr(x[1]-2e-6)+sqr(x[0]*x[1]-2)};
     x0 = numeric.uncmin(f,[0,1]).solution
 OUT> [1e6,2e-6]
-IN> f = function(x) { 
+IN> f = function(x) {
        return sqr(1.5-x[0]*(1-x[1]))+sqr(2.25-x[0]*(1-x[1]*x[1]))+sqr(2.625-x[0]*(1-x[1]*x[1]*x[1]));
-    }; 
+    };
     x0 = numeric.uncmin(f,[1,1]).solution
 OUT> [3,0.5]
-IN> f = function(x) { 
-        var ret = 0,i; 
+IN> f = function(x) {
+        var ret = 0,i;
         for(i=1;i<=10;i++) ret+=sqr(2+2*i-Math.exp(i*x[0])-Math.exp(i*x[1]));
-         return ret; 
+         return ret;
     };
     x0 = numeric.uncmin(f,[0.3,0.4]).solution
 OUT> [0.2578,0.2578]
-IN> y = [0.14,0.18,0.22,0.25,0.29,0.32,0.35,0.39,0.37,0.58,0.73,0.96,1.34,2.10,4.39]; 
-    f = function(x) { 
-        var ret = 0,i; 
-        for(i=1;i<=15;i++) ret+=sqr(y[i-1]-(x[0]+i/((16-i)*x[1]+Math.min(i,16-i)*x[2]))); 
-        return ret; 
-    }; 
+IN> y = [0.14,0.18,0.22,0.25,0.29,0.32,0.35,0.39,0.37,0.58,0.73,0.96,1.34,2.10,4.39];
+    f = function(x) {
+        var ret = 0,i;
+        for(i=1;i<=15;i++) ret+=sqr(y[i-1]-(x[0]+i/((16-i)*x[1]+Math.min(i,16-i)*x[2])));
+        return ret;
+    };
     x0 = numeric.uncmin(f,[1,1,1]).solution
 OUT> [0.08241,1.133,2.344]
-IN> y = [0.0009,0.0044,0.0175,0.0540,0.1295,0.2420,0.3521,0.3989,0.3521,0.2420,0.1295,0.0540,0.0175,0.0044,0.0009]; 
-    f = function(x) { 
-        var ret = 0,i; 
-        for(i=1;i<=15;i++) 
-        ret+=sqr(x[0]*Math.exp(-x[1]*sqr((8-i)/2-x[2])/2)-y[i-1]); 
-        return ret; 
-    }; 
+IN> y = [0.0009,0.0044,0.0175,0.0540,0.1295,0.2420,0.3521,0.3989,0.3521,0.2420,0.1295,0.0540,0.0175,0.0044,0.0009];
+    f = function(x) {
+        var ret = 0,i;
+        for(i=1;i<=15;i++)
+        ret+=sqr(x[0]*Math.exp(-x[1]*sqr((8-i)/2-x[2])/2)-y[i-1]);
+        return ret;
+    };
     x0 = numeric.div(numeric.round(numeric.mul(numeric.uncmin(f,[1,1,1]).solution,1000)),1000)
 OUT> [0.399,1,0]
-IN> f = function(x) { return sqr(x[0]+10*x[1])+5*sqr(x[2]-x[3])+sqr(sqr(x[1]-2*x[2]))+10*sqr(x[0]-x[3]); }; 
+IN> f = function(x) { return sqr(x[0]+10*x[1])+5*sqr(x[2]-x[3])+sqr(sqr(x[1]-2*x[2]))+10*sqr(x[0]-x[3]); };
     x0 = numeric.div(numeric.round(numeric.mul(numeric.uncmin(f,[3,-1,0,1]).solution,1e5)),1e5)
 OUT> [0,0,0,0]
-IN> f = function(x) { 
+IN> f = function(x) {
         return (sqr(10*(x[1]-x[0]*x[0]))+sqr(1-x[0])+
                 90*sqr(x[3]-x[2]*x[2])+sqr(1-x[2])+
-                10*sqr(x[1]+x[3]-2)+0.1*sqr(x[1]-x[3])); }; 
+                10*sqr(x[1]+x[3]-2)+0.1*sqr(x[1]-x[3])); };
     x0 = numeric.uncmin(f,[-3,-1,-3,-1]).solution
 OUT> [1,1,1,1]
-IN> y = [0.1957,0.1947,0.1735,0.1600,0.0844,0.0627,0.0456,0.0342,0.0323,0.0235,0.0246]; 
-    u = [4,2,1,0.5,0.25,0.167,0.125,0.1,0.0833,0.0714,0.0625]; 
-    f = function(x) { 
-        var ret=0, i; 
-        for(i=0;i<11;++i) ret += sqr(y[i]-x[0]*(u[i]*u[i]+u[i]*x[1])/(u[i]*u[i]+u[i]*x[2]+x[3])); 
-        return ret; 
-    }; 
+IN> y = [0.1957,0.1947,0.1735,0.1600,0.0844,0.0627,0.0456,0.0342,0.0323,0.0235,0.0246];
+    u = [4,2,1,0.5,0.25,0.167,0.125,0.1,0.0833,0.0714,0.0625];
+    f = function(x) {
+        var ret=0, i;
+        for(i=0;i<11;++i) ret += sqr(y[i]-x[0]*(u[i]*u[i]+u[i]*x[1])/(u[i]*u[i]+u[i]*x[2]+x[3]));
+        return ret;
+    };
     x0 = numeric.uncmin(f,[0.25,0.39,0.415,0.39]).solution
 OUT> [     0.1928,     0.1913,     0.1231,     0.1361]
 IN> y = [0.844,0.908,0.932,0.936,0.925,0.908,0.881,0.850,0.818,0.784,0.751,0.718,
          0.685,0.658,0.628,0.603,0.580,0.558,0.538,0.522,0.506,0.490,0.478,0.467,
-         0.457,0.448,0.438,0.431,0.424,0.420,0.414,0.411,0.406]; 
-    f = function(x) { 
-        var ret=0, i; 
-        for(i=0;i<33;++i) ret += sqr(y[i]-(x[0]+x[1]*Math.exp(-10*i*x[3])+x[2]*Math.exp(-10*i*x[4]))); 
-        return ret; 
-    }; 
+         0.457,0.448,0.438,0.431,0.424,0.420,0.414,0.411,0.406];
+    f = function(x) {
+        var ret=0, i;
+        for(i=0;i<33;++i) ret += sqr(y[i]-(x[0]+x[1]*Math.exp(-10*i*x[3])+x[2]*Math.exp(-10*i*x[4])));
+        return ret;
+    };
     x0 = numeric.uncmin(f,[0.5,1.5,-1,0.01,0.02]).solution
 OUT> [     0.3754,      1.936,     -1.465,    0.01287,    0.02212]
-IN> f = function(x) { 
-        var ret=0, i,ti,yi,exp=Math.exp; 
-        for(i=1;i<=13;++i) { 
-            ti = 0.1*i; 
-            yi = exp(-ti)-5*exp(-10*ti)+3*exp(-4*ti); 
-            ret += sqr(x[2]*exp(-ti*x[0])-x[3]*exp(-ti*x[1])+x[5]*exp(-ti*x[4])-yi); 
-        } 
-        return ret; 
-    }; 
+IN> f = function(x) {
+        var ret=0, i,ti,yi,exp=Math.exp;
+        for(i=1;i<=13;++i) {
+            ti = 0.1*i;
+            yi = exp(-ti)-5*exp(-10*ti)+3*exp(-4*ti);
+            ret += sqr(x[2]*exp(-ti*x[0])-x[3]*exp(-ti*x[1])+x[5]*exp(-ti*x[4])-yi);
+        }
+        return ret;
+    };
     x0 = numeric.uncmin(f,[1,2,1,1,1,1],1e-14).solution;
     f(x0)<1e-20;
 OUT> true
@@ -1163,8 +1263,8 @@ 

Unconstrained optimization

gradient of f(). If it is not provided, a numerical gradient is used. The iteration stops when maxit iterations have been performed. The optional callback() parameter, if provided, is called at each step:
-IN> z = []; 
-    cb = function(i,x,f,g,H) { z.push({i:i, x:x, f:f, g:g, H:H }); }; 
+IN> z = [];
+    cb = function(i,x,f,g,H) { z.push({i:i, x:x, f:f, g:g, H:H }); };
     x0 = numeric.uncmin(function(x) { return Math.cos(2*x[0]); },
                         [1],1e-10,
                         function(x) { return [-2*Math.sin(2*x[0])]; },
@@ -1193,7 +1293,7 @@ 

Linear programming

IN> x = numeric.solveLP([1,1], /* minimize [1,1]*x */ [[-1,0],[0,-1],[-1,-2]], /* matrix of inequalities */ [0,0,-3] /* right-hand-side of inequalities */ - ); + ); numeric.trunc(x.solution,1e-12); OUT> [0,1.5]
@@ -1349,7 +1449,7 @@

Solving ODEs

Seedrandom (David Bau)

-The object numeric.seedrandom is based on +The object numeric.seedrandom is based on David Bau's seedrandom.js. This small library can be used to create better pseudorandom numbers than Math.random() which can furthermore be "seeded". @@ -1367,4 +1467,4 @@

Seedrandom (David Bau)




- + \ No newline at end of file diff --git a/src/intro.js b/src/intro.js new file mode 100644 index 0000000..759fa9e --- /dev/null +++ b/src/intro.js @@ -0,0 +1,17 @@ +(function (root, factory) { + if (typeof exports === 'object') { + // Node. + module.exports = factory(); + } else if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(factory); + } else { + // Browser globals (root is window) + root.numeric = factory(); + } +}(this, function() { + +'use strict'; +var numeric = function numeric(){}; + +//if(typeof global !== "undefined") { global.numeric = numeric; } diff --git a/src/iterative.js b/src/iterative.js new file mode 100644 index 0000000..b895f28 --- /dev/null +++ b/src/iterative.js @@ -0,0 +1,363 @@ +// CCS matrix mul dense vector +// +// numeric.ccsMV is defined in src/numeric.js + + +numeric.bicgstab = function bicgstab(A, b, maxIters, residue) { + var maxIters = maxIters || 1024; + var residue = residue || 1e-6; + + var BiCG = function( A, b, dotVV, dotMV ) { + // initialization + var iters = 0; + var converged = false; + var rows = b.length; + + var dot = dotVV; + var mv = dotMV; + var add = numeric.add; + var mul = numeric.mul; + var axpy = function(alpha, x, y) { + return add(mul(x, alpha), y); + }; + + // initialize x + var x = numeric.rep([rows], 0); + + // r = b - A x + // x is zero initially + var r = mul(b, 1); + var rhat = mul(b, 1); + var rho = 1, alpha = 1, w = 1; + var p = mul(b, 1); + var v = numeric.rep([rows], 0); + var s, t, alpha, beta; + + var bnorm = dot(b, b); + + while( !converged && iters < maxIters ) { + var rDotr = dot(rhat, r); + + if( Math.abs(rDotr / bnorm) <= residue ) { + converged = true; + break; + } + + v = mv(A, p); + alpha = rDotr / dot(rhat, v); + s = axpy(-alpha, v, r); + + t = mv(A, s); + w = dot(t, s) / dot(t, t); + + x = axpy(w, s, axpy(alpha, p, x)); + r = axpy(-w, t, s); + + beta = dot(rhat, r) / rDotr * (alpha/w); + p = axpy(beta, axpy(-w, v, p), r); + + iters++; + } + + if( converged ) + console.log('converged in ' + iters + ' iterations'); + else + console.log('not converged in ' + iters + ' iterations'); + + return x; + } + + switch(A.format) { + case 'full': { + return BiCG(A, b, numeric.dot, numeric.dot); + } + case 'ccs': { + return BiCG(A, b, numeric.dot, numeric.ccsMV); + } + case 'crs': { + return BiCG(A, b, numeric.dot, numeric.cdotMV); + } + default: { + throw 'Not supported matrix format'; + } + } +} + +numeric.cg = function cg(A, b, maxIters, residue) { + var maxIters = maxIters || 1024; + var residue = residue || 1e-6; + + var CG = function( A, b, dotVV, dotMV ) { + // initialization + var iters = 0; + var converged = false; + var rows = b.length; + + var dot = dotVV; + var mv = dotMV; + var add = numeric.add; + var mul = numeric.mul; + var axpy = function(alpha, x, y) { + return add(mul(x, alpha), y); + }; + + // initialize x + var x = numeric.rep([rows], 0); + + // r = b - A x + // x is zero initially + var r = mul(b, 1); + var p = mul(b, 1); + + var bnorm = dot(b, b); + var rho = bnorm; + var flag = 1; + var Ap, pAp, alpha, beta, rho_new; + while( !converged && iters < maxIters ) { + if( Math.abs(rho / bnorm) <= residue ) { + converged = true; + break; + } + + Ap = mv(A, p); + pAp = dot(p, Ap); + alpha = rho / pAp; + + x = axpy(alpha, p, x); + r = axpy(-alpha, Ap, r); + + rho_new = dot(r, r); + beta = rho_new / rho; + p = axpy(beta, p, r); + rho = rho_new; + iters++; + } + + if( converged ) + console.log('converged in ' + iters + ' iterations'); + else + console.log('not converged in ' + iters + ' iterations'); + + return x; + } + + switch(A.format) { + case 'full': { + return CG(A, b, numeric.dot, numeric.dot); + } + case 'ccs': { + return CG(A, b, numeric.dot, numeric.ccsMV); + } + case 'crs': { + return CG(A, b, numeric.dot, numeric.cdotMV); + } + default: { + throw 'Not supported matrix format'; + } + } +}; + +numeric.sor = function sor(A, b, relax, maxIters, residue) { + var maxIters = maxIters || 1024; + var residue = residue || 1e-6; + var relax = relax || 1.0; // no relaxation by default, fall back to Gauss-Seidel + + var sor_full = function(A, b) { + // initialization + var iters = 0; + var converged = false; + var rows = b.length; + + var sA = numeric.dim(A); + var n = sA[0], m = sA[1]; + if( n != rows ) { + throw 'Matrix dimension does not match input vector.'; + } + + // initialize x + var x = numeric.rep([rows], 0); + var dot = numeric.dot; + var bnorm = dot(b, b); + var rowsum = 0; + var i, j; + var Ai; + var rowdiff; + var res = numeric.rep([rows], 0), r2; + + while(!converged && iters < maxIters) { + for(i=0;i phi0 && t > epsilon) { + var theta = phi1 / phi0; + var u = (Math.sqrt(1.0 + 6.0 * theta) - 1.0) / (3.0 * theta); + t *= u; + } + else { + this.copyVariables(x, x_new); + break; + } + } + } + + // add -dx to x to get the new variables + // + this.getNewVariableValue = function (x, dx, t) { + var x_new = new Array(x.length); + var i = 0; + for (i = 0; i < x.length; i++) { + x_new[i] = x[i] - t*dx[i]; + } + + return x_new; + } + + // copy x_new to x + // + this.copyVariables = function (x, x_new) { + var i = 0; + for (i = 0; i < x.length; i++) { + x[i] = x_new[i] + } + } + + // evaluate the function value's residual + // + this.evaluate_residual = function (funcsVal) { + var i; + var residual = 0; + for (i = 0; i < funcsVal.length; i++) { + residual += Math.abs(funcsVal[i]); + } + return residual; + } + + // evaluate the Euclidean_norm_of_residual + // + this.evaluate_Euclidean_norm_of_residual = function (funcsVal) { + var i; + var residual2 = 0; + for (i = 0; i < funcsVal.length; i++) { + var fabs = Math.abs(funcsVal[i]); + residual2 += fabs*fabs; + } + return Math.sqrt(residual2); + } + + // main function start here + // + var residual_tol = 1e-7; + var max_iteration = 1000; + var epsilon = 2.22e-16; + var JS_GSL_SUCCESS = 0; + var JS_GSL_CONTINUE = 1; + + // evaluate none linear system of equations and its jacobian matrix + // + var funcs = F(x); + var jacobian = A(x); + + // iterate to get the solution + // + var iter = 0; + var status; + do { + iter++; + + this.newton_iterate(F, A, x); + + if (this.evaluate_residual(F(x)) < residual_tol) + status = JS_GSL_SUCCESS; + else + status = JS_GSL_CONTINUE; + + } while (status == JS_GSL_CONTINUE && iter < max_iteration) + +} + +/* unit test + +Rosenbrock Function + + double y0 = 1 - x0; + double y1 = 10 * (x1 - x0 * x0); + + x0 = -1.2 + x1 = 1.0 + +*/ + + diff --git a/src/numeric.js b/src/numeric.js index 336f081..2b37c32 100644 --- a/src/numeric.js +++ b/src/numeric.js @@ -1,9 +1,5 @@ -"use strict"; -var numeric = (typeof exports === "undefined")?(function numeric() {}):(exports); -if(typeof global !== "undefined") { global.numeric = numeric; } - -numeric.version = "1.2.6"; +numeric.version = "1.2.8-2"; // 1. Utility functions numeric.bench = function bench (f,interval) { @@ -22,7 +18,7 @@ numeric.bench = function bench (f,interval) { while(i>0) { f(); i--; } t2 = new Date(); return 1000*(3*n-1)/(t2-t1); -} +}; numeric._myIndexOf = (function _myIndexOf(w) { var n = this.length,k; @@ -31,10 +27,17 @@ numeric._myIndexOf = (function _myIndexOf(w) { }); numeric.myIndexOf = (Array.prototype.indexOf)?Array.prototype.indexOf:numeric._myIndexOf; -numeric.Function = Function; numeric.precision = 4; numeric.largeArray = 50; +// Wrapper around `new Function` that closures in the `numeric` object. +numeric.compile = function () { + var args = Array.prototype.slice.call(arguments); + var body = args.pop(); + body = 'return function (' + args.join(',') + ') {' + body + '}'; + return (new Function(['numeric'], body))(numeric); +} + numeric.prettyPrint = function prettyPrint(x) { function fmtnum(x) { if(x === 0) { return '0'; } @@ -56,25 +59,25 @@ numeric.prettyPrint = function prettyPrint(x) { if(typeof x === "string") { ret.push('"'+x+'"'); return false; } if(typeof x === "boolean") { ret.push(x.toString()); return false; } if(typeof x === "number") { - var a = fmtnum(x); + var a = parseFloat(x.toString()).toString(); var b = x.toPrecision(numeric.precision); - var c = parseFloat(x.toString()).toString(); + var c = fmtnum(x); var d = [a,b,c,parseFloat(b).toString(),parseFloat(c).toString()]; for(k=1;k0) { - ret[count] = []; - for(j=0;j0) { + ret[count] = []; + for(j=0;j>> 8) ^ table[y]; } - + return crc ^ (-1); } @@ -232,7 +236,7 @@ numeric.imageURL = function imageURL(img) { var stream = [ 137, 80, 78, 71, 13, 10, 26, 10, // 0: PNG signature 0,0,0,13, // 8: IHDR Chunk length - 73, 72, 68, 82, // 12: "IHDR" + 73, 72, 68, 82, // 12: "IHDR" (w >> 24) & 255, (w >> 16) & 255, (w >> 8) & 255, w&255, // 16: Width (h >> 24) & 255, (h >> 16) & 255, (h >> 8) & 255, h&255, // 20: Height 8, // 24: bit depth @@ -303,14 +307,14 @@ numeric.imageURL = function imageURL(img) { stream.push(96); // CRC3 stream.push(130); // CRC4 return 'data:image/png;base64,'+base64(stream); -} +}; // 2. Linear algebra with Arrays. numeric._dim = function _dim(x) { var ret = []; while(typeof x === "object") { ret.push(x.length); x = x[0]; } return ret; -} +}; numeric.dim = function dim(x) { var y,z; @@ -326,10 +330,11 @@ numeric.dim = function dim(x) { return [x.length]; } return []; -} +}; -numeric.mapreduce = function mapreduce(body,init) { - return Function('x','accum','_s','_k', +// mapreduce +numeric.mapreduce = function mapreduce(body, init) { + return numeric.compile('x','accum','_s','_k', 'if(typeof accum === "undefined") accum = '+init+';\n'+ 'if(typeof x === "number") { var xi = x; '+body+'; return accum; }\n'+ 'if(typeof _s === "undefined") _s = numeric.dim(x);\n'+ @@ -354,47 +359,76 @@ numeric.mapreduce = function mapreduce(body,init) { '}\n'+ 'return accum;' ); -} -numeric.mapreduce2 = function mapreduce2(body,setup) { - return Function('x', +}; + +// +numeric.mapreduce2 = function mapreduce2(body, setup) { + return numeric.compile('x', 'var n = x.length;\n'+ - 'var i,xi;\n'+setup+';\n'+ + 'var i,xi;\n'+setup+'\n'+ 'for(i=n-1;i!==-1;--i) { \n'+ ' xi = x[i];\n'+ - ' '+body+';\n'+ + ' '+body+'\n'+ '}\n'+ 'return accum;' ); -} - +}; +// compare arrays/tensors numeric.same = function same(x,y) { - var i,n; + var i, n; + if(!(x instanceof Array) || !(y instanceof Array)) { return false; } + n = x.length; + if(n !== y.length) { return false; } - for(i=0;i=0;i--) { z[i] = numeric.empty(s,k+1); } + return z; +}; + +// repeat +numeric.rep = function rep(s, v, k) +{ + // repeat value v over a tensor of size s = [s0, s1, s2, ...] + // k recursive index + 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; } + + 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; } - for(i=n-1;i>=0;i--) { ret[i] = numeric.rep(s,v,k+1); } + + for(i = n - 1; i >= 0; i--) { ret[i] = numeric.rep(s, v, k+1); } + return ret; -} +}; +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) { +// dot functions +numeric.dotMMsmall = function dotMMsmall(x,y) +{ var i,j,k,p,q,r,ret,foo,bar,woo,i0,k0,p0,r0; p = x.length; q = y.length; r = y[0].length; ret = Array(p); @@ -413,7 +447,8 @@ numeric.dotMMsmall = function dotMMsmall(x,y) { ret[i] = foo; } return ret; -} +}; + numeric._getCol = function _getCol(A,j,x) { var n = A.length, i; for(i=n-1;i>0;--i) { @@ -422,7 +457,8 @@ numeric._getCol = function _getCol(A,j,x) { x[i] = A[i][j]; } 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; @@ -441,14 +477,14 @@ numeric.dotMMbig = function dotMMbig(x,y){ } } return A; -} +}; numeric.dotMV = function dotMV(x,y) { var p = x.length, q = y.length,i; var ret = Array(p), dotVV = numeric.dotVV; for(i=p-1;i>=0;i--) { ret[i] = dotVV(x[i],y); } return ret; -} +}; numeric.dotVM = function dotVM(x,y) { var i,j,k,p,q,r,ret,foo,bar,woo,i0,k0,p0,r0,s1,s2,s3,baz,accum; @@ -464,7 +500,7 @@ numeric.dotVM = function dotVM(x,y) { ret[k] = woo; } return ret; -} +}; numeric.dotVV = function dotVV(x,y) { var i,n=x.length,i1,ret = x[n-1]*y[n-1]; @@ -474,7 +510,7 @@ numeric.dotVV = function dotVV(x,y) { } if(i===0) { ret += x[0]*y[0]; } return ret; -} +}; numeric.dot = function dot(x,y) { var d = numeric.dim; @@ -490,7 +526,63 @@ numeric.dot = function dot(x,y) { case 0: return x*y; default: throw new Error('numeric.dot only works on vectors and matrices'); } -} +}; + +// diag function + +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=1;--i) { @@ -523,10 +616,12 @@ numeric.getDiag = function(A) { ret[0] = A[0][0]; } return ret; -} +}; + +numeric.identity = function identity(n) { return numeric.diag(numeric.rep([n],1)); }; -numeric.identity = function identity(n) { return numeric.diag(numeric.rep([n],1)); } -numeric.pointwise = function pointwise(params,body,setup) { +numeric.pointwise = function pointwise(params,body,setup) +{ if(typeof setup === "undefined") { setup = ""; } var fun = []; var k; @@ -557,9 +652,11 @@ numeric.pointwise = function pointwise(params,body,setup) { '}\n'+ 'return ret;' ); - return Function.apply(null,fun); -} -numeric.pointwise2 = function pointwise2(params,body,setup) { + return numeric.compile.apply(null,fun); +}; + +numeric.pointwise2 = function pointwise2(params,body,setup) +{ if(typeof setup === "undefined") { setup = ""; } var fun = []; var k; @@ -582,24 +679,28 @@ numeric.pointwise2 = function pointwise2(params,body,setup) { '}\n'+ 'return ret;' ); - return Function.apply(null,fun); -} + return numeric.compile.apply(null,fun); +}; + numeric._biforeach = (function _biforeach(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); } }); + 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); @@ -633,6 +734,7 @@ numeric.ops2 = { rshift: '>>', rrshift: '>>>' }; + numeric.opseq = { addeq: '+=', subeq: '-=', @@ -646,16 +748,20 @@ numeric.opseq = { 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']; + numeric.ops1 = { neg: '-', not: '!', bnot: '~', clone: '' }; + numeric.mapreducers = { any: ['if(xi) return true;','var accum = false;'], all: ['if(!xi) return false;','var accum = true;'], @@ -663,7 +769,7 @@ numeric.mapreducers = { 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;'], + 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;'] }; @@ -693,7 +799,7 @@ numeric.mapreducers = { 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] = Function( + numeric[i] = numeric.compile( 'var n = arguments.length, i, x = arguments[0], y;\n'+ 'var VV = numeric.'+i+'VV, VS = numeric.'+i+'VS, SV = numeric.'+i+'SV;\n'+ 'var dim = numeric.dim;\n'+ @@ -708,7 +814,7 @@ numeric.mapreducers = { 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+'eq'] = Function( + numeric[i+'eq'] = numeric.compile( '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'+ @@ -735,7 +841,7 @@ numeric.mapreducers = { 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+'eq'] = Function('x', + numeric[i+'eq'] = numeric.compile('x', 'if(typeof x !== "object") return '+o+'x\n'+ 'var i;\n'+ 'var V = numeric.'+i+'eqV;\n'+ @@ -743,7 +849,7 @@ numeric.mapreducers = { 'numeric._foreach(x,s,0,V);\n'+ 'return x;\n'); numeric[i+'V'] = numeric.pointwise2(['x[i]'],'ret[i] = '+o+'(x[i]);',setup); - numeric[i] = Function('x', + numeric[i] = numeric.compile('x', 'if(typeof x !== "object") return '+o+'(x)\n'+ 'var i;\n'+ 'var V = numeric.'+i+'V;\n'+ @@ -759,11 +865,11 @@ numeric.mapreducers = { if(numeric.mapreducers.hasOwnProperty(i)) { o = numeric.mapreducers[i]; numeric[i+'V'] = numeric.mapreduce2(o[0],o[1]); - numeric[i] = Function('x','s','k', + numeric[i] = numeric.compile('x','s','k', o[1]+ 'if(typeof x !== "object") {'+ ' xi = x;\n'+ - o[0]+';\n'+ + o[0]+'\n'+ ' return accum;\n'+ '}'+ 'if(typeof s === "undefined") s = numeric.dim(x);\n'+ @@ -773,7 +879,7 @@ numeric.mapreducers = { 'var n = x.length, i;\n'+ 'for(i=n-1;i!==-1;--i) {\n'+ ' xi = arguments.callee(x[i]);\n'+ - o[0]+';\n'+ + o[0]+'\n'+ '}\n'+ 'return accum;\n'); } @@ -783,6 +889,7 @@ numeric.mapreducers = { numeric.truncVV = numeric.pointwise(['x[i]','y[i]'],'ret[i] = round(x[i]/y[i])*y[i];','var round = Math.round;'); numeric.truncVS = numeric.pointwise(['x[i]','y'],'ret[i] = round(x[i]/y)*y;','var round = Math.round;'); numeric.truncSV = numeric.pointwise(['x','y[i]'],'ret[i] = round(x/y[i])*y[i];','var round = Math.round;'); + numeric.trunc = function trunc(x,y) { if(typeof x === "object") { if(typeof y === "object") return numeric.truncVV(x,y); @@ -790,7 +897,7 @@ numeric.trunc = function trunc(x,y) { } if (typeof y === "object") return numeric.truncSV(x,y); return Math.round(x/y)*y; -} +}; numeric.inv = function inv(x) { var s = numeric.dim(x), abs = Math.abs, m = s[0], n = s[1]; @@ -804,7 +911,7 @@ numeric.inv = function inv(x) { Aj = A[i0]; A[i0] = A[j]; A[j] = Aj; Ij = I[i0]; I[i0] = I[j]; I[j] = Ij; x = Aj[j]; - for(k=j;k!==n;++k) Aj[k] /= x; + for(k=j;k!==n;++k) Aj[k] /= x; for(k=n-1;k!==-1;--k) Ij[k] /= x; for(i=m-1;i!==-1;--i) { if(i!==j) { @@ -818,7 +925,7 @@ numeric.inv = function inv(x) { } } return I; -} +}; numeric.det = function det(x) { var s = numeric.dim(x); @@ -846,7 +953,7 @@ numeric.det = function det(x) { ret *= Aj[j]; } return ret*A[j][j]; -} +}; numeric.transpose = function transpose(x) { var i,j,m = x.length,n = x[0].length, ret=Array(n),A0,A1,Bj; @@ -873,7 +980,8 @@ numeric.transpose = function transpose(x) { if(j===0) { ret[0][0] = A0[0]; } } return ret; -} +}; + 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=0;i--) ret[i] = _random(s,k+1); return ret; -} -numeric.random = function random(s) { return numeric._random(s,0); } +}; + +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); @@ -926,6 +1035,21 @@ numeric.linspace = function linspace(a,b,n) { n--; for(i=n;i>=0;i--) { ret[i] = (i*b+(n-i)*a)/n; } return ret; +}; + +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 ? 1 : -1; @@ -1360,8 +1503,9 @@ numeric.house = function house(x) { var foo = numeric.norm2(v); if(foo === 0) { /* this should not happen */ throw new Error('eig: internal error'); } return numeric.div(v,foo); -} +}; +// upper hessenberg numeric.toUpperHessenberg = function toUpperHessenberg(me) { var s = numeric.dim(me); if(s.length !== 2 || s[0] !== s[1]) { throw new Error('numeric: toUpperHessenberg() only works on square matrices'); } @@ -1384,11 +1528,15 @@ numeric.toUpperHessenberg = function toUpperHessenberg(me) { } } return {H:A, Q:Q}; -} +}; +// precision numeric.epsilon = 2.220446049250313e-16; +numeric.pi = 3.141592653589793238462643383279502884197169399375105820; +numeric.e = 2.71828182845904523536028747135266249775724709369995; -numeric.QRFrancis = function(H,maxiter) { +// qr +numeric.QRFrancis = function(H, maxiter) { if(typeof maxiter === "undefined") { maxiter = 10000; } H = numeric.clone(H); var H0 = numeric.clone(H); @@ -1473,8 +1621,162 @@ numeric.QRFrancis = function(H,maxiter) { } } throw new Error('numeric: eigenvalue iteration does not converge -- increase maxiter?'); +}; + +// extension to real hermitian (symmetric) matrices +numeric.eigh = function(A, maxiter) +{ + return numeric.jacobi(A, maxiter) } +numeric.jacobi = function(Ain, maxiter) +{ + // jacobi method with rutishauser improvements from + // Rutishauser, H. (1966). The Jacobi method for real symmetric matrices. + // Numerische Mathematik, 9(1), 1–10. doi:10.1007/BF02165223 + + // returns object containing + // E: {x : v} eigenvalues. + // lambda : {x: d} eigenstates. + // niter : number of iterations. + // iterations : list of convergence factors for each step of the iteration. + // nrot : number of rotations performed. + + var size = [Ain.length, Ain[0].length]; + if (size[0] != size[1]) + { + throw 'jacobi : matrix must be square'; + } + // remember use only symmetric real matrices. + var n = size[0]; + + var v = numeric.identity(n); + var A = numeric.clone(Ain); + + var iters = numeric.rep([maxiter], 0); + var d = numeric.getDiag(A); + var bw = numeric.clone(d); + + // zeros + var zw = numeric.rep([n], 0); + + // iteration parameters + var iter = -1; + var niter = 0; + var nrot = 0; + var tresh = 0; + + // prealloc + var h, g, gapq, term, termp, termq, theta, t, c, s, tau; + while (iter < maxiter) + { + iter++; + iters[iter] = numeric.jacobinorm(A) + niter = iter; + tresh = iters[iter]/(4 * n); + + if (tresh==0) { return {E: {x: v}, lambda: {x: d}, iterations: iters, niter: niter, nrot: nrot}; } + + for (var p = 0; p < n; p++) + { + for (var q = p + 1; q < n; q++) + { + gapq = 10*Math.abs(A[p][q]); + termp = gapq + Math.abs(d[p]); + termq = gapq + Math.abs(d[q]); + if (iter > 4 && termp == Math.abs(d[p]) && termq == Math.abs(d[q])) + { + // remove small elmts + A[p][q] = 0; + } + else + { + if (Math.abs(A[p][q]) >= tresh) + { + // apply rotation + h = d[q] - d[p]; + term = Math.abs(h) + gapq; + if (term == Math.abs(h)) + { + t = A[p][q]/h; + } + else + { + theta = 0.5 * h / A[p][q]; + t = 1/(Math.abs(theta) + Math.sqrt(1 + theta*theta)); + if (theta < 0) + { + t = -t; + } + } + c = 1/Math.sqrt(1 + t*t); + s = t * c; + tau = s/(1 + c); + h = t * A[p][q]; + zw[p] = zw[p] - h; + zw[q] = zw[q] + h; + d[p] = d[p] - h; + d[q] = d[q] + h; + A[p][q] = 0; + // rotate and use upper tria only + for (var j = 0; j < p; j++) + { + g = A[j][p]; + h = A[j][q]; + A[j][p] = g - s * (h + g * tau); + A[j][q] = h + s * (g - h * tau); + } + for (var j = p + 1; j < q; j++) + { + g = A[p][j]; + h = A[j][q]; + A[p][j] = g - s * (h + g * tau); + A[j][q] = h + s * (g - h * tau); + } + for (var j = q + 1; j < n; j++) + { + g = A[p][j]; + h = A[q][j]; + A[p][j] = g - s * (h + g * tau); + A[q][j] = h + s * (g - h * tau); + } + // eigenstates + for (var j = 0; j < n; j++) + { + g = v[j][p]; + h = v[j][q]; + v[j][p] = g - s * (h + g * tau); + v[j][q] = h + s * (g - h * tau); + } + nrot++; + } + } + } + } + bw = numeric.add(bw, zw); + d = numeric.clone(bw); + zw = numeric.rep([n], 0); + } + + return {E: {x: v}, lambda: {x: d}, iterations: iters, niter: niter, nrot: nrot}; +} + +numeric.jacobinorm = function(A) +{ + // used in numeric.jacobi + var n = A.length; + var s = 0; + for (var i = 0; i < n; i ++) + { + for (var j = i + 1; j < n; j ++) + { + s = s + Math.pow(A[i][j], 2) + } + } + return Math.sqrt(s); +} + +// eig function numeric.eig = function eig(A,maxiter) { var QH = numeric.toUpperHessenberg(A); var QB = numeric.QRFrancis(QH.H,maxiter); @@ -1589,7 +1891,8 @@ numeric.ccsSparse = function ccsSparse(A) { } } return [Ai,Aj,Av]; -} +}; + numeric.ccsFull = function ccsFull(A) { var Ai = A[0], Aj = A[1], Av = A[2], s = numeric.ccsDim(A), m = s[0], n = s[1], i,j,j0,j1,k; var B = numeric.rep([m,n],0); @@ -1599,7 +1902,20 @@ numeric.ccsFull = function ccsFull(A) { for(j=j0;jn) k.pop(); return ret; -} +}; // 6. Coordinate matrices numeric.cLU = function LU(A) { @@ -2338,7 +2686,7 @@ numeric.cgrid = function grid(n,shape) { if(typeof shape !== "function") { switch(shape) { case 'L': - shape = function(i,j) { return (i>=n[0]/2 || j=n[0]/2 || j=0;i--) { dx[i] = x[i+1]-x[i]; dy[i] = sub(y[i+1],y[i]); } - if(typeof k1 === "string" || typeof kn === "string") { + if(typeof k1 === "string" || typeof kn === "string") { k1 = kn = "periodic"; } // Build sparse tridiagonal system @@ -2600,7 +2953,7 @@ numeric.spline = function spline(x,y,k1,kn) { if(typeof y[0] === "number") k = k[0]; else k = numeric.transpose(k); return new numeric.Spline(x,y,y,k,k); -} +}; // 8. FFT numeric.fftpow2 = function fftpow2(x,y) { @@ -2630,7 +2983,8 @@ numeric.fftpow2 = function fftpow2(x,y) { x[i] = xe[j] + ci*xo[j] - si*yo[j]; y[i] = ye[j] + ci*yo[j] + si*xo[j]; } -} +}; + numeric._ifftpow2 = function _ifftpow2(x,y) { var n = x.length; if(n === 1) return; @@ -2658,12 +3012,14 @@ numeric._ifftpow2 = function _ifftpow2(x,y) { x[i] = xe[j] + ci*xo[j] - si*yo[j]; y[i] = ye[j] + ci*yo[j] + si*xo[j]; } -} +}; + numeric.ifftpow2 = function ifftpow2(x,y) { numeric._ifftpow2(x,y); numeric.diveq(x,x.length); numeric.diveq(y,y.length); -} +}; + numeric.convpow2 = function convpow2(ax,ay,bx,by) { numeric.fftpow2(ax,ay); numeric.fftpow2(bx,by); @@ -2674,13 +3030,14 @@ numeric.convpow2 = function convpow2(ax,ay,bx,by) { ay[i] = axi*byi+ayi*bxi; } numeric.ifftpow2(ax,ay); -} +}; + numeric.T.prototype.fft = function fft() { var x = this.x, y = this.y; 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 b) - return a*Math.sqrt(1.0+(b*b/a/a)) - else if (b == 0.0) - return a - return b*Math.sqrt(1.0+(a*a/b/b)) - } - - //Householder's reduction to bidiagonal form - - var f= 0.0; - var g= 0.0; - var h= 0.0; - var x= 0.0; - var y= 0.0; - var z= 0.0; - var s= 0.0; - - for (i=0; i < n; i++) - { - e[i]= g; - s= 0.0; - l= i+1; - for (j=i; j < m; j++) - s += (u[j][i]*u[j][i]); - if (s <= tolerance) - g= 0.0; - else - { - f= u[i][i]; - g= Math.sqrt(s); - if (f >= 0.0) g= -g; - h= f*g-s - u[i][i]=f-g; - for (j=l; j < n; j++) - { - s= 0.0 - for (k=i; k < m; k++) - s += u[k][i]*u[k][j] - f= s/h - for (k=i; k < m; k++) - u[k][j]+=f*u[k][i] - } - } - q[i]= g - s= 0.0 - for (j=l; j < n; j++) - s= s + u[i][j]*u[i][j] - if (s <= tolerance) - g= 0.0 - else - { - f= u[i][i+1] - g= Math.sqrt(s) - if (f >= 0.0) g= -g - h= f*g - s - u[i][i+1] = f-g; - for (j=l; j < n; j++) e[j]= u[i][j]/h - for (j=l; j < m; j++) - { - s=0.0 - for (k=l; k < n; k++) - s += (u[j][k]*u[i][k]) - for (k=l; k < n; k++) - u[j][k]+=s*e[k] - } - } - y= Math.abs(q[i])+Math.abs(e[i]) - if (y>x) - x=y - } - - // accumulation of right hand gtransformations - for (i=n-1; i != -1; i+= -1) - { - if (g != 0.0) - { - h= g*u[i][i+1] - for (j=l; j < n; j++) - v[j][i]=u[i][j]/h - for (j=l; j < n; j++) - { - s=0.0 - for (k=l; k < n; k++) - s += u[i][k]*v[k][j] - for (k=l; k < n; k++) - v[k][j]+=(s*v[k][i]) - } - } - for (j=l; j < n; j++) - { - v[i][j] = 0; - v[j][i] = 0; - } - v[i][i] = 1; - g= e[i] - l= i - } - - // accumulation of left hand transformations - for (i=n-1; i != -1; i+= -1) - { - l= i+1 - g= q[i] - for (j=l; j < n; j++) - u[i][j] = 0; - if (g != 0.0) - { - h= u[i][i]*g - for (j=l; j < n; j++) - { - s=0.0 - for (k=l; k < m; k++) s += u[k][i]*u[k][j]; - f= s/h - for (k=i; k < m; k++) u[k][j]+=f*u[k][i]; - } - for (j=i; j < m; j++) u[j][i] = u[j][i]/g; - } - else - for (j=i; j < m; j++) u[j][i] = 0; - u[i][i] += 1; - } - - // diagonalization of the bidiagonal form - prec= prec*x - for (k=n-1; k != -1; k+= -1) - { - for (var iteration=0; iteration < itmax; iteration++) - { // test f splitting - var test_convergence = false - for (l=k; l != -1; l+= -1) - { - if (Math.abs(e[l]) <= prec) - { test_convergence= true - break - } - if (Math.abs(q[l-1]) <= prec) - break - } - if (!test_convergence) - { // cancellation of e[l] if l>0 - c= 0.0 - s= 1.0 - var l1= l-1 - for (i =l; i= itmax-1) - throw 'Error: no convergence.' - // shift from bottom 2x2 minor - x= q[l] - y= q[k-1] - g= e[k-1] - h= e[k] - f= ((y-z)*(y+z)+(g-h)*(g+h))/(2.0*h*y) - g= pythag(f,1.0) - if (f < 0.0) - f= ((x-z)*(x+z)+h*(y/(f-g)-h))/x - else - f= ((x-z)*(x+z)+h*(y/(f+g)-h))/x - // next QR transformation - c= 1.0 - s= 1.0 - for (i=l+1; i< k+1; i++) - { - g= e[i] - y= q[i] - h= s*g - g= c*g - z= pythag(f,h) - e[i-1]= z - c= f/z - s= h/z - f= x*c+g*s - g= -x*s+g*c - h= y*s - y= y*c - for (j=0; j < n; j++) - { - x= v[j][i-1] - z= v[j][i] - v[j][i-1] = x*c+z*s - v[j][i] = -x*s+z*c - } - z= pythag(f,h) - q[i-1]= z - c= f/z - s= h/z - f= c*g+s*y - x= -s*g+c*y - for (j=0; j < m; j++) - { - y= u[j][i-1] - z= u[j][i] - u[j][i-1] = y*c+z*s - u[j][i] = -y*s+z*c - } - } - e[l]= 0.0 - e[k]= f - q[k]= x - } - } - - //vt= transpose(v) - //return (u,q,vt) - for (i=0;i= 0; j--) - { - if (q[j] < q[i]) - { - // writeln(i,'-',j) - c = q[j] - q[j] = q[i] - q[i] = c - for(k=0;k b) + return a*Math.sqrt(1.0+(b*b/a/a)); + else if (b == 0.0) + return a; + return b*Math.sqrt(1.0+(a*a/b/b)); + } + + //Householder's reduction to bidiagonal form + + var f= 0.0; + var g= 0.0; + var h= 0.0; + var x= 0.0; + var y= 0.0; + var z= 0.0; + var s= 0.0; + + for (i=0; i < n; i++) + { + e[i]= g; + s= 0.0; + l= i+1; + for (j=i; j < m; j++) + s += (u[j][i]*u[j][i]); + if (s <= tolerance) + g= 0.0; + else + { + f= u[i][i]; + g= Math.sqrt(s); + if (f >= 0.0) g= -g; + h= f*g-s; + u[i][i]=f-g; + for (j=l; j < n; j++) + { + s= 0.0; + for (k=i; k < m; k++) + s += u[k][i]*u[k][j]; + f= s/h; + for (k=i; k < m; k++) + u[k][j]+=f*u[k][i]; + } + } + q[i]= g; + s= 0.0; + for (j=l; j < n; j++) + s= s + u[i][j]*u[i][j]; + if (s <= tolerance) + g= 0.0; + else + { + f= u[i][i+1]; + g= Math.sqrt(s); + if (f >= 0.0) g= -g; + h= f*g - s; + u[i][i+1] = f-g; + for (j=l; j < n; j++) e[j]= u[i][j]/h; + for (j=l; j < m; j++) + { + s=0.0; + for (k=l; k < n; k++) + s += (u[j][k]*u[i][k]); + for (k=l; k < n; k++) + u[j][k]+=s*e[k]; + } + } + y= Math.abs(q[i])+Math.abs(e[i]); + if (y>x) + x=y; + } + + // accumulation of right hand gtransformations + for (i=n-1; i != -1; i+= -1) + { + if (g != 0.0) + { + h= g*u[i][i+1]; + for (j=l; j < n; j++) + v[j][i]=u[i][j]/h; + for (j=l; j < n; j++) + { + s=0.0; + for (k=l; k < n; k++) + s += u[i][k]*v[k][j]; + for (k=l; k < n; k++) + v[k][j]+=(s*v[k][i]); + } + } + for (j=l; j < n; j++) + { + v[i][j] = 0; + v[j][i] = 0; + } + v[i][i] = 1; + g= e[i]; + l= i; + } + + // accumulation of left hand transformations + for (i=n-1; i != -1; i+= -1) + { + l= i+1; + g= q[i]; + for (j=l; j < n; j++) + u[i][j] = 0; + if (g != 0.0) + { + h= u[i][i]*g; + for (j=l; j < n; j++) + { + s=0.0; + for (k=l; k < m; k++) s += u[k][i]*u[k][j]; + f= s/h; + for (k=i; k < m; k++) u[k][j]+=f*u[k][i]; + } + for (j=i; j < m; j++) u[j][i] = u[j][i]/g; + } + else + for (j=i; j < m; j++) u[j][i] = 0; + u[i][i] += 1; + } + + // diagonalization of the bidiagonal form + prec= prec*x; + for (k=n-1; k != -1; k+= -1) + { + for (var iteration=0; iteration < itmax; iteration++) + { // test f splitting + var test_convergence = false; + for (l=k; l != -1; l+= -1) + { + if (Math.abs(e[l]) <= prec) + { test_convergence= true; + break; + } + if (Math.abs(q[l-1]) <= prec) + break; + } + if (!test_convergence) + { // cancellation of e[l] if l>0 + c= 0.0; + s= 1.0; + var l1= l-1; + for (i =l; i= itmax-1) + throw 'Error: no convergence.'; + // shift from bottom 2x2 minor + x= q[l]; + y= q[k-1]; + g= e[k-1]; + h= e[k]; + f= ((y-z)*(y+z)+(g-h)*(g+h))/(2.0*h*y); + g= pythag(f,1.0); + if (f < 0.0) + f= ((x-z)*(x+z)+h*(y/(f-g)-h))/x; + else + f= ((x-z)*(x+z)+h*(y/(f+g)-h))/x; + // next QR transformation + c= 1.0; + s= 1.0; + for (i=l+1; i< k+1; i++) + { + g= e[i]; + y= q[i]; + h= s*g; + g= c*g; + z= pythag(f,h); + e[i-1]= z; + c= f/z; + s= h/z; + f= x*c+g*s; + g= -x*s+g*c; + h= y*s; + y= y*c; + for (j=0; j < n; j++) + { + x= v[j][i-1]; + z= v[j][i]; + v[j][i-1] = x*c+z*s; + v[j][i] = -x*s+z*c; + } + z= pythag(f,h); + q[i-1]= z; + c= f/z; + s= h/z; + f= c*g+s*y; + x= -s*g+c*y; + for (j=0; j < m; j++) + { + y= u[j][i-1]; + z= u[j][i]; + u[j][i-1] = y*c+z*s; + u[j][i] = -y*s+z*c; + } + } + e[l]= 0.0; + e[k]= f; + q[k]= x; + } + } + + //vt= transpose(v) + //return (u,q,vt) + for (i=0;i= 0; j--) + { + if (q[j] < q[i]) + { + // writeln(i,'-',j) + c = q[j]; + q[j] = q[i]; + q[i] = c; + for(k=0;klowerLimit
to upperLimit + * for a root (i.e., zero) of the function func with respect to + * its first argument using Brent's method root-finding algorithm. + * + * @param {function} function for which the root is sought. + * @param {number} the lower point of the interval to be searched. + * @param {number} the upper point of the interval to be searched. + * @param {number} the desired accuracy (convergence tolerance). + * @param {number} the maximum number of iterations. + * @returns an estimate for the root within accuracy. + */ +// Translated from zeroin.c in http://www.netlib.org/c/brent.shar. +numeric.uniroot = function uniroot(func, lowerLimit, upperLimit, errorTol, maxIter) { + var a = lowerLimit + , b = upperLimit + , c = a + , fa = func(a) + , fb = func(b) + , fc = fa + , s = 0 + , fs = 0 + , tol_act // Actual tolerance + , new_step // Step at this iteration + , prev_step // Distance from the last but one to the last approximation + , p // Interpolation step is calculated in the form p/q; division is delayed until the last moment + , q + ; + + errorTol = errorTol || 0; + maxIter = maxIter || 1000; + + while ( maxIter-- > 0 ) { + + prev_step = b - a; + + if ( Math.abs(fc) < Math.abs(fb) ) { + // Swap data for b to be the best approximation + a = b, b = c, c = a; + fa = fb, fb = fc, fc = fa; + } + + tol_act = 1e-15 * Math.abs(b) + errorTol / 2; + new_step = ( c - b ) / 2; + + if ( Math.abs(new_step) <= tol_act || fb === 0 ) { + return b; // Acceptable approx. is found + } + + // Decide if the interpolation can be tried + if ( Math.abs(prev_step) >= tol_act && Math.abs(fa) > Math.abs(fb) ) { + // If prev_step was large enough and was in true direction, Interpolatiom may be tried + var t1, cb, t2; + cb = c - b; + if ( a === c ) { // If we have only two distinct points linear interpolation can only be applied + t1 = fb / fa; + p = cb * t1; + q = 1.0 - t1; + } + else { // Quadric inverse interpolation + q = fa / fc, t1 = fb / fc, t2 = fb / fa; + p = t2 * (cb * q * (q - t1) - (b - a) * (t1 - 1)); + q = (q - 1) * (t1 - 1) * (t2 - 1); + } + + if ( p > 0 ) { + q = -q; // p was calculated with the opposite sign; make p positive + } + else { + p = -p; // and assign possible minus to q + } + + if ( p < ( 0.75 * cb * q - Math.abs( tol_act * q ) / 2 ) && + p < Math.abs( prev_step * q / 2 ) ) { + // If (b + p / q) falls in [b,c] and isn't too large it is accepted + new_step = p / q; + } + + // If p/q is too large then the bissection procedure can reduce [b,c] range to more extent + } + + if ( Math.abs( new_step ) < tol_act ) { // Adjust the step to be not less than tolerance + new_step = ( new_step > 0 ) ? tol_act : -tol_act; + } + + a = b, fa = fb; // Save the previous approx. + b += new_step, fb = func(b); // Do step to a new approxim. + + if ( (fb > 0 && fc > 0) || (fb < 0 && fc < 0) ) { + c = a, fc = fa; // Adjust c for it to have a sign opposite to that of b + } + } + +}; + + +/* +var test_counter; +function f1 (x) { test_counter++; return (Math.pow(x,2)-1)*x - 5; } +function f2 (x) { test_counter++; return Math.cos(x)-x; } +function f3 (x) { test_counter++; return Math.sin(x)-x; } +function f4 (x) { test_counter++; return (x + 3) * Math.pow(x - 1, 2); } +[ + [f1, 2, 3], + [f2, 2, 3], + [f2, -1, 3], + [f3, -1, 3], + [f4, -4, 4/3] +].forEach(function (args) { + test_counter = 0; + var root = uniroot.apply( pv, args ); + ;;;console.log( 'uniroot:', args.slice(1), root, test_counter ); +}) +*/ diff --git a/tools/Crypto-JS v2.4.0/aes/aes-min.js b/tools/Crypto-JS v2.4.0/aes/aes-min.js index b96adf4..7109d37 100755 --- a/tools/Crypto-JS v2.4.0/aes/aes-min.js +++ b/tools/Crypto-JS v2.4.0/aes/aes-min.js @@ -1,9 +1,9 @@ -/* - * Crypto-JS v2.4.0 - * http://code.google.com/p/crypto-js/ - * Copyright (c) 2011, Jeff Mott. All rights reserved. - * http://code.google.com/p/crypto-js/wiki/License - */ +/* + * Crypto-JS v2.4.0 + * http://code.google.com/p/crypto-js/ + * Copyright (c) 2011, Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ (function(){function q(d,e){for(var b=0,a=0;a<8;a++){if(e&1)b^=d;var h=d&128;d=d<<1&255;if(h)d^=27;e>>>=1}return b}for(var o=Crypto,x=o.util,z=o.charenc.UTF8,k=[99,124,119,123,242,107,111,197,48,1,103,43,254,215,171,118,202,130,201,125,250,89,71,240,173,212,162,175,156,164,114,192,183,253,147,38,54,63,247,204,52,165,229,241,113,216,49,21,4,199,35,195,24,150,5,154,7,18,128,226,235,39,178,117,9,131,44,26,27,110,90,160,82,59,214,179,41,227,47,132,83,209,0,237,32,252,177,91,106,203,190,57,74,76,88,207, 208,239,170,251,67,77,51,133,69,249,2,127,80,60,159,168,81,163,64,143,146,157,56,245,188,182,218,33,16,255,243,210,205,12,19,236,95,151,68,23,196,167,126,61,100,93,25,115,96,129,79,220,34,42,144,136,70,238,184,20,222,94,11,219,224,50,58,10,73,6,36,92,194,211,172,98,145,149,228,121,231,200,55,109,141,213,78,169,108,86,244,234,101,122,174,8,186,120,37,46,28,166,180,198,232,221,116,31,75,189,139,138,112,62,181,102,72,3,246,14,97,53,87,185,134,193,29,158,225,248,152,17,105,217,142,148,155,30,135,233, 206,85,40,223,140,161,137,13,191,230,66,104,65,153,45,15,176,84,187,22],y=[],f=0;f<256;f++)y[k[f]]=f;var r=[],s=[],t=[],u=[],v=[],w=[];for(f=0;f<256;f++){r[f]=q(f,2);s[f]=q(f,3);t[f]=q(f,9);u[f]=q(f,11);v[f]=q(f,13);w[f]=q(f,14)}var A=[0,1,2,4,8,16,32,64,128,27,54],c=[[],[],[],[]],i,p,g,j=o.AES={encrypt:function(d,e,b){b=b||{};var a=b.mode||new o.mode.OFB;a.fixOptions&&a.fixOptions(b);d=d.constructor==String?z.stringToBytes(d):d;var h=b.iv||x.randomBytes(j._blocksize*4);e=e.constructor==String?o.PBKDF2(e, diff --git a/tools/Crypto-JS v2.4.0/aes/aes.js b/tools/Crypto-JS v2.4.0/aes/aes.js index bca0e13..d565a14 100755 --- a/tools/Crypto-JS v2.4.0/aes/aes.js +++ b/tools/Crypto-JS v2.4.0/aes/aes.js @@ -1,407 +1,407 @@ -/* - * Crypto-JS v2.4.0 - * http://code.google.com/p/crypto-js/ - * Copyright (c) 2011, Jeff Mott. All rights reserved. - * http://code.google.com/p/crypto-js/wiki/License - */ -(function(){ - -// Shortcuts -var C = Crypto, - util = C.util, - charenc = C.charenc, - UTF8 = charenc.UTF8; - -// Precomputed SBOX -var SBOX = [ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, - 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, - 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, - 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, - 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, - 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, - 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, - 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, - 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, - 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, - 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, - 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, - 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, - 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, - 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, - 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, - 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, - 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, - 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, - 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, - 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, - 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, - 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, - 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, - 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, - 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, - 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, - 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, - 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, - 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, - 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, - 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 ]; - -// Compute inverse SBOX lookup table -for (var INVSBOX = [], i = 0; i < 256; i++) INVSBOX[SBOX[i]] = i; - -// Compute mulitplication in GF(2^8) lookup tables -var MULT2 = [], - MULT3 = [], - MULT9 = [], - MULTB = [], - MULTD = [], - MULTE = []; - -function xtime(a, b) { - for (var result = 0, i = 0; i < 8; i++) { - if (b & 1) result ^= a; - var hiBitSet = a & 0x80; - a = (a << 1) & 0xFF; - if (hiBitSet) a ^= 0x1b; - b >>>= 1; - } - return result; -} - -for (var i = 0; i < 256; i++) { - MULT2[i] = xtime(i,2); - MULT3[i] = xtime(i,3); - MULT9[i] = xtime(i,9); - MULTB[i] = xtime(i,0xB); - MULTD[i] = xtime(i,0xD); - MULTE[i] = xtime(i,0xE); -} - -// Precomputed RCon lookup -var RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36]; - -// Inner state -var state = [[], [], [], []], - keylength, - nrounds, - keyschedule; - -var AES = C.AES = { - - /** - * Public API - */ - - encrypt: function (message, password, options) { - - options = options || {}; - - // Determine mode - var mode = options.mode || new C.mode.OFB; - - // Allow mode to override options - if (mode.fixOptions) mode.fixOptions(options); - - var - - // Convert to bytes if message is a string - m = ( - message.constructor == String ? - UTF8.stringToBytes(message) : - message - ), - - // Generate random IV - iv = options.iv || util.randomBytes(AES._blocksize * 4), - - // Generate key - k = ( - password.constructor == String ? - // Derive key from passphrase - C.PBKDF2(password, iv, 32, { asBytes: true }) : - // else, assume byte array representing cryptographic key - password - ); - - // Encrypt - AES._init(k); - mode.encrypt(AES, m, iv); - - // Return ciphertext - m = options.iv ? m : iv.concat(m); - return (options && options.asBytes) ? m : util.bytesToBase64(m); - - }, - - decrypt: function (ciphertext, password, options) { - - options = options || {}; - - // Determine mode - var mode = options.mode || new C.mode.OFB; - - // Allow mode to override options - if (mode.fixOptions) mode.fixOptions(options); - - var - - // Convert to bytes if ciphertext is a string - c = ( - ciphertext.constructor == String ? - util.base64ToBytes(ciphertext): - ciphertext - ), - - // Separate IV and message - iv = options.iv || c.splice(0, AES._blocksize * 4), - - // Generate key - k = ( - password.constructor == String ? - // Derive key from passphrase - C.PBKDF2(password, iv, 32, { asBytes: true }) : - // else, assume byte array representing cryptographic key - password - ); - - // Decrypt - AES._init(k); - mode.decrypt(AES, c, iv); - - // Return plaintext - return (options && options.asBytes) ? c : UTF8.bytesToString(c); - - }, - - - /** - * Package private methods and properties - */ - - _blocksize: 4, - - _encryptblock: function (m, offset) { - - // Set input - for (var row = 0; row < AES._blocksize; row++) { - for (var col = 0; col < 4; col++) - state[row][col] = m[offset + col * 4 + row]; - } - - // Add round key - for (var row = 0; row < 4; row++) { - for (var col = 0; col < 4; col++) - state[row][col] ^= keyschedule[col][row]; - } - - for (var round = 1; round < nrounds; round++) { - - // Sub bytes - for (var row = 0; row < 4; row++) { - for (var col = 0; col < 4; col++) - state[row][col] = SBOX[state[row][col]]; - } - - // Shift rows - state[1].push(state[1].shift()); - state[2].push(state[2].shift()); - state[2].push(state[2].shift()); - state[3].unshift(state[3].pop()); - - // Mix columns - for (var col = 0; col < 4; col++) { - - var s0 = state[0][col], - s1 = state[1][col], - s2 = state[2][col], - s3 = state[3][col]; - - state[0][col] = MULT2[s0] ^ MULT3[s1] ^ s2 ^ s3; - state[1][col] = s0 ^ MULT2[s1] ^ MULT3[s2] ^ s3; - state[2][col] = s0 ^ s1 ^ MULT2[s2] ^ MULT3[s3]; - state[3][col] = MULT3[s0] ^ s1 ^ s2 ^ MULT2[s3]; - - } - - // Add round key - for (var row = 0; row < 4; row++) { - for (var col = 0; col < 4; col++) - state[row][col] ^= keyschedule[round * 4 + col][row]; - } - - } - - // Sub bytes - for (var row = 0; row < 4; row++) { - for (var col = 0; col < 4; col++) - state[row][col] = SBOX[state[row][col]]; - } - - // Shift rows - state[1].push(state[1].shift()); - state[2].push(state[2].shift()); - state[2].push(state[2].shift()); - state[3].unshift(state[3].pop()); - - // Add round key - for (var row = 0; row < 4; row++) { - for (var col = 0; col < 4; col++) - state[row][col] ^= keyschedule[nrounds * 4 + col][row]; - } - - // Set output - for (var row = 0; row < AES._blocksize; row++) { - for (var col = 0; col < 4; col++) - m[offset + col * 4 + row] = state[row][col]; - } - - }, - - _decryptblock: function (c, offset) { - - // Set input - for (var row = 0; row < AES._blocksize; row++) { - for (var col = 0; col < 4; col++) - state[row][col] = c[offset + col * 4 + row]; - } - - // Add round key - for (var row = 0; row < 4; row++) { - for (var col = 0; col < 4; col++) - state[row][col] ^= keyschedule[nrounds * 4 + col][row]; - } - - for (var round = 1; round < nrounds; round++) { - - // Inv shift rows - state[1].unshift(state[1].pop()); - state[2].push(state[2].shift()); - state[2].push(state[2].shift()); - state[3].push(state[3].shift()); - - // Inv sub bytes - for (var row = 0; row < 4; row++) { - for (var col = 0; col < 4; col++) - state[row][col] = INVSBOX[state[row][col]]; - } - - // Add round key - for (var row = 0; row < 4; row++) { - for (var col = 0; col < 4; col++) - state[row][col] ^= keyschedule[(nrounds - round) * 4 + col][row]; - } - - // Inv mix columns - for (var col = 0; col < 4; col++) { - - var s0 = state[0][col], - s1 = state[1][col], - s2 = state[2][col], - s3 = state[3][col]; - - state[0][col] = MULTE[s0] ^ MULTB[s1] ^ MULTD[s2] ^ MULT9[s3]; - state[1][col] = MULT9[s0] ^ MULTE[s1] ^ MULTB[s2] ^ MULTD[s3]; - state[2][col] = MULTD[s0] ^ MULT9[s1] ^ MULTE[s2] ^ MULTB[s3]; - state[3][col] = MULTB[s0] ^ MULTD[s1] ^ MULT9[s2] ^ MULTE[s3]; - - } - - } - - // Inv shift rows - state[1].unshift(state[1].pop()); - state[2].push(state[2].shift()); - state[2].push(state[2].shift()); - state[3].push(state[3].shift()); - - // Inv sub bytes - for (var row = 0; row < 4; row++) { - for (var col = 0; col < 4; col++) - state[row][col] = INVSBOX[state[row][col]]; - } - - // Add round key - for (var row = 0; row < 4; row++) { - for (var col = 0; col < 4; col++) - state[row][col] ^= keyschedule[col][row]; - } - - // Set output - for (var row = 0; row < AES._blocksize; row++) { - for (var col = 0; col < 4; col++) - c[offset + col * 4 + row] = state[row][col]; - } - - }, - - - /** - * Private methods - */ - - _init: function (k) { - keylength = k.length / 4; - nrounds = keylength + 6; - AES._keyexpansion(k); - }, - - // Generate a key schedule - _keyexpansion: function (k) { - - keyschedule = []; - - for (var row = 0; row < keylength; row++) { - keyschedule[row] = [ - k[row * 4], - k[row * 4 + 1], - k[row * 4 + 2], - k[row * 4 + 3] - ]; - } - - for (var row = keylength; row < AES._blocksize * (nrounds + 1); row++) { - - var temp = [ - keyschedule[row - 1][0], - keyschedule[row - 1][1], - keyschedule[row - 1][2], - keyschedule[row - 1][3] - ]; - - if (row % keylength == 0) { - - // Rot word - temp.push(temp.shift()); - - // Sub word - temp[0] = SBOX[temp[0]]; - temp[1] = SBOX[temp[1]]; - temp[2] = SBOX[temp[2]]; - temp[3] = SBOX[temp[3]]; - - temp[0] ^= RCON[row / keylength]; - - } else if (keylength > 6 && row % keylength == 4) { - - // Sub word - temp[0] = SBOX[temp[0]]; - temp[1] = SBOX[temp[1]]; - temp[2] = SBOX[temp[2]]; - temp[3] = SBOX[temp[3]]; - - } - - keyschedule[row] = [ - keyschedule[row - keylength][0] ^ temp[0], - keyschedule[row - keylength][1] ^ temp[1], - keyschedule[row - keylength][2] ^ temp[2], - keyschedule[row - keylength][3] ^ temp[3] - ]; - - } - - } - -}; - -})(); +/* + * Crypto-JS v2.4.0 + * http://code.google.com/p/crypto-js/ + * Copyright (c) 2011, Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ +(function(){ + +// Shortcuts +var C = Crypto, + util = C.util, + charenc = C.charenc, + UTF8 = charenc.UTF8; + +// Precomputed SBOX +var SBOX = [ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, + 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, + 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, + 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, + 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, + 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, + 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, + 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, + 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, + 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, + 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, + 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, + 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, + 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, + 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, + 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, + 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 ]; + +// Compute inverse SBOX lookup table +for (var INVSBOX = [], i = 0; i < 256; i++) INVSBOX[SBOX[i]] = i; + +// Compute mulitplication in GF(2^8) lookup tables +var MULT2 = [], + MULT3 = [], + MULT9 = [], + MULTB = [], + MULTD = [], + MULTE = []; + +function xtime(a, b) { + for (var result = 0, i = 0; i < 8; i++) { + if (b & 1) result ^= a; + var hiBitSet = a & 0x80; + a = (a << 1) & 0xFF; + if (hiBitSet) a ^= 0x1b; + b >>>= 1; + } + return result; +} + +for (var i = 0; i < 256; i++) { + MULT2[i] = xtime(i,2); + MULT3[i] = xtime(i,3); + MULT9[i] = xtime(i,9); + MULTB[i] = xtime(i,0xB); + MULTD[i] = xtime(i,0xD); + MULTE[i] = xtime(i,0xE); +} + +// Precomputed RCon lookup +var RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36]; + +// Inner state +var state = [[], [], [], []], + keylength, + nrounds, + keyschedule; + +var AES = C.AES = { + + /** + * Public API + */ + + encrypt: function (message, password, options) { + + options = options || {}; + + // Determine mode + var mode = options.mode || new C.mode.OFB; + + // Allow mode to override options + if (mode.fixOptions) mode.fixOptions(options); + + var + + // Convert to bytes if message is a string + m = ( + message.constructor == String ? + UTF8.stringToBytes(message) : + message + ), + + // Generate random IV + iv = options.iv || util.randomBytes(AES._blocksize * 4), + + // Generate key + k = ( + password.constructor == String ? + // Derive key from passphrase + C.PBKDF2(password, iv, 32, { asBytes: true }) : + // else, assume byte array representing cryptographic key + password + ); + + // Encrypt + AES._init(k); + mode.encrypt(AES, m, iv); + + // Return ciphertext + m = options.iv ? m : iv.concat(m); + return (options && options.asBytes) ? m : util.bytesToBase64(m); + + }, + + decrypt: function (ciphertext, password, options) { + + options = options || {}; + + // Determine mode + var mode = options.mode || new C.mode.OFB; + + // Allow mode to override options + if (mode.fixOptions) mode.fixOptions(options); + + var + + // Convert to bytes if ciphertext is a string + c = ( + ciphertext.constructor == String ? + util.base64ToBytes(ciphertext): + ciphertext + ), + + // Separate IV and message + iv = options.iv || c.splice(0, AES._blocksize * 4), + + // Generate key + k = ( + password.constructor == String ? + // Derive key from passphrase + C.PBKDF2(password, iv, 32, { asBytes: true }) : + // else, assume byte array representing cryptographic key + password + ); + + // Decrypt + AES._init(k); + mode.decrypt(AES, c, iv); + + // Return plaintext + return (options && options.asBytes) ? c : UTF8.bytesToString(c); + + }, + + + /** + * Package private methods and properties + */ + + _blocksize: 4, + + _encryptblock: function (m, offset) { + + // Set input + for (var row = 0; row < AES._blocksize; row++) { + for (var col = 0; col < 4; col++) + state[row][col] = m[offset + col * 4 + row]; + } + + // Add round key + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] ^= keyschedule[col][row]; + } + + for (var round = 1; round < nrounds; round++) { + + // Sub bytes + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] = SBOX[state[row][col]]; + } + + // Shift rows + state[1].push(state[1].shift()); + state[2].push(state[2].shift()); + state[2].push(state[2].shift()); + state[3].unshift(state[3].pop()); + + // Mix columns + for (var col = 0; col < 4; col++) { + + var s0 = state[0][col], + s1 = state[1][col], + s2 = state[2][col], + s3 = state[3][col]; + + state[0][col] = MULT2[s0] ^ MULT3[s1] ^ s2 ^ s3; + state[1][col] = s0 ^ MULT2[s1] ^ MULT3[s2] ^ s3; + state[2][col] = s0 ^ s1 ^ MULT2[s2] ^ MULT3[s3]; + state[3][col] = MULT3[s0] ^ s1 ^ s2 ^ MULT2[s3]; + + } + + // Add round key + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] ^= keyschedule[round * 4 + col][row]; + } + + } + + // Sub bytes + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] = SBOX[state[row][col]]; + } + + // Shift rows + state[1].push(state[1].shift()); + state[2].push(state[2].shift()); + state[2].push(state[2].shift()); + state[3].unshift(state[3].pop()); + + // Add round key + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] ^= keyschedule[nrounds * 4 + col][row]; + } + + // Set output + for (var row = 0; row < AES._blocksize; row++) { + for (var col = 0; col < 4; col++) + m[offset + col * 4 + row] = state[row][col]; + } + + }, + + _decryptblock: function (c, offset) { + + // Set input + for (var row = 0; row < AES._blocksize; row++) { + for (var col = 0; col < 4; col++) + state[row][col] = c[offset + col * 4 + row]; + } + + // Add round key + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] ^= keyschedule[nrounds * 4 + col][row]; + } + + for (var round = 1; round < nrounds; round++) { + + // Inv shift rows + state[1].unshift(state[1].pop()); + state[2].push(state[2].shift()); + state[2].push(state[2].shift()); + state[3].push(state[3].shift()); + + // Inv sub bytes + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] = INVSBOX[state[row][col]]; + } + + // Add round key + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] ^= keyschedule[(nrounds - round) * 4 + col][row]; + } + + // Inv mix columns + for (var col = 0; col < 4; col++) { + + var s0 = state[0][col], + s1 = state[1][col], + s2 = state[2][col], + s3 = state[3][col]; + + state[0][col] = MULTE[s0] ^ MULTB[s1] ^ MULTD[s2] ^ MULT9[s3]; + state[1][col] = MULT9[s0] ^ MULTE[s1] ^ MULTB[s2] ^ MULTD[s3]; + state[2][col] = MULTD[s0] ^ MULT9[s1] ^ MULTE[s2] ^ MULTB[s3]; + state[3][col] = MULTB[s0] ^ MULTD[s1] ^ MULT9[s2] ^ MULTE[s3]; + + } + + } + + // Inv shift rows + state[1].unshift(state[1].pop()); + state[2].push(state[2].shift()); + state[2].push(state[2].shift()); + state[3].push(state[3].shift()); + + // Inv sub bytes + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] = INVSBOX[state[row][col]]; + } + + // Add round key + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] ^= keyschedule[col][row]; + } + + // Set output + for (var row = 0; row < AES._blocksize; row++) { + for (var col = 0; col < 4; col++) + c[offset + col * 4 + row] = state[row][col]; + } + + }, + + + /** + * Private methods + */ + + _init: function (k) { + keylength = k.length / 4; + nrounds = keylength + 6; + AES._keyexpansion(k); + }, + + // Generate a key schedule + _keyexpansion: function (k) { + + keyschedule = []; + + for (var row = 0; row < keylength; row++) { + keyschedule[row] = [ + k[row * 4], + k[row * 4 + 1], + k[row * 4 + 2], + k[row * 4 + 3] + ]; + } + + for (var row = keylength; row < AES._blocksize * (nrounds + 1); row++) { + + var temp = [ + keyschedule[row - 1][0], + keyschedule[row - 1][1], + keyschedule[row - 1][2], + keyschedule[row - 1][3] + ]; + + if (row % keylength == 0) { + + // Rot word + temp.push(temp.shift()); + + // Sub word + temp[0] = SBOX[temp[0]]; + temp[1] = SBOX[temp[1]]; + temp[2] = SBOX[temp[2]]; + temp[3] = SBOX[temp[3]]; + + temp[0] ^= RCON[row / keylength]; + + } else if (keylength > 6 && row % keylength == 4) { + + // Sub word + temp[0] = SBOX[temp[0]]; + temp[1] = SBOX[temp[1]]; + temp[2] = SBOX[temp[2]]; + temp[3] = SBOX[temp[3]]; + + } + + keyschedule[row] = [ + keyschedule[row - keylength][0] ^ temp[0], + keyschedule[row - keylength][1] ^ temp[1], + keyschedule[row - keylength][2] ^ temp[2], + keyschedule[row - keylength][3] ^ temp[3] + ]; + + } + + } + +}; + +})(); diff --git a/tools/Crypto-JS v2.4.0/blockmodes/blockmodes-min.js b/tools/Crypto-JS v2.4.0/blockmodes/blockmodes-min.js index 1866d2e..1150c20 100755 --- a/tools/Crypto-JS v2.4.0/blockmodes/blockmodes-min.js +++ b/tools/Crypto-JS v2.4.0/blockmodes/blockmodes-min.js @@ -1,9 +1,9 @@ -/* - * Crypto-JS v2.4.0 - * http://code.google.com/p/crypto-js/ - * Copyright (c) 2011, Jeff Mott. All rights reserved. - * http://code.google.com/p/crypto-js/wiki/License - */ +/* + * Crypto-JS v2.4.0 + * http://code.google.com/p/crypto-js/ + * Copyright (c) 2011, Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ (function(h){function l(c,a){var b=c._blocksize*4;return b-a.length%b}var j=h.pad={},g=function(c){for(var a=c.pop(),b=1;b0;d--)a.push(0)},unpad:function(){}};j.iso7816={pad:function(c,a){var b=l(c,a);for(a.push(128);b>1;b--)a.push(0)},unpad:function(c){for(;c.pop()!=128;);}};j.ansix923={pad:function(c,a){for(var b=l(c,a),d=1;d0; reqd--) { - message.push(0x00); - } - } - }, - - unpad : function (message) {} -}; - -// ISO/IEC 7816-4 padding. -// -// Pads the plain text with an 0x80 byte followed by as many 0x00 -// bytes are required to complete the block. -C_pad.iso7816 = { - pad : function (cipher, message) { - var reqd = _requiredPadding(cipher, message); - message.push(0x80); - for (; reqd > 1; reqd--) { - message.push(0x00); - } - }, - - unpad : function (message) { - while (message.pop() != 0x80) {} - } -}; - -// ANSI X.923 padding -// -// The final block is padded with zeros except for the last byte of the -// last block which contains the number of padding bytes. -C_pad.ansix923 = { - pad : function (cipher, message) { - var reqd = _requiredPadding(cipher, message); - for (var i = 1; i < reqd; i++) { - message.push(0x00); - } - message.push(reqd); - }, - - unpad : _unpadLength -}; - -// ISO 10126 -// -// The final block is padded with random bytes except for the last -// byte of the last block which contains the number of padding bytes. -C_pad.iso10126 = { - pad : function (cipher, message) { - var reqd = _requiredPadding(cipher, message); - for (var i = 1; i < reqd; i++) { - message.push(Math.floor(Math.random() * 256)); - } - message.push(reqd); - }, - - unpad : _unpadLength -}; - -// PKCS7 padding -// -// PKCS7 is described in RFC 5652. Padding is in whole bytes. The -// value of each added byte is the number of bytes that are added, -// i.e. N bytes, each of value N are added. -C_pad.pkcs7 = { - pad : function (cipher, message) { - var reqd = _requiredPadding(cipher, message); - for (var i = 0; i < reqd; i++) { - message.push(reqd); - } - }, - - unpad : _unpadLength -}; - -// Create mode namespace -var C_mode = C.mode = {}; - -/** - * Mode base "class". - */ -var Mode = C_mode.Mode = function (padding) { - if (padding) { - this._padding = padding; - } -}; - -Mode.prototype = { - encrypt: function (cipher, m, iv) { - this._padding.pad(cipher, m); - this._doEncrypt(cipher, m, iv); - }, - - decrypt: function (cipher, m, iv) { - this._doDecrypt(cipher, m, iv); - this._padding.unpad(m); - }, - - // Default padding - _padding: C_pad.iso7816 -}; - - -/** - * Electronic Code Book mode. - * - * ECB applies the cipher directly against each block of the input. - * - * ECB does not require an initialization vector. - */ -var ECB = C_mode.ECB = function () { - // Call parent constructor - Mode.apply(this, arguments); -}; - -// Inherit from Mode -var ECB_prototype = ECB.prototype = new Mode; - -// Concrete steps for Mode template -ECB_prototype._doEncrypt = function (cipher, m, iv) { - var blockSizeInBytes = cipher._blocksize * 4; - // Encrypt each block - for (var offset = 0; offset < m.length; offset += blockSizeInBytes) { - cipher._encryptblock(m, offset); - } -}; -ECB_prototype._doDecrypt = function (cipher, c, iv) { - var blockSizeInBytes = cipher._blocksize * 4; - // Decrypt each block - for (var offset = 0; offset < c.length; offset += blockSizeInBytes) { - cipher._decryptblock(c, offset); - } -}; - -// ECB never uses an IV -ECB_prototype.fixOptions = function (options) { - options.iv = []; -}; - - -/** - * Cipher block chaining - * - * The first block is XORed with the IV. Subsequent blocks are XOR with the - * previous cipher output. - */ -var CBC = C_mode.CBC = function () { - // Call parent constructor - Mode.apply(this, arguments); -}; - -// Inherit from Mode -var CBC_prototype = CBC.prototype = new Mode; - -// Concrete steps for Mode template -CBC_prototype._doEncrypt = function (cipher, m, iv) { - var blockSizeInBytes = cipher._blocksize * 4; - - // Encrypt each block - for (var offset = 0; offset < m.length; offset += blockSizeInBytes) { - if (offset == 0) { - // XOR first block using IV - for (var i = 0; i < blockSizeInBytes; i++) - m[i] ^= iv[i]; - } else { - // XOR this block using previous crypted block - for (var i = 0; i < blockSizeInBytes; i++) - m[offset + i] ^= m[offset + i - blockSizeInBytes]; - } - // Encrypt block - cipher._encryptblock(m, offset); - } -}; -CBC_prototype._doDecrypt = function (cipher, c, iv) { - var blockSizeInBytes = cipher._blocksize * 4; - - // At the start, the previously crypted block is the IV - var prevCryptedBlock = iv; - - // Decrypt each block - for (var offset = 0; offset < c.length; offset += blockSizeInBytes) { - // Save this crypted block - var thisCryptedBlock = c.slice(offset, offset + blockSizeInBytes); - // Decrypt block - cipher._decryptblock(c, offset); - // XOR decrypted block using previous crypted block - for (var i = 0; i < blockSizeInBytes; i++) { - c[offset + i] ^= prevCryptedBlock[i]; - } - prevCryptedBlock = thisCryptedBlock; - } -}; - - -/** - * Cipher feed back - * - * The cipher output is XORed with the plain text to produce the cipher output, - * which is then fed back into the cipher to produce a bit pattern to XOR the - * next block with. - * - * This is a stream cipher mode and does not require padding. - */ -var CFB = C_mode.CFB = function () { - // Call parent constructor - Mode.apply(this, arguments); -}; - -// Inherit from Mode -var CFB_prototype = CFB.prototype = new Mode; - -// Override padding -CFB_prototype._padding = C_pad.NoPadding; - -// Concrete steps for Mode template -CFB_prototype._doEncrypt = function (cipher, m, iv) { - var blockSizeInBytes = cipher._blocksize * 4, - keystream = iv.slice(0); - - // Encrypt each byte - for (var i = 0; i < m.length; i++) { - - var j = i % blockSizeInBytes; - if (j == 0) cipher._encryptblock(keystream, 0); - - m[i] ^= keystream[j]; - keystream[j] = m[i]; - } -}; -CFB_prototype._doDecrypt = function (cipher, c, iv) { - var blockSizeInBytes = cipher._blocksize * 4, - keystream = iv.slice(0); - - // Encrypt each byte - for (var i = 0; i < c.length; i++) { - - var j = i % blockSizeInBytes; - if (j == 0) cipher._encryptblock(keystream, 0); - - var b = c[i]; - c[i] ^= keystream[j]; - keystream[j] = b; - } -}; - - -/** - * Output feed back - * - * The cipher repeatedly encrypts its own output. The output is XORed with the - * plain text to produce the cipher text. - * - * This is a stream cipher mode and does not require padding. - */ -var OFB = C_mode.OFB = function () { - // Call parent constructor - Mode.apply(this, arguments); -}; - -// Inherit from Mode -var OFB_prototype = OFB.prototype = new Mode; - -// Override padding -OFB_prototype._padding = C_pad.NoPadding; - -// Concrete steps for Mode template -OFB_prototype._doEncrypt = function (cipher, m, iv) { - - var blockSizeInBytes = cipher._blocksize * 4, - keystream = iv.slice(0); - - // Encrypt each byte - for (var i = 0; i < m.length; i++) { - - // Generate keystream - if (i % blockSizeInBytes == 0) - cipher._encryptblock(keystream, 0); - - // Encrypt byte - m[i] ^= keystream[i % blockSizeInBytes]; - - } -}; -OFB_prototype._doDecrypt = OFB_prototype._doEncrypt; - -/** - * Counter - * @author Gergely Risko - * - * After every block the last 4 bytes of the IV is increased by one - * with carry and that IV is used for the next block. - * - * This is a stream cipher mode and does not require padding. - */ -var CTR = C_mode.CTR = function () { - // Call parent constructor - Mode.apply(this, arguments); -}; - -// Inherit from Mode -var CTR_prototype = CTR.prototype = new Mode; - -// Override padding -CTR_prototype._padding = C_pad.NoPadding; - -CTR_prototype._doEncrypt = function (cipher, m, iv) { - var blockSizeInBytes = cipher._blocksize * 4; - - for (var i = 0; i < m.length;) { - // do not lose iv - var keystream = iv.slice(0); - - // Generate keystream for next block - cipher._encryptblock(keystream, 0); - - // XOR keystream with block - for (var j = 0; i < m.length && j < blockSizeInBytes; j++, i++) { - m[i] ^= keystream[j]; - } - - // Increase IV - if(++(iv[blockSizeInBytes-1]) == 256) { - iv[blockSizeInBytes-1] = 0; - if(++(iv[blockSizeInBytes-2]) == 256) { - iv[blockSizeInBytes-2] = 0; - if(++(iv[blockSizeInBytes-3]) == 256) { - iv[blockSizeInBytes-3] = 0; - ++(iv[blockSizeInBytes-4]); - } - } - } - } -}; -CTR_prototype._doDecrypt = CTR_prototype._doEncrypt; - -})(Crypto); +/* + * Crypto-JS v2.4.0 + * http://code.google.com/p/crypto-js/ + * Copyright (c) 2011, Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ +/*! + * Crypto-JS contribution from Simon Greatrix + */ + +(function(C){ + +// Create pad namespace +var C_pad = C.pad = {}; + +// Calculate the number of padding bytes required. +function _requiredPadding(cipher, message) { + var blockSizeInBytes = cipher._blocksize * 4; + var reqd = blockSizeInBytes - message.length % blockSizeInBytes; + return reqd; +}; + +// Remove padding when the final byte gives the number of padding bytes. +var _unpadLength = function (message) { + var pad = message.pop(); + for (var i = 1; i < pad; i++) { + message.pop(); + } + }; + +// No-operation padding, used for stream ciphers +C_pad.NoPadding = { + pad : function (cipher,message) {}, + unpad : function (message) {} + }; + +// Zero Padding. +// +// If the message is not an exact number of blocks, the final block is +// completed with 0x00 bytes. There is no unpadding. +C_pad.ZeroPadding = { + pad : function (cipher, message) { + var blockSizeInBytes = cipher._blocksize * 4; + var reqd = message.length % blockSizeInBytes; + if( reqd!=0 ) { + for(reqd = blockSizeInBytes - reqd; reqd>0; reqd--) { + message.push(0x00); + } + } + }, + + unpad : function (message) {} +}; + +// ISO/IEC 7816-4 padding. +// +// Pads the plain text with an 0x80 byte followed by as many 0x00 +// bytes are required to complete the block. +C_pad.iso7816 = { + pad : function (cipher, message) { + var reqd = _requiredPadding(cipher, message); + message.push(0x80); + for (; reqd > 1; reqd--) { + message.push(0x00); + } + }, + + unpad : function (message) { + while (message.pop() != 0x80) {} + } +}; + +// ANSI X.923 padding +// +// The final block is padded with zeros except for the last byte of the +// last block which contains the number of padding bytes. +C_pad.ansix923 = { + pad : function (cipher, message) { + var reqd = _requiredPadding(cipher, message); + for (var i = 1; i < reqd; i++) { + message.push(0x00); + } + message.push(reqd); + }, + + unpad : _unpadLength +}; + +// ISO 10126 +// +// The final block is padded with random bytes except for the last +// byte of the last block which contains the number of padding bytes. +C_pad.iso10126 = { + pad : function (cipher, message) { + var reqd = _requiredPadding(cipher, message); + for (var i = 1; i < reqd; i++) { + message.push(Math.floor(Math.random() * 256)); + } + message.push(reqd); + }, + + unpad : _unpadLength +}; + +// PKCS7 padding +// +// PKCS7 is described in RFC 5652. Padding is in whole bytes. The +// value of each added byte is the number of bytes that are added, +// i.e. N bytes, each of value N are added. +C_pad.pkcs7 = { + pad : function (cipher, message) { + var reqd = _requiredPadding(cipher, message); + for (var i = 0; i < reqd; i++) { + message.push(reqd); + } + }, + + unpad : _unpadLength +}; + +// Create mode namespace +var C_mode = C.mode = {}; + +/** + * Mode base "class". + */ +var Mode = C_mode.Mode = function (padding) { + if (padding) { + this._padding = padding; + } +}; + +Mode.prototype = { + encrypt: function (cipher, m, iv) { + this._padding.pad(cipher, m); + this._doEncrypt(cipher, m, iv); + }, + + decrypt: function (cipher, m, iv) { + this._doDecrypt(cipher, m, iv); + this._padding.unpad(m); + }, + + // Default padding + _padding: C_pad.iso7816 +}; + + +/** + * Electronic Code Book mode. + * + * ECB applies the cipher directly against each block of the input. + * + * ECB does not require an initialization vector. + */ +var ECB = C_mode.ECB = function () { + // Call parent constructor + Mode.apply(this, arguments); +}; + +// Inherit from Mode +var ECB_prototype = ECB.prototype = new Mode; + +// Concrete steps for Mode template +ECB_prototype._doEncrypt = function (cipher, m, iv) { + var blockSizeInBytes = cipher._blocksize * 4; + // Encrypt each block + for (var offset = 0; offset < m.length; offset += blockSizeInBytes) { + cipher._encryptblock(m, offset); + } +}; +ECB_prototype._doDecrypt = function (cipher, c, iv) { + var blockSizeInBytes = cipher._blocksize * 4; + // Decrypt each block + for (var offset = 0; offset < c.length; offset += blockSizeInBytes) { + cipher._decryptblock(c, offset); + } +}; + +// ECB never uses an IV +ECB_prototype.fixOptions = function (options) { + options.iv = []; +}; + + +/** + * Cipher block chaining + * + * The first block is XORed with the IV. Subsequent blocks are XOR with the + * previous cipher output. + */ +var CBC = C_mode.CBC = function () { + // Call parent constructor + Mode.apply(this, arguments); +}; + +// Inherit from Mode +var CBC_prototype = CBC.prototype = new Mode; + +// Concrete steps for Mode template +CBC_prototype._doEncrypt = function (cipher, m, iv) { + var blockSizeInBytes = cipher._blocksize * 4; + + // Encrypt each block + for (var offset = 0; offset < m.length; offset += blockSizeInBytes) { + if (offset == 0) { + // XOR first block using IV + for (var i = 0; i < blockSizeInBytes; i++) + m[i] ^= iv[i]; + } else { + // XOR this block using previous crypted block + for (var i = 0; i < blockSizeInBytes; i++) + m[offset + i] ^= m[offset + i - blockSizeInBytes]; + } + // Encrypt block + cipher._encryptblock(m, offset); + } +}; +CBC_prototype._doDecrypt = function (cipher, c, iv) { + var blockSizeInBytes = cipher._blocksize * 4; + + // At the start, the previously crypted block is the IV + var prevCryptedBlock = iv; + + // Decrypt each block + for (var offset = 0; offset < c.length; offset += blockSizeInBytes) { + // Save this crypted block + var thisCryptedBlock = c.slice(offset, offset + blockSizeInBytes); + // Decrypt block + cipher._decryptblock(c, offset); + // XOR decrypted block using previous crypted block + for (var i = 0; i < blockSizeInBytes; i++) { + c[offset + i] ^= prevCryptedBlock[i]; + } + prevCryptedBlock = thisCryptedBlock; + } +}; + + +/** + * Cipher feed back + * + * The cipher output is XORed with the plain text to produce the cipher output, + * which is then fed back into the cipher to produce a bit pattern to XOR the + * next block with. + * + * This is a stream cipher mode and does not require padding. + */ +var CFB = C_mode.CFB = function () { + // Call parent constructor + Mode.apply(this, arguments); +}; + +// Inherit from Mode +var CFB_prototype = CFB.prototype = new Mode; + +// Override padding +CFB_prototype._padding = C_pad.NoPadding; + +// Concrete steps for Mode template +CFB_prototype._doEncrypt = function (cipher, m, iv) { + var blockSizeInBytes = cipher._blocksize * 4, + keystream = iv.slice(0); + + // Encrypt each byte + for (var i = 0; i < m.length; i++) { + + var j = i % blockSizeInBytes; + if (j == 0) cipher._encryptblock(keystream, 0); + + m[i] ^= keystream[j]; + keystream[j] = m[i]; + } +}; +CFB_prototype._doDecrypt = function (cipher, c, iv) { + var blockSizeInBytes = cipher._blocksize * 4, + keystream = iv.slice(0); + + // Encrypt each byte + for (var i = 0; i < c.length; i++) { + + var j = i % blockSizeInBytes; + if (j == 0) cipher._encryptblock(keystream, 0); + + var b = c[i]; + c[i] ^= keystream[j]; + keystream[j] = b; + } +}; + + +/** + * Output feed back + * + * The cipher repeatedly encrypts its own output. The output is XORed with the + * plain text to produce the cipher text. + * + * This is a stream cipher mode and does not require padding. + */ +var OFB = C_mode.OFB = function () { + // Call parent constructor + Mode.apply(this, arguments); +}; + +// Inherit from Mode +var OFB_prototype = OFB.prototype = new Mode; + +// Override padding +OFB_prototype._padding = C_pad.NoPadding; + +// Concrete steps for Mode template +OFB_prototype._doEncrypt = function (cipher, m, iv) { + + var blockSizeInBytes = cipher._blocksize * 4, + keystream = iv.slice(0); + + // Encrypt each byte + for (var i = 0; i < m.length; i++) { + + // Generate keystream + if (i % blockSizeInBytes == 0) + cipher._encryptblock(keystream, 0); + + // Encrypt byte + m[i] ^= keystream[i % blockSizeInBytes]; + + } +}; +OFB_prototype._doDecrypt = OFB_prototype._doEncrypt; + +/** + * Counter + * @author Gergely Risko + * + * After every block the last 4 bytes of the IV is increased by one + * with carry and that IV is used for the next block. + * + * This is a stream cipher mode and does not require padding. + */ +var CTR = C_mode.CTR = function () { + // Call parent constructor + Mode.apply(this, arguments); +}; + +// Inherit from Mode +var CTR_prototype = CTR.prototype = new Mode; + +// Override padding +CTR_prototype._padding = C_pad.NoPadding; + +CTR_prototype._doEncrypt = function (cipher, m, iv) { + var blockSizeInBytes = cipher._blocksize * 4; + + for (var i = 0; i < m.length;) { + // do not lose iv + var keystream = iv.slice(0); + + // Generate keystream for next block + cipher._encryptblock(keystream, 0); + + // XOR keystream with block + for (var j = 0; i < m.length && j < blockSizeInBytes; j++, i++) { + m[i] ^= keystream[j]; + } + + // Increase IV + if(++(iv[blockSizeInBytes-1]) == 256) { + iv[blockSizeInBytes-1] = 0; + if(++(iv[blockSizeInBytes-2]) == 256) { + iv[blockSizeInBytes-2] = 0; + if(++(iv[blockSizeInBytes-3]) == 256) { + iv[blockSizeInBytes-3] = 0; + ++(iv[blockSizeInBytes-4]); + } + } + } + } +}; +CTR_prototype._doDecrypt = CTR_prototype._doEncrypt; + +})(Crypto); diff --git a/tools/Crypto-JS v2.4.0/crypto-md5-hmac/crypto-md5-hmac.js b/tools/Crypto-JS v2.4.0/crypto-md5-hmac/crypto-md5-hmac.js index 71ebcf2..c87094f 100755 --- a/tools/Crypto-JS v2.4.0/crypto-md5-hmac/crypto-md5-hmac.js +++ b/tools/Crypto-JS v2.4.0/crypto-md5-hmac/crypto-md5-hmac.js @@ -1,9 +1,9 @@ -/* - * Crypto-JS v2.4.0 - * http://code.google.com/p/crypto-js/ - * Copyright (c) 2011, Jeff Mott. All rights reserved. - * http://code.google.com/p/crypto-js/wiki/License - */ +/* + * Crypto-JS v2.4.0 + * http://code.google.com/p/crypto-js/ + * Copyright (c) 2011, Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ if(typeof Crypto=="undefined"||!Crypto.util)(function(){var n=window.Crypto={},o=n.util={rotl:function(h,i){return h<>>32-i},rotr:function(h,i){return h<<32-i|h>>>i},endian:function(h){if(h.constructor==Number)return o.rotl(h,8)&16711935|o.rotl(h,24)&4278255360;for(var i=0;i0;h--)i.push(Math.floor(Math.random()*256));return i},bytesToWords:function(h){for(var i=[],g=0,a=0;g>>5]|=h[g]<<24- a%32;return i},wordsToBytes:function(h){for(var i=[],g=0;g>>5]>>>24-g%32&255);return i},bytesToHex:function(h){for(var i=[],g=0;g>>4).toString(16));i.push((h[g]&15).toString(16))}return i.join("")},hexToBytes:function(h){for(var i=[],g=0;g>>6*(3-b)&63)):i.push("=");return i.join("")},base64ToBytes:function(h){if(typeof atob=="function")return p.stringToBytes(atob(h));h=h.replace(/[^A-Z0-9+\/]/ig,"");for(var i=[],g=0,a=0;g>> diff --git a/tools/Crypto-JS v2.4.0/crypto-md5/crypto-md5.js b/tools/Crypto-JS v2.4.0/crypto-md5/crypto-md5.js index f964a50..1d00820 100755 --- a/tools/Crypto-JS v2.4.0/crypto-md5/crypto-md5.js +++ b/tools/Crypto-JS v2.4.0/crypto-md5/crypto-md5.js @@ -1,9 +1,9 @@ -/* - * Crypto-JS v2.4.0 - * http://code.google.com/p/crypto-js/ - * Copyright (c) 2011, Jeff Mott. All rights reserved. - * http://code.google.com/p/crypto-js/wiki/License - */ +/* + * Crypto-JS v2.4.0 + * http://code.google.com/p/crypto-js/ + * Copyright (c) 2011, Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ if(typeof Crypto=="undefined"||!Crypto.util)(function(){var n=window.Crypto={},o=n.util={rotl:function(g,i){return g<>>32-i},rotr:function(g,i){return g<<32-i|g>>>i},endian:function(g){if(g.constructor==Number)return o.rotl(g,8)&16711935|o.rotl(g,24)&4278255360;for(var i=0;i0;g--)i.push(Math.floor(Math.random()*256));return i},bytesToWords:function(g){for(var i=[],h=0,a=0;h>>5]|=g[h]<<24- a%32;return i},wordsToBytes:function(g){for(var i=[],h=0;h>>5]>>>24-h%32&255);return i},bytesToHex:function(g){for(var i=[],h=0;h>>4).toString(16));i.push((g[h]&15).toString(16))}return i.join("")},hexToBytes:function(g){for(var i=[],h=0;h>>6*(3-b)&63)):i.push("=");return i.join("")},base64ToBytes:function(g){if(typeof atob=="function")return p.stringToBytes(atob(g));g=g.replace(/[^A-Z0-9+\/]/ig,"");for(var i=[],h=0,a=0;h>> diff --git a/tools/Crypto-JS v2.4.0/crypto-sha1-hmac-pbkdf2-blockmodes-aes/crypto-sha1-hmac-pbkdf2-blockmodes-aes.js b/tools/Crypto-JS v2.4.0/crypto-sha1-hmac-pbkdf2-blockmodes-aes/crypto-sha1-hmac-pbkdf2-blockmodes-aes.js index 608a7ad..4287cea 100755 --- a/tools/Crypto-JS v2.4.0/crypto-sha1-hmac-pbkdf2-blockmodes-aes/crypto-sha1-hmac-pbkdf2-blockmodes-aes.js +++ b/tools/Crypto-JS v2.4.0/crypto-sha1-hmac-pbkdf2-blockmodes-aes/crypto-sha1-hmac-pbkdf2-blockmodes-aes.js @@ -1,9 +1,9 @@ -/* - * Crypto-JS v2.4.0 - * http://code.google.com/p/crypto-js/ - * Copyright (c) 2011, Jeff Mott. All rights reserved. - * http://code.google.com/p/crypto-js/wiki/License - */ +/* + * Crypto-JS v2.4.0 + * http://code.google.com/p/crypto-js/ + * Copyright (c) 2011, Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ if(typeof Crypto=="undefined"||!Crypto.util)(function(){var n=window.Crypto={},q=n.util={rotl:function(f,j){return f<>>32-j},rotr:function(f,j){return f<<32-j|f>>>j},endian:function(f){if(f.constructor==Number)return q.rotl(f,8)&16711935|q.rotl(f,24)&4278255360;for(var j=0;j0;f--)j.push(Math.floor(Math.random()*256));return j},bytesToWords:function(f){for(var j=[],b=0,a=0;b>>5]|=f[b]<<24- a%32;return j},wordsToBytes:function(f){for(var j=[],b=0;b>>5]>>>24-b%32&255);return j},bytesToHex:function(f){for(var j=[],b=0;b>>4).toString(16));j.push((f[b]&15).toString(16))}return j.join("")},hexToBytes:function(f){for(var j=[],b=0;b>>6*(3-e)&63)):j.push("=");return j.join("")},base64ToBytes:function(f){if(typeof atob=="function")return p.stringToBytes(atob(f));f=f.replace(/[^A-Z0-9+\/]/ig,"");for(var j=[],b=0,a=0;b>> diff --git a/tools/Crypto-JS v2.4.0/crypto-sha1-hmac-pbkdf2-marc4/crypto-sha1-hmac-pbkdf2-marc4.js b/tools/Crypto-JS v2.4.0/crypto-sha1-hmac-pbkdf2-marc4/crypto-sha1-hmac-pbkdf2-marc4.js index 650d03f..7006067 100755 --- a/tools/Crypto-JS v2.4.0/crypto-sha1-hmac-pbkdf2-marc4/crypto-sha1-hmac-pbkdf2-marc4.js +++ b/tools/Crypto-JS v2.4.0/crypto-sha1-hmac-pbkdf2-marc4/crypto-sha1-hmac-pbkdf2-marc4.js @@ -1,9 +1,9 @@ -/* - * Crypto-JS v2.4.0 - * http://code.google.com/p/crypto-js/ - * Copyright (c) 2011, Jeff Mott. All rights reserved. - * http://code.google.com/p/crypto-js/wiki/License - */ +/* + * Crypto-JS v2.4.0 + * http://code.google.com/p/crypto-js/ + * Copyright (c) 2011, Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ if(typeof Crypto=="undefined"||!Crypto.util)(function(){var h=window.Crypto={},k=h.util={rotl:function(b,d){return b<>>32-d},rotr:function(b,d){return b<<32-d|b>>>d},endian:function(b){if(b.constructor==Number)return k.rotl(b,8)&16711935|k.rotl(b,24)&4278255360;for(var d=0;d0;b--)d.push(Math.floor(Math.random()*256));return d},bytesToWords:function(b){for(var d=[],a=0,e=0;a>>5]|=b[a]<<24- e%32;return d},wordsToBytes:function(b){for(var d=[],a=0;a>>5]>>>24-a%32&255);return d},bytesToHex:function(b){for(var d=[],a=0;a>>4).toString(16));d.push((b[a]&15).toString(16))}return d.join("")},hexToBytes:function(b){for(var d=[],a=0;a>>6*(3-c)&63)):d.push("=");return d.join("")},base64ToBytes:function(b){if(typeof atob=="function")return l.stringToBytes(atob(b));b=b.replace(/[^A-Z0-9+\/]/ig,"");for(var d=[],a=0,e=0;a>> diff --git a/tools/Crypto-JS v2.4.0/crypto-sha1-hmac-pbkdf2-rabbit/crypto-sha1-hmac-pbkdf2-rabbit.js b/tools/Crypto-JS v2.4.0/crypto-sha1-hmac-pbkdf2-rabbit/crypto-sha1-hmac-pbkdf2-rabbit.js index 88d5aae..651dc5e 100755 --- a/tools/Crypto-JS v2.4.0/crypto-sha1-hmac-pbkdf2-rabbit/crypto-sha1-hmac-pbkdf2-rabbit.js +++ b/tools/Crypto-JS v2.4.0/crypto-sha1-hmac-pbkdf2-rabbit/crypto-sha1-hmac-pbkdf2-rabbit.js @@ -1,9 +1,9 @@ -/* - * Crypto-JS v2.4.0 - * http://code.google.com/p/crypto-js/ - * Copyright (c) 2011, Jeff Mott. All rights reserved. - * http://code.google.com/p/crypto-js/wiki/License - */ +/* + * Crypto-JS v2.4.0 + * http://code.google.com/p/crypto-js/ + * Copyright (c) 2011, Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ if(typeof Crypto=="undefined"||!Crypto.util)(function(){var i=window.Crypto={},j=i.util={rotl:function(b,c){return b<>>32-c},rotr:function(b,c){return b<<32-c|b>>>c},endian:function(b){if(b.constructor==Number)return j.rotl(b,8)&16711935|j.rotl(b,24)&4278255360;for(var c=0;c0;b--)c.push(Math.floor(Math.random()*256));return c},bytesToWords:function(b){for(var c=[],e=0,g=0;e>>5]|=b[e]<<24- g%32;return c},wordsToBytes:function(b){for(var c=[],e=0;e>>5]>>>24-e%32&255);return c},bytesToHex:function(b){for(var c=[],e=0;e>>4).toString(16));c.push((b[e]&15).toString(16))}return c.join("")},hexToBytes:function(b){for(var c=[],e=0;e>>6*(3-a)&63)):c.push("=");return c.join("")},base64ToBytes:function(b){if(typeof atob=="function")return m.stringToBytes(atob(b));b=b.replace(/[^A-Z0-9+\/]/ig,"");for(var c=[],e=0,g=0;e>> diff --git a/tools/Crypto-JS v2.4.0/crypto-sha1-hmac-pbkdf2/crypto-sha1-hmac-pbkdf2.js b/tools/Crypto-JS v2.4.0/crypto-sha1-hmac-pbkdf2/crypto-sha1-hmac-pbkdf2.js index 58c00ec..dcc018b 100755 --- a/tools/Crypto-JS v2.4.0/crypto-sha1-hmac-pbkdf2/crypto-sha1-hmac-pbkdf2.js +++ b/tools/Crypto-JS v2.4.0/crypto-sha1-hmac-pbkdf2/crypto-sha1-hmac-pbkdf2.js @@ -1,9 +1,9 @@ -/* - * Crypto-JS v2.4.0 - * http://code.google.com/p/crypto-js/ - * Copyright (c) 2011, Jeff Mott. All rights reserved. - * http://code.google.com/p/crypto-js/wiki/License - */ +/* + * Crypto-JS v2.4.0 + * http://code.google.com/p/crypto-js/ + * Copyright (c) 2011, Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ if(typeof Crypto=="undefined"||!Crypto.util)(function(){var g=window.Crypto={},m=g.util={rotl:function(a,c){return a<>>32-c},rotr:function(a,c){return a<<32-c|a>>>c},endian:function(a){if(a.constructor==Number)return m.rotl(a,8)&16711935|m.rotl(a,24)&4278255360;for(var c=0;c0;a--)c.push(Math.floor(Math.random()*256));return c},bytesToWords:function(a){for(var c=[],b=0,d=0;b>>5]|=a[b]<<24- d%32;return c},wordsToBytes:function(a){for(var c=[],b=0;b>>5]>>>24-b%32&255);return c},bytesToHex:function(a){for(var c=[],b=0;b>>4).toString(16));c.push((a[b]&15).toString(16))}return c.join("")},hexToBytes:function(a){for(var c=[],b=0;b>>6*(3-e)&63)):c.push("=");return c.join("")},base64ToBytes:function(a){if(typeof atob=="function")return k.stringToBytes(atob(a));a=a.replace(/[^A-Z0-9+\/]/ig,"");for(var c=[],b=0,d=0;b>> diff --git a/tools/Crypto-JS v2.4.0/crypto-sha1-hmac-pbkdf2async/crypto-sha1-hmac-pbkdf2async.js b/tools/Crypto-JS v2.4.0/crypto-sha1-hmac-pbkdf2async/crypto-sha1-hmac-pbkdf2async.js index 8d416b0..397a848 100755 --- a/tools/Crypto-JS v2.4.0/crypto-sha1-hmac-pbkdf2async/crypto-sha1-hmac-pbkdf2async.js +++ b/tools/Crypto-JS v2.4.0/crypto-sha1-hmac-pbkdf2async/crypto-sha1-hmac-pbkdf2async.js @@ -1,9 +1,9 @@ -/* - * Crypto-JS v2.4.0 - * http://code.google.com/p/crypto-js/ - * Copyright (c) 2011, Jeff Mott. All rights reserved. - * http://code.google.com/p/crypto-js/wiki/License - */ +/* + * Crypto-JS v2.4.0 + * http://code.google.com/p/crypto-js/ + * Copyright (c) 2011, Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ if(typeof Crypto=="undefined"||!Crypto.util)(function(){var f=window.Crypto={},n=f.util={rotl:function(a,c){return a<>>32-c},rotr:function(a,c){return a<<32-c|a>>>c},endian:function(a){if(a.constructor==Number)return n.rotl(a,8)&16711935|n.rotl(a,24)&4278255360;for(var c=0;c0;a--)c.push(Math.floor(Math.random()*256));return c},bytesToWords:function(a){for(var c=[],b=0,d=0;b>>5]|=a[b]<<24- d%32;return c},wordsToBytes:function(a){for(var c=[],b=0;b>>5]>>>24-b%32&255);return c},bytesToHex:function(a){for(var c=[],b=0;b>>4).toString(16));c.push((a[b]&15).toString(16))}return c.join("")},hexToBytes:function(a){for(var c=[],b=0;b>>6*(3-e)&63)):c.push("=");return c.join("")},base64ToBytes:function(a){if(typeof atob=="function")return l.stringToBytes(atob(a));a=a.replace(/[^A-Z0-9+\/]/ig,"");for(var c=[],b=0,d=0;b>> diff --git a/tools/Crypto-JS v2.4.0/crypto-sha1-hmac/crypto-sha1-hmac.js b/tools/Crypto-JS v2.4.0/crypto-sha1-hmac/crypto-sha1-hmac.js index 6a5a49c..094a430 100755 --- a/tools/Crypto-JS v2.4.0/crypto-sha1-hmac/crypto-sha1-hmac.js +++ b/tools/Crypto-JS v2.4.0/crypto-sha1-hmac/crypto-sha1-hmac.js @@ -1,9 +1,9 @@ -/* - * Crypto-JS v2.4.0 - * http://code.google.com/p/crypto-js/ - * Copyright (c) 2011, Jeff Mott. All rights reserved. - * http://code.google.com/p/crypto-js/wiki/License - */ +/* + * Crypto-JS v2.4.0 + * http://code.google.com/p/crypto-js/ + * Copyright (c) 2011, Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ if(typeof Crypto=="undefined"||!Crypto.util)(function(){var i=window.Crypto={},n=i.util={rotl:function(a,c){return a<>>32-c},rotr:function(a,c){return a<<32-c|a>>>c},endian:function(a){if(a.constructor==Number)return n.rotl(a,8)&16711935|n.rotl(a,24)&4278255360;for(var c=0;c0;a--)c.push(Math.floor(Math.random()*256));return c},bytesToWords:function(a){for(var c=[],b=0,d=0;b>>5]|=a[b]<<24- d%32;return c},wordsToBytes:function(a){for(var c=[],b=0;b>>5]>>>24-b%32&255);return c},bytesToHex:function(a){for(var c=[],b=0;b>>4).toString(16));c.push((a[b]&15).toString(16))}return c.join("")},hexToBytes:function(a){for(var c=[],b=0;b>>6*(3-e)&63)):c.push("=");return c.join("")},base64ToBytes:function(a){if(typeof atob=="function")return j.stringToBytes(atob(a));a=a.replace(/[^A-Z0-9+\/]/ig,"");for(var c=[],b=0,d=0;b>> diff --git a/tools/Crypto-JS v2.4.0/crypto-sha1/crypto-sha1.js b/tools/Crypto-JS v2.4.0/crypto-sha1/crypto-sha1.js index 7a99356..52ed1c1 100755 --- a/tools/Crypto-JS v2.4.0/crypto-sha1/crypto-sha1.js +++ b/tools/Crypto-JS v2.4.0/crypto-sha1/crypto-sha1.js @@ -1,9 +1,9 @@ -/* - * Crypto-JS v2.4.0 - * http://code.google.com/p/crypto-js/ - * Copyright (c) 2011, Jeff Mott. All rights reserved. - * http://code.google.com/p/crypto-js/wiki/License - */ +/* + * Crypto-JS v2.4.0 + * http://code.google.com/p/crypto-js/ + * Copyright (c) 2011, Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ if(typeof Crypto=="undefined"||!Crypto.util)(function(){var k=window.Crypto={},l=k.util={rotl:function(a,c){return a<>>32-c},rotr:function(a,c){return a<<32-c|a>>>c},endian:function(a){if(a.constructor==Number)return l.rotl(a,8)&16711935|l.rotl(a,24)&4278255360;for(var c=0;c0;a--)c.push(Math.floor(Math.random()*256));return c},bytesToWords:function(a){for(var c=[],b=0,d=0;b>>5]|=a[b]<<24- d%32;return c},wordsToBytes:function(a){for(var c=[],b=0;b>>5]>>>24-b%32&255);return c},bytesToHex:function(a){for(var c=[],b=0;b>>4).toString(16));c.push((a[b]&15).toString(16))}return c.join("")},hexToBytes:function(a){for(var c=[],b=0;b>>6*(3-e)&63)):c.push("=");return c.join("")},base64ToBytes:function(a){if(typeof atob=="function")return m.stringToBytes(atob(a));a=a.replace(/[^A-Z0-9+\/]/ig,"");for(var c=[],b=0,d=0;b>> diff --git a/tools/Crypto-JS v2.4.0/crypto-sha256-hmac/crypto-sha256-hmac.js b/tools/Crypto-JS v2.4.0/crypto-sha256-hmac/crypto-sha256-hmac.js index fefdcfb..73aaa61 100755 --- a/tools/Crypto-JS v2.4.0/crypto-sha256-hmac/crypto-sha256-hmac.js +++ b/tools/Crypto-JS v2.4.0/crypto-sha256-hmac/crypto-sha256-hmac.js @@ -1,9 +1,9 @@ -/* - * Crypto-JS v2.4.0 - * http://code.google.com/p/crypto-js/ - * Copyright (c) 2011, Jeff Mott. All rights reserved. - * http://code.google.com/p/crypto-js/wiki/License - */ +/* + * Crypto-JS v2.4.0 + * http://code.google.com/p/crypto-js/ + * Copyright (c) 2011, Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ if(typeof Crypto=="undefined"||!Crypto.util)(function(){var h=window.Crypto={},n=h.util={rotl:function(a,c){return a<>>32-c},rotr:function(a,c){return a<<32-c|a>>>c},endian:function(a){if(a.constructor==Number)return n.rotl(a,8)&16711935|n.rotl(a,24)&4278255360;for(var c=0;c0;a--)c.push(Math.floor(Math.random()*256));return c},bytesToWords:function(a){for(var c=[],b=0,f=0;b>>5]|=a[b]<<24- f%32;return c},wordsToBytes:function(a){for(var c=[],b=0;b>>5]>>>24-b%32&255);return c},bytesToHex:function(a){for(var c=[],b=0;b>>4).toString(16));c.push((a[b]&15).toString(16))}return c.join("")},hexToBytes:function(a){for(var c=[],b=0;b>>6*(3-d)&63)):c.push("=");return c.join("")},base64ToBytes:function(a){if(typeof atob=="function")return l.stringToBytes(atob(a));a=a.replace(/[^A-Z0-9+\/]/ig,"");for(var c=[],b=0,f=0;b>> diff --git a/tools/Crypto-JS v2.4.0/crypto-sha256/crypto-sha256.js b/tools/Crypto-JS v2.4.0/crypto-sha256/crypto-sha256.js index 64dc0d8..873a1bb 100755 --- a/tools/Crypto-JS v2.4.0/crypto-sha256/crypto-sha256.js +++ b/tools/Crypto-JS v2.4.0/crypto-sha256/crypto-sha256.js @@ -1,9 +1,9 @@ -/* - * Crypto-JS v2.4.0 - * http://code.google.com/p/crypto-js/ - * Copyright (c) 2011, Jeff Mott. All rights reserved. - * http://code.google.com/p/crypto-js/wiki/License - */ +/* + * Crypto-JS v2.4.0 + * http://code.google.com/p/crypto-js/ + * Copyright (c) 2011, Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ if(typeof Crypto=="undefined"||!Crypto.util)(function(){var j=window.Crypto={},m=j.util={rotl:function(a,b){return a<>>32-b},rotr:function(a,b){return a<<32-b|a>>>b},endian:function(a){if(a.constructor==Number)return m.rotl(a,8)&16711935|m.rotl(a,24)&4278255360;for(var b=0;b0;a--)b.push(Math.floor(Math.random()*256));return b},bytesToWords:function(a){for(var b=[],c=0,f=0;c>>5]|=a[c]<<24- f%32;return b},wordsToBytes:function(a){for(var b=[],c=0;c>>5]>>>24-c%32&255);return b},bytesToHex:function(a){for(var b=[],c=0;c>>4).toString(16));b.push((a[c]&15).toString(16))}return b.join("")},hexToBytes:function(a){for(var b=[],c=0;c>>6*(3-d)&63)):b.push("=");return b.join("")},base64ToBytes:function(a){if(typeof atob=="function")return n.stringToBytes(atob(a));a=a.replace(/[^A-Z0-9+\/]/ig,"");for(var b=[],c=0,f=0;c>> diff --git a/tools/Crypto-JS v2.4.0/crypto/crypto-min.js b/tools/Crypto-JS v2.4.0/crypto/crypto-min.js index a9a70f0..e194fb3 100755 --- a/tools/Crypto-JS v2.4.0/crypto/crypto-min.js +++ b/tools/Crypto-JS v2.4.0/crypto/crypto-min.js @@ -1,9 +1,9 @@ -/* - * Crypto-JS v2.4.0 - * http://code.google.com/p/crypto-js/ - * Copyright (c) 2011, Jeff Mott. All rights reserved. - * http://code.google.com/p/crypto-js/wiki/License - */ +/* + * Crypto-JS v2.4.0 + * http://code.google.com/p/crypto-js/ + * Copyright (c) 2011, Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ if(typeof Crypto=="undefined"||!Crypto.util)(function(){var e=window.Crypto={},h=e.util={rotl:function(a,b){return a<>>32-b},rotr:function(a,b){return a<<32-b|a>>>b},endian:function(a){if(a.constructor==Number)return h.rotl(a,8)&16711935|h.rotl(a,24)&4278255360;for(var b=0;b0;a--)b.push(Math.floor(Math.random()*256));return b},bytesToWords:function(a){for(var b=[],c=0,d=0;c>>5]|=a[c]<<24- d%32;return b},wordsToBytes:function(a){for(var b=[],c=0;c>>5]>>>24-c%32&255);return b},bytesToHex:function(a){for(var b=[],c=0;c>>4).toString(16));b.push((a[c]&15).toString(16))}return b.join("")},hexToBytes:function(a){for(var b=[],c=0;c>>6*(3-g)&63)):b.push("=");return b.join("")},base64ToBytes:function(a){if(typeof atob=="function")return f.stringToBytes(atob(a));a=a.replace(/[^A-Z0-9+\/]/ig,"");for(var b=[],c=0,d=0;c>> diff --git a/tools/Crypto-JS v2.4.0/crypto/crypto.js b/tools/Crypto-JS v2.4.0/crypto/crypto.js index e8090fe..35d5216 100755 --- a/tools/Crypto-JS v2.4.0/crypto/crypto.js +++ b/tools/Crypto-JS v2.4.0/crypto/crypto.js @@ -1,160 +1,160 @@ -/* - * Crypto-JS v2.4.0 - * http://code.google.com/p/crypto-js/ - * Copyright (c) 2011, Jeff Mott. All rights reserved. - * http://code.google.com/p/crypto-js/wiki/License - */ -if (typeof Crypto == "undefined" || ! Crypto.util) -{ -(function(){ - -var base64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -// Global Crypto object -var Crypto = window.Crypto = {}; - -// Crypto utilities -var util = Crypto.util = { - - // Bit-wise rotate left - rotl: function (n, b) { - return (n << b) | (n >>> (32 - b)); - }, - - // Bit-wise rotate right - rotr: function (n, b) { - return (n << (32 - b)) | (n >>> b); - }, - - // Swap big-endian to little-endian and vice versa - endian: function (n) { - - // If number given, swap endian - if (n.constructor == Number) { - return util.rotl(n, 8) & 0x00FF00FF | - util.rotl(n, 24) & 0xFF00FF00; - } - - // Else, assume array and swap all items - for (var i = 0; i < n.length; i++) - n[i] = util.endian(n[i]); - return n; - - }, - - // Generate an array of any length of random bytes - randomBytes: function (n) { - for (var bytes = []; n > 0; n--) - bytes.push(Math.floor(Math.random() * 256)); - return bytes; - }, - - // Convert a byte array to big-endian 32-bit words - bytesToWords: function (bytes) { - for (var words = [], i = 0, b = 0; i < bytes.length; i++, b += 8) - words[b >>> 5] |= bytes[i] << (24 - b % 32); - return words; - }, - - // Convert big-endian 32-bit words to a byte array - wordsToBytes: function (words) { - for (var bytes = [], b = 0; b < words.length * 32; b += 8) - bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF); - return bytes; - }, - - // Convert a byte array to a hex string - bytesToHex: function (bytes) { - for (var hex = [], i = 0; i < bytes.length; i++) { - hex.push((bytes[i] >>> 4).toString(16)); - hex.push((bytes[i] & 0xF).toString(16)); - } - return hex.join(""); - }, - - // Convert a hex string to a byte array - hexToBytes: function (hex) { - for (var bytes = [], c = 0; c < hex.length; c += 2) - bytes.push(parseInt(hex.substr(c, 2), 16)); - return bytes; - }, - - // Convert a byte array to a base-64 string - bytesToBase64: function (bytes) { - - // Use browser-native function if it exists - if (typeof btoa == "function") return btoa(Binary.bytesToString(bytes)); - - for(var base64 = [], i = 0; i < bytes.length; i += 3) { - var triplet = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2]; - for (var j = 0; j < 4; j++) { - if (i * 8 + j * 6 <= bytes.length * 8) - base64.push(base64map.charAt((triplet >>> 6 * (3 - j)) & 0x3F)); - else base64.push("="); - } - } - - return base64.join(""); - - }, - - // Convert a base-64 string to a byte array - base64ToBytes: function (base64) { - - // Use browser-native function if it exists - if (typeof atob == "function") return Binary.stringToBytes(atob(base64)); - - // Remove non-base-64 characters - base64 = base64.replace(/[^A-Z0-9+\/]/ig, ""); - - for (var bytes = [], i = 0, imod4 = 0; i < base64.length; imod4 = ++i % 4) { - if (imod4 == 0) continue; - bytes.push(((base64map.indexOf(base64.charAt(i - 1)) & (Math.pow(2, -2 * imod4 + 8) - 1)) << (imod4 * 2)) | - (base64map.indexOf(base64.charAt(i)) >>> (6 - imod4 * 2))); - } - - return bytes; - - } - -}; - -// Crypto character encodings -var charenc = Crypto.charenc = {}; - -// UTF-8 encoding -var UTF8 = charenc.UTF8 = { - - // Convert a string to a byte array - stringToBytes: function (str) { - return Binary.stringToBytes(unescape(encodeURIComponent(str))); - }, - - // Convert a byte array to a string - bytesToString: function (bytes) { - return decodeURIComponent(escape(Binary.bytesToString(bytes))); - } - -}; - -// Binary encoding -var Binary = charenc.Binary = { - - // Convert a string to a byte array - stringToBytes: function (str) { - for (var bytes = [], i = 0; i < str.length; i++) - bytes.push(str.charCodeAt(i) & 0xFF); - return bytes; - }, - - // Convert a byte array to a string - bytesToString: function (bytes) { - for (var str = [], i = 0; i < bytes.length; i++) - str.push(String.fromCharCode(bytes[i])); - return str.join(""); - } - -}; - -})(); -} +/* + * Crypto-JS v2.4.0 + * http://code.google.com/p/crypto-js/ + * Copyright (c) 2011, Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ +if (typeof Crypto == "undefined" || ! Crypto.util) +{ +(function(){ + +var base64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +// Global Crypto object +var Crypto = window.Crypto = {}; + +// Crypto utilities +var util = Crypto.util = { + + // Bit-wise rotate left + rotl: function (n, b) { + return (n << b) | (n >>> (32 - b)); + }, + + // Bit-wise rotate right + rotr: function (n, b) { + return (n << (32 - b)) | (n >>> b); + }, + + // Swap big-endian to little-endian and vice versa + endian: function (n) { + + // If number given, swap endian + if (n.constructor == Number) { + return util.rotl(n, 8) & 0x00FF00FF | + util.rotl(n, 24) & 0xFF00FF00; + } + + // Else, assume array and swap all items + for (var i = 0; i < n.length; i++) + n[i] = util.endian(n[i]); + return n; + + }, + + // Generate an array of any length of random bytes + randomBytes: function (n) { + for (var bytes = []; n > 0; n--) + bytes.push(Math.floor(Math.random() * 256)); + return bytes; + }, + + // Convert a byte array to big-endian 32-bit words + bytesToWords: function (bytes) { + for (var words = [], i = 0, b = 0; i < bytes.length; i++, b += 8) + words[b >>> 5] |= bytes[i] << (24 - b % 32); + return words; + }, + + // Convert big-endian 32-bit words to a byte array + wordsToBytes: function (words) { + for (var bytes = [], b = 0; b < words.length * 32; b += 8) + bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF); + return bytes; + }, + + // Convert a byte array to a hex string + bytesToHex: function (bytes) { + for (var hex = [], i = 0; i < bytes.length; i++) { + hex.push((bytes[i] >>> 4).toString(16)); + hex.push((bytes[i] & 0xF).toString(16)); + } + return hex.join(""); + }, + + // Convert a hex string to a byte array + hexToBytes: function (hex) { + for (var bytes = [], c = 0; c < hex.length; c += 2) + bytes.push(parseInt(hex.substr(c, 2), 16)); + return bytes; + }, + + // Convert a byte array to a base-64 string + bytesToBase64: function (bytes) { + + // Use browser-native function if it exists + if (typeof btoa == "function") return btoa(Binary.bytesToString(bytes)); + + for(var base64 = [], i = 0; i < bytes.length; i += 3) { + var triplet = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2]; + for (var j = 0; j < 4; j++) { + if (i * 8 + j * 6 <= bytes.length * 8) + base64.push(base64map.charAt((triplet >>> 6 * (3 - j)) & 0x3F)); + else base64.push("="); + } + } + + return base64.join(""); + + }, + + // Convert a base-64 string to a byte array + base64ToBytes: function (base64) { + + // Use browser-native function if it exists + if (typeof atob == "function") return Binary.stringToBytes(atob(base64)); + + // Remove non-base-64 characters + base64 = base64.replace(/[^A-Z0-9+\/]/ig, ""); + + for (var bytes = [], i = 0, imod4 = 0; i < base64.length; imod4 = ++i % 4) { + if (imod4 == 0) continue; + bytes.push(((base64map.indexOf(base64.charAt(i - 1)) & (Math.pow(2, -2 * imod4 + 8) - 1)) << (imod4 * 2)) | + (base64map.indexOf(base64.charAt(i)) >>> (6 - imod4 * 2))); + } + + return bytes; + + } + +}; + +// Crypto character encodings +var charenc = Crypto.charenc = {}; + +// UTF-8 encoding +var UTF8 = charenc.UTF8 = { + + // Convert a string to a byte array + stringToBytes: function (str) { + return Binary.stringToBytes(unescape(encodeURIComponent(str))); + }, + + // Convert a byte array to a string + bytesToString: function (bytes) { + return decodeURIComponent(escape(Binary.bytesToString(bytes))); + } + +}; + +// Binary encoding +var Binary = charenc.Binary = { + + // Convert a string to a byte array + stringToBytes: function (str) { + for (var bytes = [], i = 0; i < str.length; i++) + bytes.push(str.charCodeAt(i) & 0xFF); + return bytes; + }, + + // Convert a byte array to a string + bytesToString: function (bytes) { + for (var str = [], i = 0; i < bytes.length; i++) + str.push(String.fromCharCode(bytes[i])); + return str.join(""); + } + +}; + +})(); +} diff --git a/tools/Crypto-JS v2.4.0/hmac/hmac-min.js b/tools/Crypto-JS v2.4.0/hmac/hmac-min.js index 0becfbc..da13e60 100755 --- a/tools/Crypto-JS v2.4.0/hmac/hmac-min.js +++ b/tools/Crypto-JS v2.4.0/hmac/hmac-min.js @@ -1,7 +1,7 @@ -/* - * Crypto-JS v2.4.0 - * http://code.google.com/p/crypto-js/ - * Copyright (c) 2011, Jeff Mott. All rights reserved. - * http://code.google.com/p/crypto-js/wiki/License - */ +/* + * Crypto-JS v2.4.0 + * http://code.google.com/p/crypto-js/ + * Copyright (c) 2011, Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ (function(){var f=Crypto,j=f.util,g=f.charenc,h=g.UTF8,k=g.Binary;f.HMAC=function(b,c,a,d){if(c.constructor==String)c=h.stringToBytes(c);if(a.constructor==String)a=h.stringToBytes(a);if(a.length>b._blocksize*4)a=b(a,{asBytes:true});var i=a.slice(0);a=a.slice(0);for(var e=0;e hasher._blocksize * 4) - key = hasher(key, { asBytes: true }); - - // XOR keys with pad constants - var okey = key.slice(0), - ikey = key.slice(0); - for (var i = 0; i < hasher._blocksize * 4; i++) { - okey[i] ^= 0x5C; - ikey[i] ^= 0x36; - } - - var hmacbytes = hasher(okey.concat(hasher(ikey.concat(message), { asBytes: true })), { asBytes: true }); - - return options && options.asBytes ? hmacbytes : - options && options.asString ? Binary.bytesToString(hmacbytes) : - util.bytesToHex(hmacbytes); - -}; - -})(); +/* + * Crypto-JS v2.4.0 + * http://code.google.com/p/crypto-js/ + * Copyright (c) 2011, Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ +(function(){ + +// Shortcuts +var C = Crypto, + util = C.util, + charenc = C.charenc, + UTF8 = charenc.UTF8, + Binary = charenc.Binary; + +C.HMAC = function (hasher, message, key, options) { + + // Convert to byte arrays + if (message.constructor == String) message = UTF8.stringToBytes(message); + if (key.constructor == String) key = UTF8.stringToBytes(key); + /* else, assume byte arrays already */ + + // Allow arbitrary length keys + if (key.length > hasher._blocksize * 4) + key = hasher(key, { asBytes: true }); + + // XOR keys with pad constants + var okey = key.slice(0), + ikey = key.slice(0); + for (var i = 0; i < hasher._blocksize * 4; i++) { + okey[i] ^= 0x5C; + ikey[i] ^= 0x36; + } + + var hmacbytes = hasher(okey.concat(hasher(ikey.concat(message), { asBytes: true })), { asBytes: true }); + + return options && options.asBytes ? hmacbytes : + options && options.asString ? Binary.bytesToString(hmacbytes) : + util.bytesToHex(hmacbytes); + +}; + +})(); diff --git a/tools/Crypto-JS v2.4.0/marc4/marc4-min.js b/tools/Crypto-JS v2.4.0/marc4/marc4-min.js index dfcff6a..96d1066 100755 --- a/tools/Crypto-JS v2.4.0/marc4/marc4-min.js +++ b/tools/Crypto-JS v2.4.0/marc4/marc4-min.js @@ -1,8 +1,8 @@ -/* - * Crypto-JS v2.4.0 - * http://code.google.com/p/crypto-js/ - * Copyright (c) 2011, Jeff Mott. All rights reserved. - * http://code.google.com/p/crypto-js/wiki/License - */ +/* + * Crypto-JS v2.4.0 + * http://code.google.com/p/crypto-js/ + * Copyright (c) 2011, Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ (function(){var g=Crypto,i=g.util,j=g.charenc.UTF8,k=g.MARC4={encrypt:function(f,b){var e=j.stringToBytes(f),a=i.randomBytes(16),d=b.constructor==String?g.PBKDF2(b,a,32,{asBytes:true}):b;k._marc4(e,d,1536);return i.bytesToBase64(a.concat(e))},decrypt:function(f,b){var e=i.base64ToBytes(f),a=e.splice(0,16);a=b.constructor==String?g.PBKDF2(b,a,32,{asBytes:true}):b;k._marc4(e,a,1536);return j.bytesToString(e)},_marc4:function(f,b,e){var a,d,c,h;a=0;for(c=[];a<256;a++)c[a]=a;for(d=a=0;a<256;a++){d=(d+ c[a]+b[a%b.length])%256;h=c[a];c[a]=c[d];c[d]=h}a=d=0;for(b=-e;b>>24)&16711935|(e[f]<<24|e[f]>>>8)&4278255360;e[g>>>5]|=128<>>9<<4)+14]=g;g=k._ff;var h=k._gg,i= k._hh,j=k._ii;for(f=0;f>> 24)) & 0x00FF00FF | - ((m[i] << 24) | (m[i] >>> 8)) & 0xFF00FF00; - } - - // Padding - m[l >>> 5] |= 0x80 << (l % 32); - m[(((l + 64) >>> 9) << 4) + 14] = l; - - // Method shortcuts - var FF = MD5._ff, - GG = MD5._gg, - HH = MD5._hh, - II = MD5._ii; - - for (var i = 0; i < m.length; i += 16) { - - var aa = a, - bb = b, - cc = c, - dd = d; - - a = FF(a, b, c, d, m[i+ 0], 7, -680876936); - d = FF(d, a, b, c, m[i+ 1], 12, -389564586); - c = FF(c, d, a, b, m[i+ 2], 17, 606105819); - b = FF(b, c, d, a, m[i+ 3], 22, -1044525330); - a = FF(a, b, c, d, m[i+ 4], 7, -176418897); - d = FF(d, a, b, c, m[i+ 5], 12, 1200080426); - c = FF(c, d, a, b, m[i+ 6], 17, -1473231341); - b = FF(b, c, d, a, m[i+ 7], 22, -45705983); - a = FF(a, b, c, d, m[i+ 8], 7, 1770035416); - d = FF(d, a, b, c, m[i+ 9], 12, -1958414417); - c = FF(c, d, a, b, m[i+10], 17, -42063); - b = FF(b, c, d, a, m[i+11], 22, -1990404162); - a = FF(a, b, c, d, m[i+12], 7, 1804603682); - d = FF(d, a, b, c, m[i+13], 12, -40341101); - c = FF(c, d, a, b, m[i+14], 17, -1502002290); - b = FF(b, c, d, a, m[i+15], 22, 1236535329); - - a = GG(a, b, c, d, m[i+ 1], 5, -165796510); - d = GG(d, a, b, c, m[i+ 6], 9, -1069501632); - c = GG(c, d, a, b, m[i+11], 14, 643717713); - b = GG(b, c, d, a, m[i+ 0], 20, -373897302); - a = GG(a, b, c, d, m[i+ 5], 5, -701558691); - d = GG(d, a, b, c, m[i+10], 9, 38016083); - c = GG(c, d, a, b, m[i+15], 14, -660478335); - b = GG(b, c, d, a, m[i+ 4], 20, -405537848); - a = GG(a, b, c, d, m[i+ 9], 5, 568446438); - d = GG(d, a, b, c, m[i+14], 9, -1019803690); - c = GG(c, d, a, b, m[i+ 3], 14, -187363961); - b = GG(b, c, d, a, m[i+ 8], 20, 1163531501); - a = GG(a, b, c, d, m[i+13], 5, -1444681467); - d = GG(d, a, b, c, m[i+ 2], 9, -51403784); - c = GG(c, d, a, b, m[i+ 7], 14, 1735328473); - b = GG(b, c, d, a, m[i+12], 20, -1926607734); - - a = HH(a, b, c, d, m[i+ 5], 4, -378558); - d = HH(d, a, b, c, m[i+ 8], 11, -2022574463); - c = HH(c, d, a, b, m[i+11], 16, 1839030562); - b = HH(b, c, d, a, m[i+14], 23, -35309556); - a = HH(a, b, c, d, m[i+ 1], 4, -1530992060); - d = HH(d, a, b, c, m[i+ 4], 11, 1272893353); - c = HH(c, d, a, b, m[i+ 7], 16, -155497632); - b = HH(b, c, d, a, m[i+10], 23, -1094730640); - a = HH(a, b, c, d, m[i+13], 4, 681279174); - d = HH(d, a, b, c, m[i+ 0], 11, -358537222); - c = HH(c, d, a, b, m[i+ 3], 16, -722521979); - b = HH(b, c, d, a, m[i+ 6], 23, 76029189); - a = HH(a, b, c, d, m[i+ 9], 4, -640364487); - d = HH(d, a, b, c, m[i+12], 11, -421815835); - c = HH(c, d, a, b, m[i+15], 16, 530742520); - b = HH(b, c, d, a, m[i+ 2], 23, -995338651); - - a = II(a, b, c, d, m[i+ 0], 6, -198630844); - d = II(d, a, b, c, m[i+ 7], 10, 1126891415); - c = II(c, d, a, b, m[i+14], 15, -1416354905); - b = II(b, c, d, a, m[i+ 5], 21, -57434055); - a = II(a, b, c, d, m[i+12], 6, 1700485571); - d = II(d, a, b, c, m[i+ 3], 10, -1894986606); - c = II(c, d, a, b, m[i+10], 15, -1051523); - b = II(b, c, d, a, m[i+ 1], 21, -2054922799); - a = II(a, b, c, d, m[i+ 8], 6, 1873313359); - d = II(d, a, b, c, m[i+15], 10, -30611744); - c = II(c, d, a, b, m[i+ 6], 15, -1560198380); - b = II(b, c, d, a, m[i+13], 21, 1309151649); - a = II(a, b, c, d, m[i+ 4], 6, -145523070); - d = II(d, a, b, c, m[i+11], 10, -1120210379); - c = II(c, d, a, b, m[i+ 2], 15, 718787259); - b = II(b, c, d, a, m[i+ 9], 21, -343485551); - - a = (a + aa) >>> 0; - b = (b + bb) >>> 0; - c = (c + cc) >>> 0; - d = (d + dd) >>> 0; - - } - - return util.endian([a, b, c, d]); - -}; - -// Auxiliary functions -MD5._ff = function (a, b, c, d, x, s, t) { - var n = a + (b & c | ~b & d) + (x >>> 0) + t; - return ((n << s) | (n >>> (32 - s))) + b; -}; -MD5._gg = function (a, b, c, d, x, s, t) { - var n = a + (b & d | c & ~d) + (x >>> 0) + t; - return ((n << s) | (n >>> (32 - s))) + b; -}; -MD5._hh = function (a, b, c, d, x, s, t) { - var n = a + (b ^ c ^ d) + (x >>> 0) + t; - return ((n << s) | (n >>> (32 - s))) + b; -}; -MD5._ii = function (a, b, c, d, x, s, t) { - var n = a + (c ^ (b | ~d)) + (x >>> 0) + t; - return ((n << s) | (n >>> (32 - s))) + b; -}; - -// Package private blocksize -MD5._blocksize = 16; - -MD5._digestsize = 16; - -})(); +/* + * Crypto-JS v2.4.0 + * http://code.google.com/p/crypto-js/ + * Copyright (c) 2011, Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ +(function(){ + +// Shortcuts +var C = Crypto, + util = C.util, + charenc = C.charenc, + UTF8 = charenc.UTF8, + Binary = charenc.Binary; + +// Public API +var MD5 = C.MD5 = function (message, options) { + var digestbytes = util.wordsToBytes(MD5._md5(message)); + return options && options.asBytes ? digestbytes : + options && options.asString ? Binary.bytesToString(digestbytes) : + util.bytesToHex(digestbytes); +}; + +// The core +MD5._md5 = function (message) { + + // Convert to byte array + if (message.constructor == String) message = UTF8.stringToBytes(message); + /* else, assume byte array already */ + + var m = util.bytesToWords(message), + l = message.length * 8, + a = 1732584193, + b = -271733879, + c = -1732584194, + d = 271733878; + + // Swap endian + for (var i = 0; i < m.length; i++) { + m[i] = ((m[i] << 8) | (m[i] >>> 24)) & 0x00FF00FF | + ((m[i] << 24) | (m[i] >>> 8)) & 0xFF00FF00; + } + + // Padding + m[l >>> 5] |= 0x80 << (l % 32); + m[(((l + 64) >>> 9) << 4) + 14] = l; + + // Method shortcuts + var FF = MD5._ff, + GG = MD5._gg, + HH = MD5._hh, + II = MD5._ii; + + for (var i = 0; i < m.length; i += 16) { + + var aa = a, + bb = b, + cc = c, + dd = d; + + a = FF(a, b, c, d, m[i+ 0], 7, -680876936); + d = FF(d, a, b, c, m[i+ 1], 12, -389564586); + c = FF(c, d, a, b, m[i+ 2], 17, 606105819); + b = FF(b, c, d, a, m[i+ 3], 22, -1044525330); + a = FF(a, b, c, d, m[i+ 4], 7, -176418897); + d = FF(d, a, b, c, m[i+ 5], 12, 1200080426); + c = FF(c, d, a, b, m[i+ 6], 17, -1473231341); + b = FF(b, c, d, a, m[i+ 7], 22, -45705983); + a = FF(a, b, c, d, m[i+ 8], 7, 1770035416); + d = FF(d, a, b, c, m[i+ 9], 12, -1958414417); + c = FF(c, d, a, b, m[i+10], 17, -42063); + b = FF(b, c, d, a, m[i+11], 22, -1990404162); + a = FF(a, b, c, d, m[i+12], 7, 1804603682); + d = FF(d, a, b, c, m[i+13], 12, -40341101); + c = FF(c, d, a, b, m[i+14], 17, -1502002290); + b = FF(b, c, d, a, m[i+15], 22, 1236535329); + + a = GG(a, b, c, d, m[i+ 1], 5, -165796510); + d = GG(d, a, b, c, m[i+ 6], 9, -1069501632); + c = GG(c, d, a, b, m[i+11], 14, 643717713); + b = GG(b, c, d, a, m[i+ 0], 20, -373897302); + a = GG(a, b, c, d, m[i+ 5], 5, -701558691); + d = GG(d, a, b, c, m[i+10], 9, 38016083); + c = GG(c, d, a, b, m[i+15], 14, -660478335); + b = GG(b, c, d, a, m[i+ 4], 20, -405537848); + a = GG(a, b, c, d, m[i+ 9], 5, 568446438); + d = GG(d, a, b, c, m[i+14], 9, -1019803690); + c = GG(c, d, a, b, m[i+ 3], 14, -187363961); + b = GG(b, c, d, a, m[i+ 8], 20, 1163531501); + a = GG(a, b, c, d, m[i+13], 5, -1444681467); + d = GG(d, a, b, c, m[i+ 2], 9, -51403784); + c = GG(c, d, a, b, m[i+ 7], 14, 1735328473); + b = GG(b, c, d, a, m[i+12], 20, -1926607734); + + a = HH(a, b, c, d, m[i+ 5], 4, -378558); + d = HH(d, a, b, c, m[i+ 8], 11, -2022574463); + c = HH(c, d, a, b, m[i+11], 16, 1839030562); + b = HH(b, c, d, a, m[i+14], 23, -35309556); + a = HH(a, b, c, d, m[i+ 1], 4, -1530992060); + d = HH(d, a, b, c, m[i+ 4], 11, 1272893353); + c = HH(c, d, a, b, m[i+ 7], 16, -155497632); + b = HH(b, c, d, a, m[i+10], 23, -1094730640); + a = HH(a, b, c, d, m[i+13], 4, 681279174); + d = HH(d, a, b, c, m[i+ 0], 11, -358537222); + c = HH(c, d, a, b, m[i+ 3], 16, -722521979); + b = HH(b, c, d, a, m[i+ 6], 23, 76029189); + a = HH(a, b, c, d, m[i+ 9], 4, -640364487); + d = HH(d, a, b, c, m[i+12], 11, -421815835); + c = HH(c, d, a, b, m[i+15], 16, 530742520); + b = HH(b, c, d, a, m[i+ 2], 23, -995338651); + + a = II(a, b, c, d, m[i+ 0], 6, -198630844); + d = II(d, a, b, c, m[i+ 7], 10, 1126891415); + c = II(c, d, a, b, m[i+14], 15, -1416354905); + b = II(b, c, d, a, m[i+ 5], 21, -57434055); + a = II(a, b, c, d, m[i+12], 6, 1700485571); + d = II(d, a, b, c, m[i+ 3], 10, -1894986606); + c = II(c, d, a, b, m[i+10], 15, -1051523); + b = II(b, c, d, a, m[i+ 1], 21, -2054922799); + a = II(a, b, c, d, m[i+ 8], 6, 1873313359); + d = II(d, a, b, c, m[i+15], 10, -30611744); + c = II(c, d, a, b, m[i+ 6], 15, -1560198380); + b = II(b, c, d, a, m[i+13], 21, 1309151649); + a = II(a, b, c, d, m[i+ 4], 6, -145523070); + d = II(d, a, b, c, m[i+11], 10, -1120210379); + c = II(c, d, a, b, m[i+ 2], 15, 718787259); + b = II(b, c, d, a, m[i+ 9], 21, -343485551); + + a = (a + aa) >>> 0; + b = (b + bb) >>> 0; + c = (c + cc) >>> 0; + d = (d + dd) >>> 0; + + } + + return util.endian([a, b, c, d]); + +}; + +// Auxiliary functions +MD5._ff = function (a, b, c, d, x, s, t) { + var n = a + (b & c | ~b & d) + (x >>> 0) + t; + return ((n << s) | (n >>> (32 - s))) + b; +}; +MD5._gg = function (a, b, c, d, x, s, t) { + var n = a + (b & d | c & ~d) + (x >>> 0) + t; + return ((n << s) | (n >>> (32 - s))) + b; +}; +MD5._hh = function (a, b, c, d, x, s, t) { + var n = a + (b ^ c ^ d) + (x >>> 0) + t; + return ((n << s) | (n >>> (32 - s))) + b; +}; +MD5._ii = function (a, b, c, d, x, s, t) { + var n = a + (c ^ (b | ~d)) + (x >>> 0) + t; + return ((n << s) | (n >>> (32 - s))) + b; +}; + +// Package private blocksize +MD5._blocksize = 16; + +MD5._digestsize = 16; + +})(); diff --git a/tools/Crypto-JS v2.4.0/pbkdf2/pbkdf2-min.js b/tools/Crypto-JS v2.4.0/pbkdf2/pbkdf2-min.js index 169659f..c8b20b6 100755 --- a/tools/Crypto-JS v2.4.0/pbkdf2/pbkdf2-min.js +++ b/tools/Crypto-JS v2.4.0/pbkdf2/pbkdf2-min.js @@ -1,8 +1,8 @@ -/* - * Crypto-JS v2.4.0 - * http://code.google.com/p/crypto-js/ - * Copyright (c) 2011, Jeff Mott. All rights reserved. - * http://code.google.com/p/crypto-js/wiki/License - */ +/* + * Crypto-JS v2.4.0 + * http://code.google.com/p/crypto-js/ + * Copyright (c) 2011, Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ (function(){var c=Crypto,i=c.util,j=c.charenc,k=j.UTF8,p=j.Binary;c.PBKDF2=function(d,e,l,a){function m(q,r){return c.HMAC(s,r,q,{asBytes:true})}if(d.constructor==String)d=k.stringToBytes(d);if(e.constructor==String)e=k.stringToBytes(e);for(var s=a&&a.hasher||c.SHA1,t=a&&a.iterations||1,b=[],n=1;b.length>>16^d[3]<<16;c[1]=d[2]^d[7]>>>16^d[5]<<16;c[2]=d[4]^d[1]>>>16^d[7]<<16;c[3]=d[6]^d[3]>>>16^d[1]<<16;for(var e=0;e<4;e++)c[e]=(c[e]<<8|c[e]>>>24)&16711935|(c[e]<<24|c[e]>>>8)&4278255360;for(e=120;e>=0;e-=8)c[e/8]=c[e>>>5]>>>24-e%32&255}a[f]^=c[f%16]}},_keysetup:function(a){d[0]=a[0];d[2]=a[1];d[4]=a[2];d[6]=a[3];d[1]=a[3]<<16|a[2]>>>16;d[3]=a[0]<<16|a[3]>>>16;d[5]=a[1]<<16|a[0]>>>16;d[7]=a[2]<<16|a[1]>>>16;b[0]=g.rotl(a[2],16); b[2]=g.rotl(a[3],16);b[4]=g.rotl(a[0],16);b[6]=g.rotl(a[1],16);b[1]=a[0]&4294901760|a[1]&65535;b[3]=a[1]&4294901760|a[2]&65535;b[5]=a[2]&4294901760|a[3]&65535;b[7]=a[3]&4294901760|a[0]&65535;for(a=k=0;a<4;a++)i._nextstate();for(a=0;a<8;a++)b[a]^=d[a+4&7]},_ivsetup:function(a){var c=g.endian(a[0]);a=g.endian(a[1]);var f=c>>>16|a&4294901760,e=a<<16|c&65535;b[0]^=c;b[1]^=f;b[2]^=a;b[3]^=e;b[4]^=c;b[5]^=f;b[6]^=a;b[7]^=e;for(c=0;c<4;c++)i._nextstate()},_nextstate:function(){for(var a=[],c=0;c<8;c++)a[c]= diff --git a/tools/Crypto-JS v2.4.0/rabbit/rabbit.js b/tools/Crypto-JS v2.4.0/rabbit/rabbit.js index 87bdefc..1dae96b 100755 --- a/tools/Crypto-JS v2.4.0/rabbit/rabbit.js +++ b/tools/Crypto-JS v2.4.0/rabbit/rabbit.js @@ -1,226 +1,226 @@ -/* - * Crypto-JS v2.4.0 - * http://code.google.com/p/crypto-js/ - * Copyright (c) 2011, Jeff Mott. All rights reserved. - * http://code.google.com/p/crypto-js/wiki/License - */ -(function(){ - -// Shortcuts -var C = Crypto, - util = C.util, - charenc = C.charenc, - UTF8 = charenc.UTF8, - Binary = charenc.Binary; - -// Inner state -var x = [], - c = [], - b; - -var Rabbit = C.Rabbit = { - - /** - * Public API - */ - - encrypt: function (message, password) { - - var - - // Convert to bytes - m = UTF8.stringToBytes(message), - - // Generate random IV - iv = util.randomBytes(8), - - // Generate key - k = password.constructor == String ? - // Derive key from passphrase - C.PBKDF2(password, iv, 32, { asBytes: true }) : - // else, assume byte array representing cryptographic key - password; - - // Encrypt - Rabbit._rabbit(m, k, util.bytesToWords(iv)); - - // Return ciphertext - return util.bytesToBase64(iv.concat(m)); - - }, - - decrypt: function (ciphertext, password) { - - var - - // Convert to bytes - c = util.base64ToBytes(ciphertext), - - // Separate IV and message - iv = c.splice(0, 8), - - // Generate key - k = password.constructor == String ? - // Derive key from passphrase - C.PBKDF2(password, iv, 32, { asBytes: true }) : - // else, assume byte array representing cryptographic key - password; - - // Decrypt - Rabbit._rabbit(c, k, util.bytesToWords(iv)); - - // Return plaintext - return UTF8.bytesToString(c); - - }, - - - /** - * Internal methods - */ - - // Encryption/decryption scheme - _rabbit: function (m, k, iv) { - - Rabbit._keysetup(k); - if (iv) Rabbit._ivsetup(iv); - - for (var s = [], i = 0; i < m.length; i++) { - - if (i % 16 == 0) { - - // Iterate the system - Rabbit._nextstate(); - - // Generate 16 bytes of pseudo-random data - s[0] = x[0] ^ (x[5] >>> 16) ^ (x[3] << 16); - s[1] = x[2] ^ (x[7] >>> 16) ^ (x[5] << 16); - s[2] = x[4] ^ (x[1] >>> 16) ^ (x[7] << 16); - s[3] = x[6] ^ (x[3] >>> 16) ^ (x[1] << 16); - - // Swap endian - for (var j = 0; j < 4; j++) { - s[j] = ((s[j] << 8) | (s[j] >>> 24)) & 0x00FF00FF | - ((s[j] << 24) | (s[j] >>> 8)) & 0xFF00FF00; - } - - // Convert words to bytes - for (var b = 120; b >= 0; b -= 8) - s[b / 8] = (s[b >>> 5] >>> (24 - b % 32)) & 0xFF; - - } - - m[i] ^= s[i % 16]; - - } - - }, - - // Key setup scheme - _keysetup: function (k) { - - // Generate initial state values - x[0] = k[0]; - x[2] = k[1]; - x[4] = k[2]; - x[6] = k[3]; - x[1] = (k[3] << 16) | (k[2] >>> 16); - x[3] = (k[0] << 16) | (k[3] >>> 16); - x[5] = (k[1] << 16) | (k[0] >>> 16); - x[7] = (k[2] << 16) | (k[1] >>> 16); - - // Generate initial counter values - c[0] = util.rotl(k[2], 16); - c[2] = util.rotl(k[3], 16); - c[4] = util.rotl(k[0], 16); - c[6] = util.rotl(k[1], 16); - c[1] = (k[0] & 0xFFFF0000) | (k[1] & 0xFFFF); - c[3] = (k[1] & 0xFFFF0000) | (k[2] & 0xFFFF); - c[5] = (k[2] & 0xFFFF0000) | (k[3] & 0xFFFF); - c[7] = (k[3] & 0xFFFF0000) | (k[0] & 0xFFFF); - - // Clear carry bit - b = 0; - - // Iterate the system four times - for (var i = 0; i < 4; i++) Rabbit._nextstate(); - - // Modify the counters - for (var i = 0; i < 8; i++) c[i] ^= x[(i + 4) & 7]; - - }, - - // IV setup scheme - _ivsetup: function (iv) { - - // Generate four subvectors - var i0 = util.endian(iv[0]), - i2 = util.endian(iv[1]), - i1 = (i0 >>> 16) | (i2 & 0xFFFF0000), - i3 = (i2 << 16) | (i0 & 0x0000FFFF); - - // Modify counter values - c[0] ^= i0; - c[1] ^= i1; - c[2] ^= i2; - c[3] ^= i3; - c[4] ^= i0; - c[5] ^= i1; - c[6] ^= i2; - c[7] ^= i3; - - // Iterate the system four times - for (var i = 0; i < 4; i++) Rabbit._nextstate(); - - }, - - // Next-state function - _nextstate: function () { - - // Save old counter values - for (var c_old = [], i = 0; i < 8; i++) c_old[i] = c[i]; - - // Calculate new counter values - c[0] = (c[0] + 0x4D34D34D + b) >>> 0; - c[1] = (c[1] + 0xD34D34D3 + ((c[0] >>> 0) < (c_old[0] >>> 0) ? 1 : 0)) >>> 0; - c[2] = (c[2] + 0x34D34D34 + ((c[1] >>> 0) < (c_old[1] >>> 0) ? 1 : 0)) >>> 0; - c[3] = (c[3] + 0x4D34D34D + ((c[2] >>> 0) < (c_old[2] >>> 0) ? 1 : 0)) >>> 0; - c[4] = (c[4] + 0xD34D34D3 + ((c[3] >>> 0) < (c_old[3] >>> 0) ? 1 : 0)) >>> 0; - c[5] = (c[5] + 0x34D34D34 + ((c[4] >>> 0) < (c_old[4] >>> 0) ? 1 : 0)) >>> 0; - c[6] = (c[6] + 0x4D34D34D + ((c[5] >>> 0) < (c_old[5] >>> 0) ? 1 : 0)) >>> 0; - c[7] = (c[7] + 0xD34D34D3 + ((c[6] >>> 0) < (c_old[6] >>> 0) ? 1 : 0)) >>> 0; - b = (c[7] >>> 0) < (c_old[7] >>> 0) ? 1 : 0; - - // Calculate the g-values - for (var g = [], i = 0; i < 8; i++) { - - var gx = (x[i] + c[i]) >>> 0; - - // Construct high and low argument for squaring - var ga = gx & 0xFFFF, - gb = gx >>> 16; - - // Calculate high and low result of squaring - var gh = ((((ga * ga) >>> 17) + ga * gb) >>> 15) + gb * gb, - gl = (((gx & 0xFFFF0000) * gx) >>> 0) + (((gx & 0x0000FFFF) * gx) >>> 0) >>> 0; - - // High XOR low - g[i] = gh ^ gl; - - } - - // Calculate new state values - x[0] = g[0] + ((g[7] << 16) | (g[7] >>> 16)) + ((g[6] << 16) | (g[6] >>> 16)); - x[1] = g[1] + ((g[0] << 8) | (g[0] >>> 24)) + g[7]; - x[2] = g[2] + ((g[1] << 16) | (g[1] >>> 16)) + ((g[0] << 16) | (g[0] >>> 16)); - x[3] = g[3] + ((g[2] << 8) | (g[2] >>> 24)) + g[1]; - x[4] = g[4] + ((g[3] << 16) | (g[3] >>> 16)) + ((g[2] << 16) | (g[2] >>> 16)); - x[5] = g[5] + ((g[4] << 8) | (g[4] >>> 24)) + g[3]; - x[6] = g[6] + ((g[5] << 16) | (g[5] >>> 16)) + ((g[4] << 16) | (g[4] >>> 16)); - x[7] = g[7] + ((g[6] << 8) | (g[6] >>> 24)) + g[5]; - - } - -}; - -})(); +/* + * Crypto-JS v2.4.0 + * http://code.google.com/p/crypto-js/ + * Copyright (c) 2011, Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ +(function(){ + +// Shortcuts +var C = Crypto, + util = C.util, + charenc = C.charenc, + UTF8 = charenc.UTF8, + Binary = charenc.Binary; + +// Inner state +var x = [], + c = [], + b; + +var Rabbit = C.Rabbit = { + + /** + * Public API + */ + + encrypt: function (message, password) { + + var + + // Convert to bytes + m = UTF8.stringToBytes(message), + + // Generate random IV + iv = util.randomBytes(8), + + // Generate key + k = password.constructor == String ? + // Derive key from passphrase + C.PBKDF2(password, iv, 32, { asBytes: true }) : + // else, assume byte array representing cryptographic key + password; + + // Encrypt + Rabbit._rabbit(m, k, util.bytesToWords(iv)); + + // Return ciphertext + return util.bytesToBase64(iv.concat(m)); + + }, + + decrypt: function (ciphertext, password) { + + var + + // Convert to bytes + c = util.base64ToBytes(ciphertext), + + // Separate IV and message + iv = c.splice(0, 8), + + // Generate key + k = password.constructor == String ? + // Derive key from passphrase + C.PBKDF2(password, iv, 32, { asBytes: true }) : + // else, assume byte array representing cryptographic key + password; + + // Decrypt + Rabbit._rabbit(c, k, util.bytesToWords(iv)); + + // Return plaintext + return UTF8.bytesToString(c); + + }, + + + /** + * Internal methods + */ + + // Encryption/decryption scheme + _rabbit: function (m, k, iv) { + + Rabbit._keysetup(k); + if (iv) Rabbit._ivsetup(iv); + + for (var s = [], i = 0; i < m.length; i++) { + + if (i % 16 == 0) { + + // Iterate the system + Rabbit._nextstate(); + + // Generate 16 bytes of pseudo-random data + s[0] = x[0] ^ (x[5] >>> 16) ^ (x[3] << 16); + s[1] = x[2] ^ (x[7] >>> 16) ^ (x[5] << 16); + s[2] = x[4] ^ (x[1] >>> 16) ^ (x[7] << 16); + s[3] = x[6] ^ (x[3] >>> 16) ^ (x[1] << 16); + + // Swap endian + for (var j = 0; j < 4; j++) { + s[j] = ((s[j] << 8) | (s[j] >>> 24)) & 0x00FF00FF | + ((s[j] << 24) | (s[j] >>> 8)) & 0xFF00FF00; + } + + // Convert words to bytes + for (var b = 120; b >= 0; b -= 8) + s[b / 8] = (s[b >>> 5] >>> (24 - b % 32)) & 0xFF; + + } + + m[i] ^= s[i % 16]; + + } + + }, + + // Key setup scheme + _keysetup: function (k) { + + // Generate initial state values + x[0] = k[0]; + x[2] = k[1]; + x[4] = k[2]; + x[6] = k[3]; + x[1] = (k[3] << 16) | (k[2] >>> 16); + x[3] = (k[0] << 16) | (k[3] >>> 16); + x[5] = (k[1] << 16) | (k[0] >>> 16); + x[7] = (k[2] << 16) | (k[1] >>> 16); + + // Generate initial counter values + c[0] = util.rotl(k[2], 16); + c[2] = util.rotl(k[3], 16); + c[4] = util.rotl(k[0], 16); + c[6] = util.rotl(k[1], 16); + c[1] = (k[0] & 0xFFFF0000) | (k[1] & 0xFFFF); + c[3] = (k[1] & 0xFFFF0000) | (k[2] & 0xFFFF); + c[5] = (k[2] & 0xFFFF0000) | (k[3] & 0xFFFF); + c[7] = (k[3] & 0xFFFF0000) | (k[0] & 0xFFFF); + + // Clear carry bit + b = 0; + + // Iterate the system four times + for (var i = 0; i < 4; i++) Rabbit._nextstate(); + + // Modify the counters + for (var i = 0; i < 8; i++) c[i] ^= x[(i + 4) & 7]; + + }, + + // IV setup scheme + _ivsetup: function (iv) { + + // Generate four subvectors + var i0 = util.endian(iv[0]), + i2 = util.endian(iv[1]), + i1 = (i0 >>> 16) | (i2 & 0xFFFF0000), + i3 = (i2 << 16) | (i0 & 0x0000FFFF); + + // Modify counter values + c[0] ^= i0; + c[1] ^= i1; + c[2] ^= i2; + c[3] ^= i3; + c[4] ^= i0; + c[5] ^= i1; + c[6] ^= i2; + c[7] ^= i3; + + // Iterate the system four times + for (var i = 0; i < 4; i++) Rabbit._nextstate(); + + }, + + // Next-state function + _nextstate: function () { + + // Save old counter values + for (var c_old = [], i = 0; i < 8; i++) c_old[i] = c[i]; + + // Calculate new counter values + c[0] = (c[0] + 0x4D34D34D + b) >>> 0; + c[1] = (c[1] + 0xD34D34D3 + ((c[0] >>> 0) < (c_old[0] >>> 0) ? 1 : 0)) >>> 0; + c[2] = (c[2] + 0x34D34D34 + ((c[1] >>> 0) < (c_old[1] >>> 0) ? 1 : 0)) >>> 0; + c[3] = (c[3] + 0x4D34D34D + ((c[2] >>> 0) < (c_old[2] >>> 0) ? 1 : 0)) >>> 0; + c[4] = (c[4] + 0xD34D34D3 + ((c[3] >>> 0) < (c_old[3] >>> 0) ? 1 : 0)) >>> 0; + c[5] = (c[5] + 0x34D34D34 + ((c[4] >>> 0) < (c_old[4] >>> 0) ? 1 : 0)) >>> 0; + c[6] = (c[6] + 0x4D34D34D + ((c[5] >>> 0) < (c_old[5] >>> 0) ? 1 : 0)) >>> 0; + c[7] = (c[7] + 0xD34D34D3 + ((c[6] >>> 0) < (c_old[6] >>> 0) ? 1 : 0)) >>> 0; + b = (c[7] >>> 0) < (c_old[7] >>> 0) ? 1 : 0; + + // Calculate the g-values + for (var g = [], i = 0; i < 8; i++) { + + var gx = (x[i] + c[i]) >>> 0; + + // Construct high and low argument for squaring + var ga = gx & 0xFFFF, + gb = gx >>> 16; + + // Calculate high and low result of squaring + var gh = ((((ga * ga) >>> 17) + ga * gb) >>> 15) + gb * gb, + gl = (((gx & 0xFFFF0000) * gx) >>> 0) + (((gx & 0x0000FFFF) * gx) >>> 0) >>> 0; + + // High XOR low + g[i] = gh ^ gl; + + } + + // Calculate new state values + x[0] = g[0] + ((g[7] << 16) | (g[7] >>> 16)) + ((g[6] << 16) | (g[6] >>> 16)); + x[1] = g[1] + ((g[0] << 8) | (g[0] >>> 24)) + g[7]; + x[2] = g[2] + ((g[1] << 16) | (g[1] >>> 16)) + ((g[0] << 16) | (g[0] >>> 16)); + x[3] = g[3] + ((g[2] << 8) | (g[2] >>> 24)) + g[1]; + x[4] = g[4] + ((g[3] << 16) | (g[3] >>> 16)) + ((g[2] << 16) | (g[2] >>> 16)); + x[5] = g[5] + ((g[4] << 8) | (g[4] >>> 24)) + g[3]; + x[6] = g[6] + ((g[5] << 16) | (g[5] >>> 16)) + ((g[4] << 16) | (g[4] >>> 16)); + x[7] = g[7] + ((g[6] << 8) | (g[6] >>> 24)) + g[5]; + + } + +}; + +})(); diff --git a/tools/Crypto-JS v2.4.0/sha1/sha1-min.js b/tools/Crypto-JS v2.4.0/sha1/sha1-min.js index 199bcdf..438fc27 100755 --- a/tools/Crypto-JS v2.4.0/sha1/sha1-min.js +++ b/tools/Crypto-JS v2.4.0/sha1/sha1-min.js @@ -1,8 +1,8 @@ -/* - * Crypto-JS v2.4.0 - * http://code.google.com/p/crypto-js/ - * Copyright (c) 2011, Jeff Mott. All rights reserved. - * http://code.google.com/p/crypto-js/wiki/License - */ +/* + * Crypto-JS v2.4.0 + * http://code.google.com/p/crypto-js/ + * Copyright (c) 2011, Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ (function(){var l=Crypto,m=l.util,n=l.charenc,o=n.UTF8,p=n.Binary,j=l.SHA1=function(a,g){var c=m.wordsToBytes(j._sha1(a));return g&&g.asBytes?c:g&&g.asString?p.bytesToString(c):m.bytesToHex(c)};j._sha1=function(a){if(a.constructor==String)a=o.stringToBytes(a);var g=m.bytesToWords(a),c=a.length*8;a=[];var h=1732584193,d=-271733879,e=-1732584194,f=271733878,i=-1009589776;g[c>>5]|=128<<24-c%32;g[(c+64>>>9<<4)+15]=c;for(c=0;c>>31}k=(h<<5|h>>>27)+i+(a[b]>>>0)+(b<20?(d&e|~d&f)+1518500249:b<40?(d^e^f)+1859775393:b<60?(d&e|d&f|e&f)-1894007588:(d^e^f)-899497514);i=f;f=e;e=d<<30|d>>>2;d=h;h=k}h+=q;d+=r;e+=s;f+=t;i+=u}return[h,d,e,f,i]};j._blocksize=16;j._digestsize=20})(); diff --git a/tools/Crypto-JS v2.4.0/sha1/sha1.js b/tools/Crypto-JS v2.4.0/sha1/sha1.js index cacb84a..5c5e1eb 100755 --- a/tools/Crypto-JS v2.4.0/sha1/sha1.js +++ b/tools/Crypto-JS v2.4.0/sha1/sha1.js @@ -1,91 +1,91 @@ -/* - * Crypto-JS v2.4.0 - * http://code.google.com/p/crypto-js/ - * Copyright (c) 2011, Jeff Mott. All rights reserved. - * http://code.google.com/p/crypto-js/wiki/License - */ -(function(){ - -// Shortcuts -var C = Crypto, - util = C.util, - charenc = C.charenc, - UTF8 = charenc.UTF8, - Binary = charenc.Binary; - -// Public API -var SHA1 = C.SHA1 = function (message, options) { - var digestbytes = util.wordsToBytes(SHA1._sha1(message)); - return options && options.asBytes ? digestbytes : - options && options.asString ? Binary.bytesToString(digestbytes) : - util.bytesToHex(digestbytes); -}; - -// The core -SHA1._sha1 = function (message) { - - // Convert to byte array - if (message.constructor == String) message = UTF8.stringToBytes(message); - /* else, assume byte array already */ - - var m = util.bytesToWords(message), - l = message.length * 8, - w = [], - H0 = 1732584193, - H1 = -271733879, - H2 = -1732584194, - H3 = 271733878, - H4 = -1009589776; - - // Padding - m[l >> 5] |= 0x80 << (24 - l % 32); - m[((l + 64 >>> 9) << 4) + 15] = l; - - for (var i = 0; i < m.length; i += 16) { - - var a = H0, - b = H1, - c = H2, - d = H3, - e = H4; - - for (var j = 0; j < 80; j++) { - - if (j < 16) w[j] = m[i + j]; - else { - var n = w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16]; - w[j] = (n << 1) | (n >>> 31); - } - - var t = ((H0 << 5) | (H0 >>> 27)) + H4 + (w[j] >>> 0) + ( - j < 20 ? (H1 & H2 | ~H1 & H3) + 1518500249 : - j < 40 ? (H1 ^ H2 ^ H3) + 1859775393 : - j < 60 ? (H1 & H2 | H1 & H3 | H2 & H3) - 1894007588 : - (H1 ^ H2 ^ H3) - 899497514); - - H4 = H3; - H3 = H2; - H2 = (H1 << 30) | (H1 >>> 2); - H1 = H0; - H0 = t; - - } - - H0 += a; - H1 += b; - H2 += c; - H3 += d; - H4 += e; - - } - - return [H0, H1, H2, H3, H4]; - -}; - -// Package private blocksize -SHA1._blocksize = 16; - -SHA1._digestsize = 20; - -})(); +/* + * Crypto-JS v2.4.0 + * http://code.google.com/p/crypto-js/ + * Copyright (c) 2011, Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ +(function(){ + +// Shortcuts +var C = Crypto, + util = C.util, + charenc = C.charenc, + UTF8 = charenc.UTF8, + Binary = charenc.Binary; + +// Public API +var SHA1 = C.SHA1 = function (message, options) { + var digestbytes = util.wordsToBytes(SHA1._sha1(message)); + return options && options.asBytes ? digestbytes : + options && options.asString ? Binary.bytesToString(digestbytes) : + util.bytesToHex(digestbytes); +}; + +// The core +SHA1._sha1 = function (message) { + + // Convert to byte array + if (message.constructor == String) message = UTF8.stringToBytes(message); + /* else, assume byte array already */ + + var m = util.bytesToWords(message), + l = message.length * 8, + w = [], + H0 = 1732584193, + H1 = -271733879, + H2 = -1732584194, + H3 = 271733878, + H4 = -1009589776; + + // Padding + m[l >> 5] |= 0x80 << (24 - l % 32); + m[((l + 64 >>> 9) << 4) + 15] = l; + + for (var i = 0; i < m.length; i += 16) { + + var a = H0, + b = H1, + c = H2, + d = H3, + e = H4; + + for (var j = 0; j < 80; j++) { + + if (j < 16) w[j] = m[i + j]; + else { + var n = w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16]; + w[j] = (n << 1) | (n >>> 31); + } + + var t = ((H0 << 5) | (H0 >>> 27)) + H4 + (w[j] >>> 0) + ( + j < 20 ? (H1 & H2 | ~H1 & H3) + 1518500249 : + j < 40 ? (H1 ^ H2 ^ H3) + 1859775393 : + j < 60 ? (H1 & H2 | H1 & H3 | H2 & H3) - 1894007588 : + (H1 ^ H2 ^ H3) - 899497514); + + H4 = H3; + H3 = H2; + H2 = (H1 << 30) | (H1 >>> 2); + H1 = H0; + H0 = t; + + } + + H0 += a; + H1 += b; + H2 += c; + H3 += d; + H4 += e; + + } + + return [H0, H1, H2, H3, H4]; + +}; + +// Package private blocksize +SHA1._blocksize = 16; + +SHA1._digestsize = 20; + +})(); diff --git a/tools/Crypto-JS v2.4.0/sha256/sha256-min.js b/tools/Crypto-JS v2.4.0/sha256/sha256-min.js index 7932704..f4b8cb5 100755 --- a/tools/Crypto-JS v2.4.0/sha256/sha256-min.js +++ b/tools/Crypto-JS v2.4.0/sha256/sha256-min.js @@ -1,9 +1,9 @@ -/* - * Crypto-JS v2.4.0 - * http://code.google.com/p/crypto-js/ - * Copyright (c) 2011, Jeff Mott. All rights reserved. - * http://code.google.com/p/crypto-js/wiki/License - */ +/* + * Crypto-JS v2.4.0 + * http://code.google.com/p/crypto-js/ + * Copyright (c) 2011, Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ (function(){var q=Crypto,r=q.util,s=q.charenc,t=s.UTF8,u=s.Binary,v=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921, 2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],m=q.SHA256=function(a,f){var b=r.wordsToBytes(m._sha256(a));return f&&f.asBytes?b:f&&f.asString?u.bytesToString(b):r.bytesToHex(b)};m._sha256=function(a){if(a.constructor==String)a=t.stringToBytes(a);var f=r.bytesToWords(a),b=a.length*8;a=[1779033703,3144134277, 1013904242,2773480762,1359893119,2600822924,528734635,1541459225];var h=[],i,j,n,d,k,l,o,p,c,g,e;f[b>>5]|=128<<24-b%32;f[(b+64>>9<<4)+15]=b;for(p=0;p>>7)^(g<<14|g>>>18)^g>>>3)+(h[c-7]>>>0)+((e<<15|e>>>17)^(e<<13|e>>>19)^e>>>10)+(h[c-16]>>>0)}e=b&i^b&j^i&j;var w=(b<<30|b>>>2)^(b<<19|b>>>13)^(b<<10|b>>>22);g=(o>>>0)+((d<<26|d>>>6)^(d<<21|d>>>11)^(d<<7| diff --git a/tools/Crypto-JS v2.4.0/sha256/sha256.js b/tools/Crypto-JS v2.4.0/sha256/sha256.js index e3e2969..67a5dda 100755 --- a/tools/Crypto-JS v2.4.0/sha256/sha256.js +++ b/tools/Crypto-JS v2.4.0/sha256/sha256.js @@ -1,135 +1,135 @@ -/* - * Crypto-JS v2.4.0 - * http://code.google.com/p/crypto-js/ - * Copyright (c) 2011, Jeff Mott. All rights reserved. - * http://code.google.com/p/crypto-js/wiki/License - */ -(function(){ - -// Shortcuts -var C = Crypto, - util = C.util, - charenc = C.charenc, - UTF8 = charenc.UTF8, - Binary = charenc.Binary; - -// Constants -var K = [ 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, - 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, - 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, - 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, - 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, - 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, - 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, - 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967, - 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, - 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, - 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, - 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, - 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, - 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, - 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, - 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2 ]; - -// Public API -var SHA256 = C.SHA256 = function (message, options) { - var digestbytes = util.wordsToBytes(SHA256._sha256(message)); - return options && options.asBytes ? digestbytes : - options && options.asString ? Binary.bytesToString(digestbytes) : - util.bytesToHex(digestbytes); -}; - -// The core -SHA256._sha256 = function (message) { - - // Convert to byte array - if (message.constructor == String) message = UTF8.stringToBytes(message); - /* else, assume byte array already */ - - var m = util.bytesToWords(message), - l = message.length * 8, - H = [ 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, - 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 ], - w = [], - a, b, c, d, e, f, g, h, i, j, - t1, t2; - - // Padding - m[l >> 5] |= 0x80 << (24 - l % 32); - m[((l + 64 >> 9) << 4) + 15] = l; - - for (var i = 0; i < m.length; i += 16) { - - a = H[0]; - b = H[1]; - c = H[2]; - d = H[3]; - e = H[4]; - f = H[5]; - g = H[6]; - h = H[7]; - - for (var j = 0; j < 64; j++) { - - if (j < 16) w[j] = m[j + i]; - else { - - var gamma0x = w[j - 15], - gamma1x = w[j - 2], - gamma0 = ((gamma0x << 25) | (gamma0x >>> 7)) ^ - ((gamma0x << 14) | (gamma0x >>> 18)) ^ - (gamma0x >>> 3), - gamma1 = ((gamma1x << 15) | (gamma1x >>> 17)) ^ - ((gamma1x << 13) | (gamma1x >>> 19)) ^ - (gamma1x >>> 10); - - w[j] = gamma0 + (w[j - 7] >>> 0) + - gamma1 + (w[j - 16] >>> 0); - - } - - var ch = e & f ^ ~e & g, - maj = a & b ^ a & c ^ b & c, - sigma0 = ((a << 30) | (a >>> 2)) ^ - ((a << 19) | (a >>> 13)) ^ - ((a << 10) | (a >>> 22)), - sigma1 = ((e << 26) | (e >>> 6)) ^ - ((e << 21) | (e >>> 11)) ^ - ((e << 7) | (e >>> 25)); - - - t1 = (h >>> 0) + sigma1 + ch + (K[j]) + (w[j] >>> 0); - t2 = sigma0 + maj; - - h = g; - g = f; - f = e; - e = d + t1; - d = c; - c = b; - b = a; - a = t1 + t2; - - } - - H[0] += a; - H[1] += b; - H[2] += c; - H[3] += d; - H[4] += e; - H[5] += f; - H[6] += g; - H[7] += h; - - } - - return H; - -}; - -// Package private blocksize -SHA256._blocksize = 16; - -SHA256._digestsize = 32; - -})(); +/* + * Crypto-JS v2.4.0 + * http://code.google.com/p/crypto-js/ + * Copyright (c) 2011, Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ +(function(){ + +// Shortcuts +var C = Crypto, + util = C.util, + charenc = C.charenc, + UTF8 = charenc.UTF8, + Binary = charenc.Binary; + +// Constants +var K = [ 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, + 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, + 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, + 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, + 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, + 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, + 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, + 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967, + 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, + 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, + 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, + 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, + 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, + 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, + 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, + 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2 ]; + +// Public API +var SHA256 = C.SHA256 = function (message, options) { + var digestbytes = util.wordsToBytes(SHA256._sha256(message)); + return options && options.asBytes ? digestbytes : + options && options.asString ? Binary.bytesToString(digestbytes) : + util.bytesToHex(digestbytes); +}; + +// The core +SHA256._sha256 = function (message) { + + // Convert to byte array + if (message.constructor == String) message = UTF8.stringToBytes(message); + /* else, assume byte array already */ + + var m = util.bytesToWords(message), + l = message.length * 8, + H = [ 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, + 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 ], + w = [], + a, b, c, d, e, f, g, h, i, j, + t1, t2; + + // Padding + m[l >> 5] |= 0x80 << (24 - l % 32); + m[((l + 64 >> 9) << 4) + 15] = l; + + for (var i = 0; i < m.length; i += 16) { + + a = H[0]; + b = H[1]; + c = H[2]; + d = H[3]; + e = H[4]; + f = H[5]; + g = H[6]; + h = H[7]; + + for (var j = 0; j < 64; j++) { + + if (j < 16) w[j] = m[j + i]; + else { + + var gamma0x = w[j - 15], + gamma1x = w[j - 2], + gamma0 = ((gamma0x << 25) | (gamma0x >>> 7)) ^ + ((gamma0x << 14) | (gamma0x >>> 18)) ^ + (gamma0x >>> 3), + gamma1 = ((gamma1x << 15) | (gamma1x >>> 17)) ^ + ((gamma1x << 13) | (gamma1x >>> 19)) ^ + (gamma1x >>> 10); + + w[j] = gamma0 + (w[j - 7] >>> 0) + + gamma1 + (w[j - 16] >>> 0); + + } + + var ch = e & f ^ ~e & g, + maj = a & b ^ a & c ^ b & c, + sigma0 = ((a << 30) | (a >>> 2)) ^ + ((a << 19) | (a >>> 13)) ^ + ((a << 10) | (a >>> 22)), + sigma1 = ((e << 26) | (e >>> 6)) ^ + ((e << 21) | (e >>> 11)) ^ + ((e << 7) | (e >>> 25)); + + + t1 = (h >>> 0) + sigma1 + ch + (K[j]) + (w[j] >>> 0); + t2 = sigma0 + maj; + + h = g; + g = f; + f = e; + e = d + t1; + d = c; + c = b; + b = a; + a = t1 + t2; + + } + + H[0] += a; + H[1] += b; + H[2] += c; + H[3] += d; + H[4] += e; + H[5] += f; + H[6] += g; + H[7] += h; + + } + + return H; + +}; + +// Package private blocksize +SHA256._blocksize = 16; + +SHA256._digestsize = 32; + +})(); diff --git a/tools/README.md b/tools/README.md index cb50f36..7729d1c 100644 --- a/tools/README.md +++ b/tools/README.md @@ -1,7 +1,7 @@ The /tools directory ==================== -This directory contains build/test scripts for numeric.js as well as +This directory contains build/test scripts for numeric.js as well as js libraries needed by the Workshop. Building diff --git a/tools/XMLHttpRequest.js b/tools/XMLHttpRequest.js index 54a3875..6ecaf68 100644 --- a/tools/XMLHttpRequest.js +++ b/tools/XMLHttpRequest.js @@ -15,200 +15,200 @@ var sys = require('sys'); */ exports.XMLHttpRequest = function() { - /** - * Private variables - */ - var self = this; - var http = require('http'); - - // Holds http.js objects - var client; - var request; - var response; - - var settings = {}; // Request settings - - var defaultHeaders = { - "User-Agent": "node.js", - "Accept": "*/*", - }; - - var headers = defaultHeaders; - - this.UNSENT = 0; - this.OPENED = 1; - this.HEADERS_RECEIVED = 2; - this.LOADING = 3; - this.DONE = 4; - - this.readyState = this.UNSENT; // Current state - - // Result & response - this.responseText = ""; - this.responseXML = ""; - this.status = null; - this.statusText = null; - - /** - * Open the connection. Currently supports local server requests. - * - * @param string method Connection method (eg GET, POST) - * @param string url URL for the connection. - * @param boolean async Asynchronous connection. Default is true. - * @param string user Username for basic authentication (optional) - * @param string password Password for basic authentication (optional) - */ - this.open = function(method, url, async, user, password) { - settings = { - "method": method, - "url": url, - "async": async, - "user": user, - "password": password - }; - - this.abort(); - - setState(this.OPENED); - }; - - /** - * Sets a header for the request. - * - * @param string header Header name - * @param string value Header value - */ - this.setRequestHeader = function(header, value) { - headers[header] = value; - }; - - /** - * Gets a header from the server response. - * - * @param string header Name of header to get. - * @return string Text of the header or null if it doesn't exist. - */ - this.getResponseHeader = function(header) { - if (this.readyState > this.OPENED && response.headers.header) { - return header + ": " + response.headers.header; - } - - return null; - }; - - /** - * Gets all the response headers. - * - * @return string - */ - this.getAllResponseHeaders = function() { - if (this.readyState < this.HEADERS_RECEIVED) { - throw "INVALID_STATE_ERR: Headers have not been received."; - } - var result = ""; - - for (var i in response.headers) { - result += i + ": " + response.headers[i] + "\r\n"; - } - return result.substr(0, result.length - 2); - }; - - /** - * Sends the request to the server. - * - * @param string data Optional data to send as request body. - */ + /** + * Private variables + */ + var self = this; + var http = require('http'); + + // Holds http.js objects + var client; + var request; + var response; + + var settings = {}; // Request settings + + var defaultHeaders = { + "User-Agent": "node.js", + "Accept": "*/*", + }; + + var headers = defaultHeaders; + + this.UNSENT = 0; + this.OPENED = 1; + this.HEADERS_RECEIVED = 2; + this.LOADING = 3; + this.DONE = 4; + + this.readyState = this.UNSENT; // Current state + + // Result & response + this.responseText = ""; + this.responseXML = ""; + this.status = null; + this.statusText = null; + + /** + * Open the connection. Currently supports local server requests. + * + * @param string method Connection method (eg GET, POST) + * @param string url URL for the connection. + * @param boolean async Asynchronous connection. Default is true. + * @param string user Username for basic authentication (optional) + * @param string password Password for basic authentication (optional) + */ + this.open = function(method, url, async, user, password) { + settings = { + "method": method, + "url": url, + "async": async, + "user": user, + "password": password + }; + + this.abort(); + + setState(this.OPENED); + }; + + /** + * Sets a header for the request. + * + * @param string header Header name + * @param string value Header value + */ + this.setRequestHeader = function(header, value) { + headers[header] = value; + }; + + /** + * Gets a header from the server response. + * + * @param string header Name of header to get. + * @return string Text of the header or null if it doesn't exist. + */ + this.getResponseHeader = function(header) { + if (this.readyState > this.OPENED && response.headers.header) { + return header + ": " + response.headers.header; + } + + return null; + }; + + /** + * Gets all the response headers. + * + * @return string + */ + this.getAllResponseHeaders = function() { + if (this.readyState < this.HEADERS_RECEIVED) { + throw "INVALID_STATE_ERR: Headers have not been received."; + } + var result = ""; + + for (var i in response.headers) { + result += i + ": " + response.headers[i] + "\r\n"; + } + return result.substr(0, result.length - 2); + }; + + /** + * Sends the request to the server. + * + * @param string data Optional data to send as request body. + */ this.send = function(data) { if (this.readyState != this.OPENED) { throw "INVALID_STATE_ERR: connection must be opened before send() is called"; - } - - /** + } + + /** * Figure out if a host and/or port were specified. Regex borrowed - * from parseUri and modified. Needs additional optimization. + * from parseUri and modified. Needs additional optimization. * @see http://blog.stevenlevithan.com/archives/parseuri - */ - var loc = /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?([^?#]*)/.exec(settings.url); - - // Determine the server - switch (loc[1]) { - case 'http': - var host = loc[6]; - break; - - case undefined: - case '': - var host = "localhost"; - break; - - case 'https': - throw "SSL is not implemented."; - break; - - default: - throw "Protocol not supported."; - } - + */ + var loc = /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?([^?#]*)/.exec(settings.url); + + // Determine the server + switch (loc[1]) { + case 'http': + var host = loc[6]; + break; + + case undefined: + case '': + var host = "localhost"; + break; + + case 'https': + throw "SSL is not implemented."; + break; + + default: + throw "Protocol not supported."; + } + // Default to port 80. If accessing localhost on another port be sure // to use http://localhost:port/path - var port = loc[7] || 80; - - var uri = loc[8] || "/"; - - // Set the Host header or the server may reject the request - headers["Host"] = host; - - client = http.createClient(port, host); - - if (settings.method == "GET" || settings.method == "HEAD") { - data = null; - } else if (data) { - headers["Content-Length"] = data.length; - - if (!headers["Content-Type"]) { - headers["Content-Type"] = "text/plain;charset=UTF-8"; - } - } - - // Use the correct request method + var port = loc[7] || 80; + + var uri = loc[8] || "/"; + + // Set the Host header or the server may reject the request + headers["Host"] = host; + + client = http.createClient(port, host); + + if (settings.method == "GET" || settings.method == "HEAD") { + data = null; + } else if (data) { + headers["Content-Length"] = data.length; + + if (!headers["Content-Type"]) { + headers["Content-Type"] = "text/plain;charset=UTF-8"; + } + } + + // Use the correct request method request = client.request(settings.method, uri, headers); - if (data) request.write(data); + if (data) request.write(data); request.addListener("response", function(resp) { response = resp; - response.setEncoding("utf8"); - - setState(self.HEADERS_RECEIVED); - self.status = response.statusCode; - - response.addListener("data", function(chunk) { - // Make sure there's some data - if (chunk) { - self.responseText += chunk; - } - setState(self.LOADING); - }); - - response.addListener("end", function() { - setState(self.DONE); - }); + response.setEncoding("utf8"); + + setState(self.HEADERS_RECEIVED); + self.status = response.statusCode; + + response.addListener("data", function(chunk) { + // Make sure there's some data + if (chunk) { + self.responseText += chunk; + } + setState(self.LOADING); + }); + + response.addListener("end", function() { + setState(self.DONE); + }); }); request.end(); - }; - - /** - * Aborts a request. - */ - this.abort = function() { - headers = defaultHeaders; - this.readyState = this.UNSENT; - this.responseText = ""; - this.responseXML = ""; - }; - - var setState = function(state) { - self.readyState = state; - self.onreadystatechange(); - } + }; + + /** + * Aborts a request. + */ + this.abort = function() { + headers = defaultHeaders; + this.readyState = this.UNSENT; + this.responseText = ""; + this.responseXML = ""; + }; + + var setState = function(state) { + self.readyState = state; + self.onreadystatechange(); + } }; diff --git a/tools/build.sh b/tools/build.sh index fe3be4b..f952b06 100755 --- a/tools/build.sh +++ b/tools/build.sh @@ -2,22 +2,23 @@ home=`dirname $0` cd $home if [ -f buildpid.log ]; then - buildpid=`cat buildpid.log` - kill -9 $buildpid || true - rm -f buildpid.log + buildpid=`cat buildpid.log` + kill -9 $buildpid || true + rm -f buildpid.log fi echo $$ > buildpid.log if [ -f nodepid.log ]; then - nodepid=`cat nodepid.log` - kill -9 $nodepid || true - rm -f nodepid.log + nodepid=`cat nodepid.log` + kill -9 $nodepid || true + rm -f nodepid.log fi -ver=`grep 'numeric.version.*=.*"' ../src/numeric.js | sed 's/numeric.version[ =]*"\([0-9.]*\)".*/\1/'` +ver=`grep 'numeric.version.*=.*"' ../src/numeric.js | sed 's/numeric.version[ =]*"\([0-9.\-]*\)".*/\1/'` echo "Version is $ver" -cat ../src/numeric.js ../src/seedrandom.js ../src/quadprog.js ../src/svd.js > ../lib/numeric-$ver.js -uglifyjs ../lib/numeric-$ver.js > ../lib/numeric-$ver.min.js -cat jquery-1.7.1.min.js jquery.flot.min.js 'Crypto-JS v2.4.0/crypto/crypto-min.js' 'Crypto-JS v2.4.0/crypto-sha256/crypto-sha256.js' json2.js > megalib.js -echo "" | cat closurelib.js sylvester.js - ../lib/numeric-$ver.min.js jquery-1.7.1.min.js jquery.flot.min.js > benchlib.js +cat ../src/intro.js ../src/numeric.js ../src/seedrandom.js ../src/quadprog.js ../src/svd.js ../src/iterative.js ../src/newton.js ../src/uniroot.js ../src/sparse2.js ../src/outro.js > ../lib/numeric-$ver.js +cp ../lib/numeric-$ver.js ../lib/numeric.latest.js +../node_modules/.bin/uglifyjs ../lib/numeric-$ver.js > ../lib/numeric-$ver.min.js +cat jquery-1.7.1.js jquery.flot.js 'Crypto-JS v2.4.0/crypto/crypto.js' 'Crypto-JS v2.4.0/crypto-sha256/crypto-sha256.js' json2.js > megalib.js +echo "" | cat closurelib.js sylvester.js - ../lib/numeric-$ver.js jquery-1.7.1.js jquery.flot.js > benchlib.js cat > ../resources/header.html <Fork me on GitHub