Skip to content

Commit 85ddf00

Browse files
author
Sébastien Loisel
committed
quadratic programming mainly
1 parent 9473592 commit 85ddf00

10 files changed

+792
-22
lines changed

documentation.html

+78-7
Original file line numberDiff line numberDiff line change
@@ -414,9 +414,15 @@ <h1>Data manipulation</h1>
414414
[[ "a", "b", "c"],
415415
[ 1, 2.3, 0.3],
416416
[ 4.000e6, -5.3e-8, 62800]]
417+
> numeric.toCSV([[1.23456789123,2],[3,4]])
418+
"1.235,2
419+
3,4
420+
"
417421
</pre>
422+
Note that <tt>numeric.toCSV()</tt> uses <tt>numeric.prettyPrint()</tt> to print numbers. To obtain more
423+
digits, set <tt>numeric.precision</tt> to the desired number of digits of accuracy.
418424

419-
You can also fetch a URL:
425+
You can also fetch a URL (a thin wrapper around XMLHttpRequest):
420426
<pre>
421427
> numeric.getURL('tools/helloworld.txt').responseText
422428
"Hello, world!"
@@ -572,6 +578,19 @@ <h1>Sparse linear algebra</h1>
572578
> sparse.LUPsolve(lup,b)
573579
[3,1,7]
574580
</pre>
581+
582+
<!--
583+
Some more tests.
584+
<pre>
585+
> sparse.dot([1,2,3],[,4,5])
586+
23
587+
> sparse.dot([1, ,3],[[4,5,],[,6,7],[1,,8]])
588+
[7,5,24]
589+
> sparse.dot([[3,1],[4,5,9],[,3,2]],[7,3])
590+
[24,43,9]
591+
</pre>
592+
-->
593+
575594
The <tt>sparse.scatter()</tt> and <tt>sparse.gather()</tt> functions can be used to convert between
576595
sparse matrices and the coordinate encoding:
577596
<pre>
@@ -637,15 +656,67 @@ <h1>Solving PDEs</h1>
637656
[1,1,1,1,1,1,1,1,1]
638657
</pre>
639658

659+
You can also work on an L-shaped or arbitrary-shape domain:
660+
<pre>
661+
> coord.grid(6,'L')
662+
[[-1,-1,-1,-1,-1,-1],
663+
[-1, 0, 1,-1,-1,-1],
664+
[-1, 2, 3,-1,-1,-1],
665+
[-1, 4, 5, 6, 7,-1],
666+
[-1, 8, 9,10,11,-1],
667+
[-1,-1,-1,-1,-1,-1]]
668+
> coord.grid(5,function(i,j) { return i!==2 || j!==2; })
669+
[[-1,-1,-1,-1,-1],
670+
[-1, 0, 1, 2,-1],
671+
[-1, 3,-1, 4,-1],
672+
[-1, 5, 6, 7,-1],
673+
[-1,-1,-1,-1,-1]]
674+
</pre>
675+
676+
<h1>Quadratic Programming (Alberto Santini)</h1>
677+
678+
The Quadratic Programming function <tt>numeric.solveQP()</tt> is based on <a href="https://github.com/albertosantini/node-quadprog">Alberto Santini's
679+
quadprog</a>, which is itself a port of the corresponding
680+
R routines.
681+
682+
<pre>
683+
> numeric.solveQP([[1,0,0],[0,1,0],[0,0,1]],[0,5,0],[[-4,2,0],[-3,1,-2],[0,0,1]],[-8,2,0]);
684+
{ solution: [0.4762,1.048,2.095],
685+
value: [-2.381],
686+
unconstrained_solution:[ 0, 5, 0],
687+
iterations: [ 3, 0],
688+
iact: [ 3, 2, 0],
689+
message:"" }
690+
</pre>
691+
640692
<!--
641693
<pre>
642-
> sparse.dot([1,2,3],[,4,5])
643-
23
644-
> sparse.dot([1, ,3],[[4,5,],[,6,7],[1,,8]])
645-
[7,5,24]
646-
> sparse.dot([[3,1],[4,5,9],[,3,2]],[7,3])
647-
[24,43,9]
694+
> D = numeric.identity(8); d = numeric.rep([8],0); A = [[1, 1, -1, 0, 0, 0, 0, 0, 0, 0],[-1, 1, 0, 1, 0, 0, 0, 0, 0, 0],[1, 1, 0, 0, -1, 0, 0, 0, 0, 0],[-1, 1, 0, 0, 0, 1, 0, 0, 0, 0],[1, 1, 0, 0, 0, 0, -1, 0, 0, 0],[-1, 1, 0, 0, 0, 0, 0, 1, 0, 0],[1, 1, 0, 0, 0, 0, 0, 0, -1, 0],[-1, 1, 0, 0, 0, 0, 0, 0, 0, 1]]; b = [1, 1, -1, 0, -1, 0, -1, 0, -1, 0]; numeric.solveQP(D,d,A,b,undefined,2)
695+
{ solution: [0.25,0,0.25,0,0.25,0,0.25,0],
696+
value: [0.125],
697+
unconstrained_solution:[0,0,0,0,0,0,0,0],
698+
iterations: [3,0],
699+
iact: [1,2,0,0,0,0,0,0,0,0],
700+
message: ""}
648701
</pre>
649702
-->
650703

704+
<h1>Seedrandom (David Bau)</h1>
705+
706+
The object <tt>numeric.seedrandom</tt> is based on
707+
<a href="http://davidbau.com/archives/2010/01/30/random_seeds_coded_hints_and_quintillions.html">David Bau's <tt>seedrandom.js</tt></a>.
708+
This small library can be used to create better pseudorandom numbers than <tt>Math.random()</tt> which can
709+
furthermore be "seeded".
710+
<pre>
711+
> numeric.seedrandom.seedrandom(3); numeric.seedrandom.random()
712+
0.7569
713+
> numeric.seedrandom.random()
714+
0.6139
715+
> numeric.seedrandom.seedrandom(3); numeric.seedrandom.random()
716+
0.7569
717+
</pre>
718+
For performance reasons, <tt>numeric.random()</tt> uses the default <tt>Math.random()</tt>. If you want to use
719+
the seedrandom version, just do <tt>Math.random = numeric.seedrandom.random</tt>. Note that this may slightly
720+
decrease the performance of all <tt>Math</tt> operations.
721+
651722
<br><br><br>
File renamed without changes.

license.txt

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
(See also licenses in the resources subdirectory.)
2+
13
Numeric Javascript
24
Copyright (C) 2011 by Sébastien Loisel
35

resources/LICENSE.quadprog

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
(The MIT License)
2+
3+
Copyright (c) 2011 Alberto Santini <[email protected]>
4+
5+
Permission is hereby granted, free of charge, to any person obtaining
6+
a copy of this software and associated documentation files (the
7+
'Software'), to deal in the Software without restriction, including
8+
without limitation the rights to use, copy, modify, merge, publish,
9+
distribute, sublicense, and/or sell copies of the Software, and to
10+
permit persons to whom the Software is furnished to do so, subject to
11+
the following conditions:
12+
13+
The above copyright notice and this permission notice shall be
14+
included in all copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
17+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23+

resources/style.css

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ body {
77
font-size: 18px;
88
height: 100%;
99
}
10+
pre { font-size:15px; }
1011
h1 {
1112
font-size: 22px;
1213
}

src/documentation.html

+78-7
Original file line numberDiff line numberDiff line change
@@ -414,9 +414,15 @@ <h1>Data manipulation</h1>
414414
[[ "a", "b", "c"],
415415
[ 1, 2.3, 0.3],
416416
[ 4.000e6, -5.3e-8, 62800]]
417+
> numeric.toCSV([[1.23456789123,2],[3,4]])
418+
"1.235,2
419+
3,4
420+
"
417421
</pre>
422+
Note that <tt>numeric.toCSV()</tt> uses <tt>numeric.prettyPrint()</tt> to print numbers. To obtain more
423+
digits, set <tt>numeric.precision</tt> to the desired number of digits of accuracy.
418424

419-
You can also fetch a URL:
425+
You can also fetch a URL (a thin wrapper around XMLHttpRequest):
420426
<pre>
421427
> numeric.getURL('tools/helloworld.txt').responseText
422428
"Hello, world!"
@@ -572,6 +578,19 @@ <h1>Sparse linear algebra</h1>
572578
> sparse.LUPsolve(lup,b)
573579
[3,1,7]
574580
</pre>
581+
582+
<!--
583+
Some more tests.
584+
<pre>
585+
> sparse.dot([1,2,3],[,4,5])
586+
23
587+
> sparse.dot([1, ,3],[[4,5,],[,6,7],[1,,8]])
588+
[7,5,24]
589+
> sparse.dot([[3,1],[4,5,9],[,3,2]],[7,3])
590+
[24,43,9]
591+
</pre>
592+
-->
593+
575594
The <tt>sparse.scatter()</tt> and <tt>sparse.gather()</tt> functions can be used to convert between
576595
sparse matrices and the coordinate encoding:
577596
<pre>
@@ -637,15 +656,67 @@ <h1>Solving PDEs</h1>
637656
[1,1,1,1,1,1,1,1,1]
638657
</pre>
639658

659+
You can also work on an L-shaped or arbitrary-shape domain:
660+
<pre>
661+
> coord.grid(6,'L')
662+
[[-1,-1,-1,-1,-1,-1],
663+
[-1, 0, 1,-1,-1,-1],
664+
[-1, 2, 3,-1,-1,-1],
665+
[-1, 4, 5, 6, 7,-1],
666+
[-1, 8, 9,10,11,-1],
667+
[-1,-1,-1,-1,-1,-1]]
668+
> coord.grid(5,function(i,j) { return i!==2 || j!==2; })
669+
[[-1,-1,-1,-1,-1],
670+
[-1, 0, 1, 2,-1],
671+
[-1, 3,-1, 4,-1],
672+
[-1, 5, 6, 7,-1],
673+
[-1,-1,-1,-1,-1]]
674+
</pre>
675+
676+
<h1>Quadratic Programming (Alberto Santini)</h1>
677+
678+
The Quadratic Programming function <tt>numeric.solveQP()</tt> is based on <a href="https://github.com/albertosantini/node-quadprog">Alberto Santini's
679+
quadprog</a>, which is itself a port of the corresponding
680+
R routines.
681+
682+
<pre>
683+
> numeric.solveQP([[1,0,0],[0,1,0],[0,0,1]],[0,5,0],[[-4,2,0],[-3,1,-2],[0,0,1]],[-8,2,0]);
684+
{ solution: [0.4762,1.048,2.095],
685+
value: [-2.381],
686+
unconstrained_solution:[ 0, 5, 0],
687+
iterations: [ 3, 0],
688+
iact: [ 3, 2, 0],
689+
message:"" }
690+
</pre>
691+
640692
<!--
641693
<pre>
642-
> sparse.dot([1,2,3],[,4,5])
643-
23
644-
> sparse.dot([1, ,3],[[4,5,],[,6,7],[1,,8]])
645-
[7,5,24]
646-
> sparse.dot([[3,1],[4,5,9],[,3,2]],[7,3])
647-
[24,43,9]
694+
> D = numeric.identity(8); d = numeric.rep([8],0); A = [[1, 1, -1, 0, 0, 0, 0, 0, 0, 0],[-1, 1, 0, 1, 0, 0, 0, 0, 0, 0],[1, 1, 0, 0, -1, 0, 0, 0, 0, 0],[-1, 1, 0, 0, 0, 1, 0, 0, 0, 0],[1, 1, 0, 0, 0, 0, -1, 0, 0, 0],[-1, 1, 0, 0, 0, 0, 0, 1, 0, 0],[1, 1, 0, 0, 0, 0, 0, 0, -1, 0],[-1, 1, 0, 0, 0, 0, 0, 0, 0, 1]]; b = [1, 1, -1, 0, -1, 0, -1, 0, -1, 0]; numeric.solveQP(D,d,A,b,undefined,2)
695+
{ solution: [0.25,0,0.25,0,0.25,0,0.25,0],
696+
value: [0.125],
697+
unconstrained_solution:[0,0,0,0,0,0,0,0],
698+
iterations: [3,0],
699+
iact: [1,2,0,0,0,0,0,0,0,0],
700+
message: ""}
648701
</pre>
649702
-->
650703

704+
<h1>Seedrandom (David Bau)</h1>
705+
706+
The object <tt>numeric.seedrandom</tt> is based on
707+
<a href="http://davidbau.com/archives/2010/01/30/random_seeds_coded_hints_and_quintillions.html">David Bau's <tt>seedrandom.js</tt></a>.
708+
This small library can be used to create better pseudorandom numbers than <tt>Math.random()</tt> which can
709+
furthermore be "seeded".
710+
<pre>
711+
> numeric.seedrandom.seedrandom(3); numeric.seedrandom.random()
712+
0.7569
713+
> numeric.seedrandom.random()
714+
0.6139
715+
> numeric.seedrandom.seedrandom(3); numeric.seedrandom.random()
716+
0.7569
717+
</pre>
718+
For performance reasons, <tt>numeric.random()</tt> uses the default <tt>Math.random()</tt>. If you want to use
719+
the seedrandom version, just do <tt>Math.random = numeric.seedrandom.random</tt>. Note that this may slightly
720+
decrease the performance of all <tt>Math</tt> operations.
721+
651722
<br><br><br>

src/numeric.js

+19-4
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,20 @@ numeric.parseCSV = function parseCSV(t) {
121121
return ret;
122122
}
123123

124+
numeric.toCSV = function toCSV(A) {
125+
var s = numeric.dim(A);
126+
var i,j,m,n,row,ret;
127+
m = s[0];
128+
n = s[1];
129+
ret = [];
130+
for(i=0;i<m;i++) {
131+
row = [];
132+
for(j=0;j<m;j++) { row[j] = numeric.prettyPrint(A[i][j]); }
133+
ret[i] = row.join(', ');
134+
}
135+
return ret.join('\n')+'\n';
136+
}
137+
124138
numeric.getURL = function getURL(url) {
125139
var client = new XMLHttpRequest();
126140
client.open("GET",url,false);
@@ -1565,20 +1579,21 @@ coord.LUsolve = function LUsolve(lu,b) {
15651579
};
15661580

15671581
coord.grid = function grid(n,shape) {
1568-
var ret = numeric.rep([n,n],-1);
1582+
if(typeof n === "number") n = [n,n];
1583+
var ret = numeric.rep(n,-1);
15691584
var i,j,count;
15701585
if(typeof shape !== "function") {
15711586
switch(shape) {
15721587
case 'L':
1573-
shape = function(i,j) { return i!=0 && i!=(n-1) && j!=0 && j!=(n-1) && (i<n/2 || j<n/2); }
1588+
shape = function(i,j) { return (i>=n[0]/2 || j<n[1]/2); }
15741589
break;
15751590
default:
1576-
shape = function(i,j) { return i!=0 && i!=(n-1) && j!=0 && j!=(n-1); };
1591+
shape = function(i,j) { return true; };
15771592
break;
15781593
}
15791594
}
15801595
count=0;
1581-
for(i=0;i<n;i++) for(j=0;j<n;j++)
1596+
for(i=1;i<n[0]-1;i++) for(j=1;j<n[1]-1;j++)
15821597
if(shape(i,j)) {
15831598
ret[i][j] = count;
15841599
count++;

0 commit comments

Comments
 (0)