You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

16502 lines
617 KiB
JavaScript

/////////////////////////////////////
/// Stand alone lalolib base functions
////////////////////////////////////
var printPrecision = 3; // number of digits to print
var LALOLibPlotsIndex = 0;
var LALOLibPlots = new Array();
var LALOLABPLOTMOVING = false;
//////////////////////////
//// Cross-browser compatibility
///////////////////////////
if( typeof(console) == "undefined" ) {
// for Safari
var console = {log: function ( ) { } };
}
if( typeof(Math.sign) == "undefined" ) {
// for IE, Safari
Math.sign = function ( x ) { return ( x>=0 ? (x==0 ? 0 : 1) : -1 ) ;}
}
//////////////////////////
//// printing
///////////////////////////
function laloprint( x , htmlId, append ) {
/*
use print(x) to print to the standard LALOLabOutput
use print(x, id) to print to another html entity
use str = print(x, true) to get the resulting string
*/
if ( typeof(htmlId) == "undefined" )
var htmlId = "LALOLibOutput";
if ( typeof(append) == "undefined" )
var append = true;
return printMat(x, size(x), htmlId, append ) ;
}
function printMat(A, size, htmlId, append) {
if (typeof(append) === "undefined")
var append = false;
if ( typeof(htmlId) == "undefined" || htmlId === true ) {
// return a string as [ [ .. , .. ] , [.. , ..] ]
if ( type(A) == "matrix" ) {
var str = "[";
var i;
var j;
var m = size[0];
var n = size[1];
for (i=0;i<m; i++) {
str += "[";
for ( j=0; j< n-1; j++)
str += printNumber(A.val[i*A.n+j]) + ",";
if ( i < m-1)
str += printNumber(A.val[i*A.n+j]) + "]; ";
else
str += printNumber(A.val[i*A.n+j]) + "]";
}
str += "]";
return str;
}
else if (type(A) == "vector" ) {
var n = A.length;
var str = "";
// Vector (one column)
for (var i=0;i<n; i++) {
str += "[ " + printNumber(A[i]) + " ]<br>";
}
console.log(str);
return str;
}
}
else {
// Produce HTML code and load it in htmlId
var html = "";
var i;
var j;
/*if (domathjax) {
html = tex ( A ) ;
}
else {*/
if ( isScalar(A) ) {
html += A + "<br>" ;
}
else if (type(A) == "vector" ) {
var n = size[0];
// Vector (one column)
for (i=0;i<n; i++) {
html += "[ " + printNumber(A[i]) + " ]<br>";
}
}
else {
// Matrix
var m = size[0];
var n = size[1];
for (i=0;i<m; i++) {
html += "[ ";
for(j=0;j < n - 1; j++) {
html += printNumber(A.val[i*A.n+j]) + ", ";
}
html += printNumber(A.val[i*A.n+j]) + " ]<br>";
}
}
//}
if (append)
document.getElementById(htmlId).innerHTML += html;
else
document.getElementById(htmlId).innerHTML = html;
/*
if ( domathjax)
MathJax.Hub.Queue(["Typeset",MathJax.Hub,"output"]);
*/
}
}
function printNumber ( x ) {
switch ( typeof(x) ) {
case "undefined":
return "" + 0;// for sparse matrices
break;
case "string":
/*if ( domathjax )
return "\\verb&" + x + "&";
else*/
return x;
break;
case "boolean":
return x;
break;
default:
if ( x == Infinity )
return "Inf";
if ( x == -Infinity )
return "-Inf";
var x_int = Math.floor(x);
if ( Math.abs( x - x_int ) < 2.23e-16 ) {
return "" + x_int;
}
else
return x.toFixed( printPrecision );
break;
}
}
//// Error handling
function error( msg ) {
throw new Error ( msg ) ;
// postMessage( {"error": msg} );
}
///////////
// Plots
//////////
function plot(multiargs) {
// plot(x,y,"style", x2,y2,"style",y3,"style",... )
// Part copied from lalolabworker.js
var data = new Array();
var styles = new Array();
var legends = new Array();
var minX = Infinity;
var maxX = -Infinity;
var minY = Infinity;
var maxY = -Infinity;
var p=0; // argument pointer
var x;
var y;
var style;
var i;
var n;
var c = 0; // index of current curve
while ( p < arguments.length) {
if ( type( arguments[p] ) == "vector" ) {
if ( p + 1 < arguments.length && type ( arguments[p+1] ) == "vector" ) {
// classic (x,y) arguments
x = arguments[p];
y = arguments[p+1];
p++;
}
else {
// only y provided => x = 0:n
y = arguments[p];
x = range(y.length);
}
}
else if ( type( arguments[p] ) == "matrix" ) {
// argument = [x, y]
if ( arguments[p].n == 1 ) {
y = arguments[p].val;
x = range(y.length);
}
else if (arguments[p].m == 1 ) {
y = arguments[p].val;
x = range(y.length);
}
else if ( arguments[p].n == 2 ) {
// 2 columns => [x,y]
x = getCols(arguments[p], [0]);
y = getCols(arguments[p], [1]);
}
else {
// more columns => trajectories as rows
x = range(arguments[p].n);
for ( var row = 0; row < arguments[p].m; row++) {
y = arguments[p].row(row);
data[c] = [new Array(x.length), new Array(x.length)];
for ( i=0; i < x.length; i++) {
data[c][0][i] = x[i];
data[c][1][i] = y[i];
if ( x[i] < minX )
minX = x[i];
if(x[i] > maxX )
maxX = x[i];
if ( y[i] > maxY )
maxY = y[i];
if ( y[i] < minY )
minY = y[i];
}
styles[c] = undefined;
legends[c] = "";
// Next curve
c++;
}
p++;
continue;
}
}
else {
return "undefined";
}
//Style
style = undefined;
if ( p + 1 < arguments.length && type ( arguments[p+1] ) == "string" ) {
style = arguments[p+1];
p++;
}
legend = "";
if ( p + 1 < arguments.length && type ( arguments[p+1] ) == "string" ) {
legend = arguments[p+1];
p++;
}
// Add the curve (x,y, style) to plot
data[c] = [new Array(x.length), new Array(x.length)];
for ( i=0; i < x.length; i++) {
data[c][0][i] = x[i];
data[c][1][i] = y[i];
if ( x[i] < minX )
minX = x[i];
if(x[i] > maxX )
maxX = x[i];
if ( y[i] > maxY )
maxY = y[i];
if ( y[i] < minY )
minY = y[i];
}
styles[c] = style;
legends[c] = legend;
// Next curve
c++;
p++; // from next argument
}
var widthX = maxX-minX;
var widthY = Math.max( maxY-minY, 1);
maxX += 0.1*widthX;
minX -= 0.1*widthX;
maxY += 0.1*widthY;
minY -= 0.1*widthY;
if ( minY > 0 )
minY = -0.1*maxY;
if ( maxY < 0 )
maxY = -0.1*minY;
var scaleY = 0.9 * (maxX-minX) / (2*maxY);
var plotinfo = {"data" : data, "minX" : minX, "maxX" : maxX, "minY" : minY, "maxY": maxY, "styles" : styles, "legend": legends };
//////// Part from laloplots.html //////////
var plotid = "LALOLibPlot" + LALOLibPlotsIndex;
var legendwidth = 50;
LALOLibOutput.innerHTML += "<br><div style='position:relative;left:0px;top:0px;text-align:left;'> <div><a onmousemove='mouseposition(event," + LALOLibPlotsIndex + ");' onmousedown='mousestartmove(event," + LALOLibPlotsIndex + ");' onmouseup='mousestopmove(event);' onmouseleave='mousestopmove(event);' ondblclick='zoomoriginal(" + LALOLibPlotsIndex + ");'><canvas id='" +plotid + "' width='500' height='500' style='border: 1px solid black;'></canvas></a></div> <label id='lblposition" + LALOLibPlotsIndex + "'></label> <div style='position: absolute;left: 550px;top: -1em;'> <canvas id='legend" + LALOLibPlotsIndex + "' width='" + legendwidth + "' height='500'></canvas></div> <div id='legendtxt" + LALOLibPlotsIndex + "' style='position: absolute;left: 610px;top: 0;'></div> </div>";
// prepare legend
var ylegend = 20;
// do plot
LALOLibPlots[LALOLibPlotsIndex] = new Plot(plotid) ;
LALOLibPlots[LALOLibPlotsIndex].setScalePlot(plotinfo.minX, plotinfo.maxX, 200, plotinfo.scaleY);
if ( plotinfo.minY && plotinfo.maxY ) {
LALOLibPlots[LALOLibPlotsIndex].view(plotinfo.minX, plotinfo.maxX, plotinfo.minY, plotinfo.maxY);
}
var colors = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,0];
var p;
var color;
for (p = 0; p<plotinfo.data.length; p++) {
var linestyle = true;
var pointstyle = true;
if ( typeof(plotinfo.styles[p]) == "string" ) {
if ( plotinfo.styles[p].indexOf(".") >= 0 ) {
linestyle = false;
plotinfo.styles[p] = plotinfo.styles[p].replace(".","");
}
if ( plotinfo.styles[p].indexOf("_") >= 0 ) {
pointstyle = false;
plotinfo.styles[p] = plotinfo.styles[p].replace("_","");
}
color = parseColor(plotinfo.styles[p]);
if ( color < 0 )
color = colors.splice(0,1)[0]; // pick next unused color
else
colors.splice(colors.indexOf(color),1); // remove this color
}
else
color = color = colors.splice(0,1)[0]; // pick next unused color
if ( typeof(color) == "undefined") // pick black if no next unused color
color = 0;
for ( i=0; i < plotinfo.data[p][0].length; i++) {
if ( pointstyle )
LALOLibPlots[LALOLibPlotsIndex].addPoint(plotinfo.data[p][0][i],plotinfo.data[p][1][i], color);
if ( linestyle && i < plotinfo.data[p][0].length-1 )
LALOLibPlots[LALOLibPlotsIndex].plot_line(plotinfo.data[p][0][i],plotinfo.data[p][1][i], plotinfo.data[p][0][i+1],plotinfo.data[p][1][i+1], color);
}
// Legend
if ( plotinfo.legend[p] != "" ) {
var ctx = document.getElementById("legend" +LALOLibPlotsIndex).getContext("2d");
setcolor(ctx, color);
ctx.lineWidth = "3";
if ( pointstyle ) {
ctx.beginPath();
ctx.arc( legendwidth/2 , ylegend, 5, 0, 2 * Math.PI , true);
ctx.closePath();
ctx.fill();
}
if( linestyle) {
ctx.beginPath();
ctx.moveTo ( 0,ylegend);
ctx.lineTo (legendwidth, ylegend);
ctx.stroke();
}
ylegend += 20;
document.getElementById("legendtxt" +LALOLibPlotsIndex).innerHTML += plotinfo.legend[p] + "<br>";
}
}
for ( var pi=0; pi <= LALOLibPlotsIndex; pi++)
LALOLibPlots[pi].replot();
// ZOOM
if(window.addEventListener)
document.getElementById(plotid).addEventListener('DOMMouseScroll', this.mousezoom, false);//firefox
//for IE/OPERA etc
document.getElementById(plotid).onmousewheel = this.mousezoom;
LALOLibPlotsIndex++;
}
// Color plot
function colorplot(multiargs) {
// colorplot(x,y,z) or colorplot(X) or colorplot(..., "cmapname" )
// Part copied from lalolabworker.js
var minX = Infinity;
var maxX = -Infinity;
var minY = Infinity;
var maxY = -Infinity;
var minZ = Infinity;
var maxZ = -Infinity;
var x;
var y;
var z;
var i;
var t0 = type( arguments[0] );
if ( t0 == "matrix" && arguments[0].n == 3 ) {
x = getCols(arguments[0], [0]);
y = getCols(arguments[0], [1]);
z = getCols(arguments[0], [2]);
}
else if ( t0 == "matrix" && arguments[0].n == 2 && type(arguments[1]) == "vector" ) {
x = getCols(arguments[0], [0]);
y = getCols(arguments[0], [1]);
z = arguments[1];
}
else if (t0 == "vector" && type(arguments[1]) == "vector" && type(arguments[2]) == "vector") {
x = arguments[0];
y = arguments[1];
z = arguments[2];
}
else {
return "undefined";
}
var minX = min(x);
var maxX = max(x);
var minY = min(y);
var maxY = max(y);
var minZ = min(z);
var maxZ = max(z);
var widthX = maxX-minX;
var widthY = Math.max( maxY-minY, 1);
maxX += 0.1*widthX;
minX -= 0.1*widthX;
maxY += 0.1*widthY;
minY -= 0.1*widthY;
if ( minY > 0 )
minY = -0.1*maxY;
if ( maxY < 0 )
maxY = -0.1*minY;
var plotinfo = {"x" : x, "y": y, "z": z, "minX" : minX, "maxX" : maxX, "minY" : minY, "maxY": maxY, "minZ" : minZ, "maxZ" : maxZ };
//////// Part from laloplots.html //////////
var plotid = "LALOLibPlot" + LALOLibPlotsIndex;
var legendwidth = 50;
LALOLibOutput.innerHTML += "<br><div style='position:relative;left:0px;top:0px;text-align:left;'> <div><a onmousemove='mouseposition(event," + LALOLibPlotsIndex + ");' onmousedown='mousestartmove(event," + LALOLibPlotsIndex + ");' onmouseup='mousestopmove(event);' onmouseleave='mousestopmove(event);' ondblclick='zoomoriginal(" + LALOLibPlotsIndex + ");'><canvas id='" +plotid + "' width='500' height='500' style='border: 1px solid black;'></canvas></a></div> <label id='lblposition" + LALOLibPlotsIndex + "'></label> <div style='position: absolute;left: 550px;top: -1em;'><label id='legendmaxZ" + LALOLibPlotsIndex + "' style='font-family:verdana;font-size:80%;'></label><br> <canvas id='legend" + LALOLibPlotsIndex + "' width='" + legendwidth + "' height='500'></canvas><br><label id='legendminZ" + LALOLibPlotsIndex + "' style='font-family:verdana;font-size:80%;'></label></div> <div id='legendtxt" + LALOLibPlotsIndex + "' style='position: absolute;left: 610px;top: 0;'></div> </div>";
LALOLibPlots[LALOLibPlotsIndex] = new ColorPlot(plotid) ;
LALOLibPlots[LALOLibPlotsIndex].setScale(plotinfo.minX, plotinfo.maxX, plotinfo.minY, plotinfo.maxY,plotinfo.minZ, plotinfo.maxZ);
LALOLibPlots[LALOLibPlotsIndex].view(plotinfo.minX, plotinfo.maxX, plotinfo.minY, plotinfo.maxY);
for (var i=0; i < plotinfo.x.length; i++)
LALOLibPlots[LALOLibPlotsIndex].addPoint(plotinfo.x[i],plotinfo.y[i],plotinfo.z[i]);
LALOLibPlots[LALOLibPlotsIndex].replot();
var legendwidth = 50;
// plotlegend.innerHTML += plotinfo.maxZ.toFixed(3) + "<br><canvas id='legend' width='" + legendwidth + "' height='500'></canvas><br>" + plotinfo.minZ.toFixed(3);
var ctx = document.getElementById("legend" +LALOLibPlotsIndex).getContext("2d");
var legendcanvas = document.getElementById("legend"+LALOLibPlotsIndex);
if ( legendcanvas )
var legendheight = legendcanvas.height;
else
var legendheight = 500;
var y;
for (var i=0; i< LALOLibPlots[LALOLibPlotsIndex].cmap.length;i++) {
y = Math.floor(i * legendheight / LALOLibPlots[LALOLibPlotsIndex].cmap.length);
ctx.fillStyle = "rgb(" + LALOLibPlots[LALOLibPlotsIndex].cmap[i][0] + "," + LALOLibPlots[LALOLibPlotsIndex].cmap[i][1] + "," + LALOLibPlots[LALOLibPlotsIndex].cmap[i][2] + ")";
ctx.fillRect( 0, legendheight-y, legendwidth , (legendheight / LALOLibPlots[LALOLibPlotsIndex].cmap.length) + 1) ;
}
document.getElementById("legendmaxZ" + LALOLibPlotsIndex).innerHTML = plotinfo.maxZ.toPrecision(3);
document.getElementById("legendminZ" + LALOLibPlotsIndex).innerHTML = plotinfo.minZ.toPrecision(3);
if(window.addEventListener)
document.getElementById(plotid).addEventListener('DOMMouseScroll', this.mousezoom, false);//firefox
//for IE/OPERA etc
document.getElementById(plotid).onmousewheel = this.mousezoom;
LALOLibPlotsIndex++;
}
// 3D plot
function plot3(multiargs) {
// plot3(x,y,z,"style", x2,y2,z2,"style",... )
var data = new Array();
var styles = new Array();
var legends = new Array();
var p=0; // argument pointer
var x;
var y;
var z;
var style;
var i;
var n;
var c = 0; // index of current curve
while ( p < arguments.length) {
if ( type( arguments[p] ) == "vector" ) {
if ( p + 2 < arguments.length && type ( arguments[p+1] ) == "vector" && type ( arguments[p+2] ) == "vector" ) {
// classic (x,y,z) arguments
x = arguments[p];
y = arguments[p+1];
z = arguments[p+2];
p += 2;
}
else {
return "undefined";
}
}
else if ( type( arguments[p] ) == "matrix" ) {
// argument = [x, y, z]
n = arguments[p].length;
x = new Array(n);
y = new Array(n);
z = new Array(n);
for ( i=0; i < n; i++) {
x[i] = get(arguments[p], i, 0);
y[i] = get(arguments[p], i, 1);
z[i] = get(arguments[p], i, 2);
}
}
else {
return "undefined";
}
//Style
style = undefined;
if ( p + 1 < arguments.length && type ( arguments[p+1] ) == "string" ) {
style = arguments[p+1];
p++;
}
legend = "";
if ( p + 1 < arguments.length && type ( arguments[p+1] ) == "string" ) {
legend = arguments[p+1];
p++;
}
// Add the curve (x,y,z, style) to plot
data[c] = new Array();
for ( i=0; i < x.length; i++) {
data[c][i] = [x[i], y[i], z[i]];
}
styles[c] = style;
legends[c] = legend;
// Next curve
c++;
p++; // from next argument
}
var plotinfo = { "data" : data, "styles" : styles, "legend": legends };
//////// Part from laloplots.html //////////
var plotid = "LALOLibPlot" + LALOLibPlotsIndex;
var legendwidth = 50;
LALOLibOutput.innerHTML += '<br><div style="position:relative;left:0px;top:0px;text-align:left;"> <div><a onmousedown="LALOLibPlots[' + LALOLibPlotsIndex + '].mousedown(event);" onmouseup="LALOLibPlots[' + LALOLibPlotsIndex + '].mouseup(event);" onmousemove="LALOLibPlots[' + LALOLibPlotsIndex + '].mouserotation(event);"><canvas id="' + plotid + '" width="500" height="500" style="border: 1px solid black;" title="Hold down the mouse button to change the view and use the mousewheel to zoom in or out." ></canvas></a></div><label id="lblposition' + LALOLibPlotsIndex + '"></label> <div style="position: absolute;left: 550px;top: -1em;"> <canvas id="legend' + LALOLibPlotsIndex + '" width="' + legendwidth + '" height="500"></canvas></div> <div id="legendtxt' + LALOLibPlotsIndex + '" style="position: absolute;left: 610px;top: 0;"></div> </div>';
var ylegend = 20;
// do plot
LALOLibPlots[LALOLibPlotsIndex] = new Plot3D(plotid) ;
LALOLibPlots[LALOLibPlotsIndex].cameraDistance = 30;
LALOLibPlots[LALOLibPlotsIndex].angleX = Math.PI/10;
LALOLibPlots[LALOLibPlotsIndex].angleZ = Math.PI/10;
LALOLibPlots[LALOLibPlotsIndex].axisNameX1 = "x";
LALOLibPlots[LALOLibPlotsIndex].axisNameX2 = "y";
LALOLibPlots[LALOLibPlotsIndex].axisNameX3 = "z";
var colors = [1,2,3,4,5,0];
var p;
var color;
for (p = 0; p<plotinfo.data.length; p++) {
var linestyle = false;
var pointstyle = true;
if ( typeof(plotinfo.styles[p]) == "string" ) {
if ( plotinfo.styles[p].indexOf(".") >= 0 ) {
linestyle = false;
plotinfo.styles[p] = plotinfo.styles[p].replace(".","");
}
if ( plotinfo.styles[p].indexOf("_") >= 0 ) {
pointstyle = false;
plotinfo.styles[p] = plotinfo.styles[p].replace("_","");
}
color = parseColor(plotinfo.styles[p]);
if ( color < 0 )
color = colors.splice(0,1)[0]; // pick next unused color
else
colors.splice(colors.indexOf(color),1); // remove this color
}
else
color = color = colors.splice(0,1)[0]; // pick next unused color
if ( typeof(color) == "undefined") // pick black if no next unused color
color = 0;
for ( i=0; i < plotinfo.data[p].length; i++) {
if ( pointstyle ) {
LALOLibPlots[LALOLibPlotsIndex].X.push( plotinfo.data[p][i] );
LALOLibPlots[LALOLibPlotsIndex].Y.push( color );
}
if ( linestyle && i < plotinfo.data[p].length-1 )
LALOLibPlots[LALOLibPlotsIndex].plot_line(plotinfo.data[p][i], plotinfo.data[p][i+1], "", color);
}
// Legend
if ( plotinfo.legend[p] != "" ) {
var ctx = document.getElementById("legend" +LALOLibPlotsIndex).getContext("2d");
setcolor(ctx, color);
ctx.lineWidth = "3";
if ( pointstyle ) {
ctx.beginPath();
ctx.arc( legendwidth/2 , ylegend, 5, 0, 2 * Math.PI , true);
ctx.closePath();
ctx.fill();
}
if( linestyle) {
ctx.beginPath();
ctx.moveTo ( 0,ylegend);
ctx.lineTo (legendwidth, ylegend);
ctx.stroke();
}
ylegend += 20;
document.getElementById("legendtxt" +LALOLibPlotsIndex).innerHTML += plotinfo.legend[p] + "<br>";
}
}
LALOLibPlots[LALOLibPlotsIndex].computeRanges();
LALOLibPlots[LALOLibPlotsIndex].replot();
LALOLibPlotsIndex++;
}
// image
function image(X, title) {
if (type(X) == "vector") {
X = mat([X]);
}
var style;
var minX = min(X);
var maxX = max(X);
var m = X.length;
var n = X.n;
var scale = (maxX - minX) ;
var i;
var j;
var k = 0;
var data = new Array();
for ( i=0; i < m; i++) {
var Xi = X.row(i);
for ( j=0; j < n; j++) { // could do for j in X[i] if colormap for 0 is white...
color = mul( ( Xi[j] - minX) / scale, ones(3) ) ;
data[k] = [i/m, j/n, color];
k++;
}
}
style = [m,n,minX,maxX];
var imagedata = { "data" : data, "style" : style, "title": title };
////// Part from laloplots.html
var plotid = "LALOLibPlot" + LALOLibPlotsIndex;
var legendwidth = 50;
var pixWidth ;
var pixHeight ;
// prepare legend
var ylegend = 20;
// do plot
var i;
var width = 500;
var height = 500;
var title = imagedata.title;
if(title) {
LALOLibOutput.innerHTML += "<h3>"+title+"</h3>" + " ( " + imagedata.style[0] + " by " + imagedata.style[1] + " matrix )";
}
if ( imagedata.style[1] > width ) {
width = imagedata.style[1];
plotlegend.style.left = (width+60) +"px";
}
if ( imagedata.style[0] > height )
height = imagedata.style[0];
pixWidth = width / imagedata.style[1];
pixHeight = height / imagedata.style[0];
var legendwidth = 50;
LALOLibOutput.innerHTML += '<div style="position:relative;left:0px;top:0px;text-align:left;"> <div><a onmousemove="mouseimageposition(event,' + LALOLibPlotsIndex + ');"><canvas id="' +plotid + '" width="' + width + '" height="' + height + '" style="border: 1px solid black;"></canvas></a></div><label id="lblposition' + LALOLibPlotsIndex + '"></label> <div style="position: absolute;left: 550px;top: -1em;">' + imagedata.style[2].toFixed(3) + '<br> <canvas id="legend' + LALOLibPlotsIndex + '" width="' + legendwidth + '" height="500"></canvas> <br>' + imagedata.style[3].toFixed(3) + ' </div> </div>';
var x;
var y;
var color;
LALOLibPlots[LALOLibPlotsIndex] = imagedata;
LALOLibPlots[LALOLibPlotsIndex].canvasId = plotid;
var canvas = document.getElementById(plotid);
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
for ( i=0; i < imagedata.data.length ; i++) {
x = canvas.width * LALOLibPlots[LALOLibPlotsIndex].data[i][1];
y = canvas.height * LALOLibPlots[LALOLibPlotsIndex].data[i][0] ;
color = LALOLibPlots[LALOLibPlotsIndex].data[i][2];
ctx.fillStyle = "rgb(" + Math.floor(255*(1-color[0])) + "," + Math.floor(255*(1-color[1])) + "," + Math.floor(255*(1-color[2])) + ")";
ctx.fillRect( x , y, pixWidth +1, pixHeight +1); // +1 to avoid blank lines between pixels
}
}
// add legend / colormap
var legend = document.getElementById("legend" +LALOLibPlotsIndex);
var ctx = legend.getContext("2d");
for ( i=0; i< 255;i++) {
y = Math.floor(i * legend.height / 255);
ctx.fillStyle = "rgb(" + (255-i) + "," + (255-i) + "," + (255-i) + ")";
ctx.fillRect( 0, y, legendwidth , (legend.height / 255) + 1) ;
}
// Prepare mouseposition info
LALOLibPlots[LALOLibPlotsIndex].pixelWidth = pixWidth;
LALOLibPlots[LALOLibPlotsIndex].pixelHeight = pixHeight;
LALOLibPlotsIndex++;
}
function parseColor( str ) {
if ( typeof(str) == "undefined")
return -1;
var color;
switch( str ) {
case "k":
case "black":
color = 0;
break;
case "blue":
case "b":
color = 1;
break;
case "r":
case "red":
color = 2;
break;
case "g":
case "green":
color = 3;
break;
case "m":
case "magenta":
color = 4;
break;
case "y":
case "yellow":
color = 5;
break;
default:
color = -1;
break;
}
return color;
}
function mousezoom ( e, delta , plotidx) {
if (!e)
e = window.event;
e.preventDefault();
if ( typeof(plotidx) == "undefined")
var plotidx = 0;
if ( typeof(delta) == "undefined") {
var delta = 0;
// normalize the delta
if (e.wheelDelta) {
// IE and Opera
delta = e.wheelDelta / 30;
}
else if (e.detail) {
delta = -e.detail ;
}
}
else {
if (e.button != 0 )
delta *= -1;
}
var plotcanvas = document.getElementById(LALOLibPlots[plotidx].canvasId);
var rect = plotcanvas.getBoundingClientRect();
var x = e.clientX - rect.left; // mouse coordinates relative to plot
var y = e.clientY - rect.top;
LALOLibPlots[plotidx].zoom(1+delta/30,1+delta/30, x, y);
}
function zoomoriginal(plotidx) {
LALOLibPlots[plotidx].resetzoom();
}
function mouseposition( e , plotidx) {
var plotcanvas = document.getElementById(LALOLibPlots[plotidx].canvasId);
var rect = plotcanvas.getBoundingClientRect();
var xmouse = e.clientX - rect.left; // mouse coordinates relative to plot
var ymouse = e.clientY - rect.top;
if ( LALOLABPLOTMOVING ) {
var dx = xmouse - LALOLABPLOTxprev ;
var dy = ymouse - LALOLABPLOTyprev;
if ( Math.abs( dx ) > 1 || Math.abs( dy ) > 1 ) {
LALOLibPlots[plotidx].translate(dx, dy);
}
LALOLABPLOTxprev = xmouse;
LALOLABPLOTyprev = ymouse;
}
else {
var x = xmouse / LALOLibPlots[plotidx].scaleX + LALOLibPlots[plotidx].minX;
var y = (plotcanvas.height - ymouse ) / LALOLibPlots[plotidx].scaleY + LALOLibPlots[plotidx].minY;
document.getElementById("lblposition" + plotidx).innerHTML = "x = " + x.toFixed(3) + ", y = " + y.toFixed(3);
}
}
function mousestartmove( e , plotidx) {
if ( e.button == 0 ) {
LALOLABPLOTMOVING = true;
var plotcanvas = document.getElementById(LALOLibPlots[plotidx].canvasId);
var rect = plotcanvas.getBoundingClientRect();
LALOLABPLOTxprev = e.clientX - rect.left; // mouse coordinates relative to plot
LALOLABPLOTyprev = e.clientY - rect.top;
}
else {
LALOLABPLOTMOVING = false;
}
}
function mousestopmove( e ) {
LALOLABPLOTMOVING = false;
}
function mouseimageposition( e, plotidx ) {
var plotcanvas = document.getElementById(LALOLibPlots[plotidx].canvasId);
var rect = plotcanvas.getBoundingClientRect();
var xmouse = e.clientX - rect.left; // mouse coordinates relative to plot
var ymouse = e.clientY - rect.top;
var n = LALOLibPlots[plotidx].style[1];
var minX = LALOLibPlots[plotidx].style[2];
var maxX = LALOLibPlots[plotidx].style[3];
var i = Math.floor(ymouse / LALOLibPlots[plotidx].pixelHeight);
var j = Math.floor(xmouse / LALOLibPlots[plotidx].pixelWidth );
if ( j < n ) {
var val = LALOLibPlots[plotidx].data[i*n + j][2][0]*(maxX - minX) + minX;
document.getElementById("lblposition" + plotidx).innerHTML = "Matrix[ " + i + " ][ " + j + " ] = " + val.toFixed(3);
}
}
/////////////////////////////////
//// Parser
////////////////////////////////
function lalo( Command ) {
// Parse command line and execute in current scopes
var cmd = laloparse( Command );
var res = self.eval(cmd);
return res;
}
function laloparse( WorkerCommand ) {
// Parse Commands
var WorkerCommandList = WorkerCommand.split("\n");
var k;
var cmd = "";
for (k = 0; k<WorkerCommandList.length; k++) {
if( WorkerCommandList[k].length > 0 ) {
if ( WorkerCommandList[k].indexOf("{") >= 0 || WorkerCommandList[k].indexOf("}") >= 0) {
// this line includes braces => plain javascript: do not parse it!
cmd += WorkerCommandList[k];
if ( WorkerCommandList[k].indexOf("}") >= 0 ) {
// braces closed, we can end the line
cmd += " ;\n";
}
}
else {
// standard lalolab line
cmd += parseCommand(WorkerCommandList[k]) + " ;\n";
}
}
}
return cmd;
}
function parseSplittedCommand( cmd ) {
//console.log("parsing : " + cmd);
// !!! XXX should parse unary ops before all the others !!!
var ops = ["==", "!=", ">=" ,"<=", ">", "<" , "\\" ,":", "+", "-", ".*", "*", "./" , "^", "'"]; // from lowest priority to highest
var opsFcts = ["isEqual" , "isNotEqual", "isGreaterOrEqual", "isLowerOrEqual", "isGreater" , "isLower", "solve","range", "add", "sub", "entrywisemul", "mul" , "entrywisediv", "pow", "undefined" ];
var unaryOpsFcts = ["", "", "", "", "","", "","range","", "minus", "", "" , "", "", "transpose" ];
var o;
var i ;
var k;
var operandA;
var operandB;
for ( o = 0; o < ops.length; o++) {
var splitted_wrt_op = cmd.split(ops[o]);
if ( splitted_wrt_op.length > 1) {
if ( removeSpaces(splitted_wrt_op[0]) != "" ) {
// there is actually a left-hand side operand
if( removeSpaces(splitted_wrt_op[1]) != "" ) {
// and a right-hand side operand
operandA = parseSplittedCommand(splitted_wrt_op[0]);
for ( k = 1; k< splitted_wrt_op.length ; k++) {
operandB = splitted_wrt_op[k];
operandA = opsFcts[o] + "(" + operandA + "," + parseSplittedCommand(operandB) + ")";
}
cmd = operandA;
}
else {
// no right-hand side: like transpose operator
cmd = unaryOpsFcts[o] + "(" + parseSplittedCommand(splitted_wrt_op[0]) + ")";
}
}
else {
// no left operand: like minus something...
// Apply unary operator
operandA = unaryOpsFcts[o] + "(" + parseSplittedCommand(splitted_wrt_op[1]) + ")";
// and then binary operator for the remaining occurences
for ( k = 2; k< splitted_wrt_op.length ; k++) {
operandB = splitted_wrt_op[k];
operandA = opsFcts[o] + "(" + operandA + "," + parseSplittedCommand(operandB) + ")";
}
cmd = operandA;
}
}
}
return cmd;
}
function parseAssignment ( assignmentStr ) {
if ( assignmentStr.indexOf("[") < 0 ) {
// straightforward assignment
return assignmentStr;
}
else {
var assign = removeSpaces(assignmentStr).replace("=","").replace(",","][");
var middle = assign.indexOf("][");
var start = assign.indexOf("[");
var varname = assign.substr(0,start);
if ( middle >= 0 ) {
// submatrix assignment
var rowsrange = assign.substr( start + 1, middle-start-1);
// find last "]";
var end = middle+1;
while ( assign.indexOf("]",end+1) >= 0)
end = assign.indexOf("]",end+1);
var colsrange = assign.substr(middle+2, end - (middle+2)); // everything after "][" and before last "]"
// Parse colon ranges
var rowssplit = rowsrange.split(":");
if (rowssplit.length == 2 ){
if ( rowssplit[0] =="" && rowssplit[1] =="" )
rowsrange = "[]";
else
rowsrange = "range(" + rowssplit[0] + "," + rowssplit[1] + ")";
}
else if ( rowssplit.length == 3)
rowsrange = "range(" + rowssplit[0] + "," + rowssplit[2] + "," + rowssplit[1] + ")";
var colssplit = colsrange.split(":");
if (colssplit.length == 2 ) {
if ( colssplit[0] =="" && colssplit[1] =="" )
colsrange = "[]";
else
colsrange = "range(" + colssplit[0] + "," + colssplit[1] + ")";
}
else if ( colssplit.length == 3)
colsrange = "range(" + colssplit[0] + "," + colssplit[2] + "," + colssplit[1] + ")";
return "set( " + varname + "," + rowsrange + "," + colsrange + ", ";
}
else {
// subvector assignment
// find last "]";
var end = start;
while ( assign.indexOf("]",end+1) >= 0)
end = assign.indexOf("]",end+1);
var rowsrange = assign.substr( start + 1, end-start-1);
// Parse colon ranges
var rowssplit = rowsrange.split(":");
if (rowssplit.length == 2 ){
if ( rowssplit[0] =="" && rowssplit[1] =="" )
rowsrange = "[]";
else
rowsrange = "range(" + rowssplit[0] + "," + rowssplit[1] + ")";
}
else if ( rowssplit.length == 3)
rowsrange = "range(" + rowssplit[0] + "," + rowssplit[2] + "," + rowssplit[1] + ")";
return "set( " + varname + "," + rowsrange + ", ";
}
}
}
function parseBrackets( cmdString ) {
// Parse brackets => get matrix entries
var delimiters = ["[", "(",",",";",")", "\\", "+", "-", "*", "/", ":", "^", "'", "=", ">", "<", "!"];
cmdString = cmdString.split("][").join(","); // replace ][ by , and ] by )
var cmd = cmdString.split(""); // string to array of char
var i;
var j;
var k;
var l;
var lhs;
// For the entire string:
i = cmd.length - 1;
while ( i >= 0 ) {
// Search for the right-most opening bracket:
while ( i >= 0 && cmd[i] != "[" )
i--;
if ( i >= 0 ) {
// found a bracket, find its corresponding closing bracket
j = i+1;
while ( j < cmd.length && cmd[j] != "]" )
j++;
if ( j < cmd.length ) {
// then determine its left-hand side operand:
l = 0;
k = 0;
while ( k < i ) {
if ( delimiters.indexOf(cmd[k]) >= 0)
l = k+1;
k++;
}
lhs = cmd.slice(l,i).join(""); // should be LHS as string or "" if l >= i
if ( removeSpaces(lhs) == "" ) {
// if the LHS operand is empty, leave the brackets untouched
cmd[i] = "#"; // (replace by # and $ re-replace at the end by a matrix creation)
// look for semicolon within brackets:
k = i+1;
var rowwise = false;
var colwise = false;
while ( k < j ) {
if( cmd[k] == "," ) {
//colwise = true;
}
if ( cmd[k] == ";" ) {
rowwise = true; // mark for rowwise mat
if ( colwise ) {
cmd.splice(k,1, ["@", ","] ); // end previous row vector, replace by comma
colwise = false;
}
else {
cmd[k] = ","; // simply replace by comma
}
}
k++;
}
if ( rowwise )
cmd[j] = "$";
else
cmd[j] = "@";
}
else {
// if not empty, implement a GET
cmd[l]="get(" + lhs ;
for ( k = l+1; k < i; k++)
cmd[k] = "";
cmd[i] = ",";
cmd[j] = ")";
}
}
else {
return undefined; // error no ending bracket;
}
}
i--;
}
var cmdparsed = cmd.join("").split("#").join("mat([").split("$").join("], true)").split("@").join("])");
//console.log(cmdparsed);
return cmdparsed;
}
function parseCommand( cmdString ) {
// Remove comments at the end of the line
var idxComments = cmdString.indexOf("//");
if ( idxComments >= 0 )
cmdString = cmdString.substr(0,idxComments);
// Parse "=" sign to divide between assignement String and computeString
var idxEqual = cmdString.split("==")[0].split("!=")[0].split(">=")[0].split("<=")[0].indexOf("=");
if ( idxEqual > 0 ) {
var assignmentStr = parseAssignment( cmdString.substr(0,idxEqual + 1) );
var computeStr = cmdString.substr(idxEqual+1);
// Check for simple assignments like A = B to force copy
if ( assignmentStr.indexOf("set(") < 0 && typeof(self[removeSpaces(computeStr)]) != "undefined" ) { //self.hasOwnProperty( removeSpaces(computeStr) ) ) { // self.hasOwnProperty does not work in Safari workers....
// computeStr is a varaible name
if ( !isScalar(self[ removeSpaces(computeStr) ] ) ) {
// the variable is a vector or matrix
var FinalCommand = assignmentStr + "matrixCopy(" + computeStr + ")";
console.log(FinalCommand);
return FinalCommand;
}
}
}
else {
var assignmentStr = "";
var computeStr = cmdString;
}
// parse brackets:
var cmd = parseBrackets( computeStr ).split(""); // and convert string to Array
// Parse delimiters
var startdelimiters = ["(","[",",",";"];
var enddelimiters = [")","]",",",";"];
var i;
var j;
var k;
var parsedContent = "";
var parsedCommand = new Array(cmd.length);
var map = new Array(cmd.length ) ;
for ( k=0;k<cmd.length;k++) {
map[k] = k;
parsedCommand[k] = cmd[k];
}
i = cmd.length - 1;
while ( i >= 0 ) {
// Find the most right starting delimiter
while ( i >= 0 && startdelimiters.indexOf(cmd[i]) < 0 )
i--;
if ( i >= 0 ) {
// found a delimiter, search for the closest ending delimiter
j = i+1;
while ( j < cmd.length && enddelimiters.indexOf(cmd[j] ) < 0 ) {
j++;
}
if ( j < cmd.length ) {
// starting delimiter is at cmd[i] and ending one at cmd[j]
// parse content within delimiters
parsedContent = parseSplittedCommand( parsedCommand.slice(map[i]+1,map[j]).join("") ) ;
// and replace the corresponding content in the parsed command
parsedCommand.splice (map[i]+1, map[j]-map[i]-1, parsedContent ) ;
// remove delimiters from string to be parsed
if ( cmd[i] != "," )
cmd[i] = " "; // except for commas that serve twice (once as start once as end)
cmd[j] = " ";
// map position in the original cmd to positions in the parsedCommand to track brackets
for ( k=i+1; k < j;k++)
map[k] = map[i]+1;
var deltamap = map[j] - map[i] - 1;
for ( k=j; k < cmd.length;k++)
map[k] += 1 - deltamap;
/*console.log(parsedCommand);
console.log(cmd.join(""));
console.log(map);
console.log(i + " : " + j);*/
}
else {
return "undefined";
}
}
i--;
}
var FinalCommand = assignmentStr + parseSplittedCommand(parsedCommand.join(""));
// Parse brackets => get matrix entries
//cmdString = cmdString.split("][").join(",").split("]").join(")"); // replace ][ by , and ] by )
// consider [ as a left-hand unary operator
// cmd = "get(" + parseSplittedCommand(splitted_wrt_op[0]) + ")";
if ( assignmentStr.substr(0,4) == "set(" )
FinalCommand += " )";
FinalCommand = parseRangeRange( FinalCommand );
console.log(FinalCommand);
return FinalCommand;
}
function parseRangeRange( cmd ) {
// parse complex ranges like 0:0.1:4
var elems = cmd.split("range(range(");
var i;
var j;
var tmp;
var args;
var incargs;
var endargs;
for ( i = 0; i< elems.length - 1 ; i++) {
// elems[i+1] = elems[i+1].replace(")","");
// ivert second and third arguments to get range(start, end, inc) from start:inc:end
args = elems[i+1].split(",");
tmp = args[2].split(")"); // keep only the content of the range and not the remaining commands
endargs = tmp[0];
j = 0; // deal with cases like end="minus(4)" where the first closing bracket is not at the complete end
while ( tmp[j].indexOf("(") >= 0 ) {
endargs = endargs + ")" + tmp[j+1];
j++;
}
incargs = args[1].substr(0,args[1].length-1); // remove ")"
args[1] = endargs;
//endargs[0] = incargs;
args[2] = incargs + ")" + tmp.slice(j+1).join(")");
elems[i+1] = args.join(",");
}
return elems.join("range(");//replace range(range( by range(
}
function removeSpaces( str ) {
return str.split(" ").join("");
}
////////////////////////////
/// Lab
////////////////////////////
function MLlab ( id , path ) {
var that = new Lalolab ( id, true, path);
return that;
}
function Lalolab ( id, mllab , path ) {
// constructor for a Lab with independent scope running in a worker
this.id = id;
this.callbacks = new Array();
// Create worker with a Blob to avoid distributing lalolibworker.js
// => does not work due to importScripts with relative path to the Blob unresolved (or cross-origin)
if ( typeof(path) == "undefined" )
var path = "http://mlweb.loria.fr/";
else {
if (path.length > 0 && path[path.length-1] != "/" )
path = [path,"/"].join("");
}
if ( typeof(mllab) != "undefined" && mllab ) {
this.worker = new Worker(path+"mlworker.js"); // need mlworker.js in same directory as web page
this.labtype = "ml";
/* Using a Blob to avoid distributing mlworker.js:
does not work because of importScripts from cross origin...
var workerscript = "importScripts(\"ml.js\");\n onmessage = function ( WorkerEvent ) {\n var WorkerCommand = WorkerEvent.data.cmd;var mustparse = WorkerEvent.data.parse; \n if ( mustparse )\n var res = lalo(WorkerCommand);\n else {\n if ( WorkerCommand == \"load_mat\" ) {\n if ( type(WorkerEvent.data.data) == \"matrix\" )\n var res = new Matrix(WorkerEvent.data.data.m,WorkerEvent.data.data.n,WorkerEvent.data.data.val, true);\nelse\n var res = mat(WorkerEvent.data.data, true);\n eval(WorkerEvent.data.varname + \"=res\");\n}\n else\n var res = self.eval( WorkerCommand ) ;\n}\n try {\n postMessage( { \"cmd\" : WorkerCommand, \"output\" : res } );\n} catch ( e ) {\n try {\n postMessage( { \"cmd\" : WorkerCommand, \"output\" : res.info() } );\n } catch(e2) { \n postMessage( { \"cmd\" : WorkerCommand, \"output\" : undefined } );\n}\n}\n}";
var blob = new Blob([workerscript], { "type" : "text/javascript" });
var blobURL = window.URL.createObjectURL(blob);
console.log(blobURL);
this.worker = new Worker(blobURL);*/
}
else {
this.worker = new Worker(path+"lalolibworker.js"); // need lalolibworker.js in same directory as web page
this.labtype = "lalo";
}
this.worker.onmessage = this.onresult;
this.worker.parent = this;
}
Lalolab.prototype.close = function ( ) {
this.worker.terminate();
this.worker.parent = null;// delete circular reference
}
Lalolab.prototype.onprogress = function ( ratio ) {
// do nothing by default;
// user must set lab.onprogress = function (ratio) { ... } to do something
}
Lalolab.prototype.onresult = function ( WorkerEvent ) {
// console.log(WorkerEvent, ""+ this.parent.callbacks);
if ( typeof(WorkerEvent.data.progress) != "undefined" ) {
this.parent.onprogress( WorkerEvent.data.progress ) ;
}
else {
var cb = this.parent.callbacks.splice(0,1)[0] ; // take first callback from the list
if ( typeof(cb) == "function" ) {
var WorkerCommand = WorkerEvent.data.cmd;
var WorkerResult = WorkerEvent.data.output;
cb( WorkerResult, WorkerCommand, this.parent.id ); // call the callback if present
}
}
}
Lalolab.prototype.do = function ( cmd , callback ) {
// prepare callback, parse cmd and execute in worker
this.callbacks.push( callback ) ;
this.worker.postMessage( {cmd: cmd, parse: true} );
}
Lalolab.prototype.exec = function ( cmd , callback ) {
// prepare callback, and execute cmd in worker
this.callbacks.push( callback );
this.worker.postMessage( {cmd: cmd, parse: false} );
}
Lalolab.prototype.parse = function ( cmd , callback ) {
// prepare callback, parse cmd and execute in worker
this.callbacks.push( callback );
this.worker.postMessage( {cmd: cmd, parse: false} );
}
Lalolab.prototype.load = function ( data , varname, callback ) {
// load data in varname
this.callbacks.push( callback ) ;
if ( typeof(data) == "string" ){
this.worker.postMessage( {"cmd" : varname + "= load_data (\"" + data + "\")", parse: false} );
}
else {
this.worker.postMessage( {"cmd" : "load_mat", data: data, varname: varname, parse: false} );
}
}
Lalolab.prototype.import = function ( script, callback ) {
// load a script in lalolib language
this.do('importLaloScript("' + script + '")', callback);
}
function importLaloScript ( script ) {
// load a script in lalolib language in the current Lab worker
var xhr = new XMLHttpRequest();
xhr.open('GET', script, false);
xhr.send();
var cmd = xhr.responseText;
return lalo(cmd);
}
Lalolab.prototype.importjs = function ( script, callback ) {
// load a script in javascript
this.exec("importScripts('" + script + "');", callback);
}
Lalolab.prototype.getObject = function ( varname, callback ) {
this.exec("getObjectWithoutFunc(" + varname +")", function (res) {callback(renewObject(res));} );
}
function getObjectWithoutFunc( obj ) {
// Functions and Objects with function members cannot be sent
// from one worker to another...
if ( typeof(obj) != "object" )
return obj;
else {
var res = {};
for (var p in obj ) {
switch( type(obj[p]) ) {
case "vector":
res[p] = {type: "vector", data: [].slice.call(obj[p])};
break;
case "matrix":
res[p] = obj[p];
res[p].val = [].slice.call(obj[p].val);
break;
case "spvector":
res[p] = obj[p];
res[p].val = [].slice.call(obj[p].val);
res[p].ind = [].slice.call(obj[p].ind);
break;
case "spmatrix":
res[p] = obj[p];
res[p].val = [].slice.call(obj[p].val);
res[p].cols = [].slice.call(obj[p].cols);
res[p].rows = [].slice.call(obj[p].rows);
break;
case "undefined":
res[p] = obj[p];
break;
case "function":
break;
case "Array":
res[p] = getObjectWithoutFunc( obj[p] );
res[p].type = "Array";
res[p].length = obj[p].length;
break;
default:
res[p] = getObjectWithoutFunc( obj[p] );
break;
}
}
return res;
}
}
function renewObject( obj ) {
// Recreate full object with member functions
// from an object created by getObjectWithoutFunc()
var to = type(obj);
switch( to ) {
case "number":
case "boolean":
case "string":
case "undefined":
return obj;
break;
case "vector":
return new Float64Array(obj.data);
break;
case "matrix":
return new Matrix(obj.m, obj.n, obj.val);
break;
case "spvector":
return new spVector(obj.length,obj.val,obj.ind);
break;
case "spmatrix":
return new spMatrix(obj.m, obj.n, obj.val, obj.cols, obj.rows);
break;
case "object":
// Object without type property and thus without Class
var newobj = {};
for ( var p in obj )
newobj[p] = renewObject(obj[p]);
return newobj;
break;
case "Array":
var newobj = new Array(obj.length);
for ( var p in obj )
newobj[p] = renewObject(obj[p]);
return newobj;
default:
// Structured Object like Classifier etc...
// type = Class:subclass
var typearray = obj.type.split(":");
var Class = eval(typearray[0]);
if ( typearray.length == 1 )
var newobj = new Class();
else
var newobj = new Class(typearray[1]);
for ( var p in obj )
newobj[p] = renewObject(obj[p]);
// deal with particular cases:
// Rebuild kernelFunc
if (typearray[1] == "SVM" || typearray[1] == "SVR" ) {
newobj["kernelFunc"] = kernelFunction(newobj["kernel"], newobj["kernelpar"], type(newobj["SV"]) == "spmatrix"?"spvector":"vector");
}
if (typearray[1] == "KernelRidgeRegression" ) {
newobj["kernelFunc"] = kernelFunction(newobj["kernel"], newobj["kernelpar"], type(newobj["X"]) == "spmatrix"?"spvector":"vector");
}
return newobj;
break;
}
}
function load_data ( datastring ) {
// convert a string into a matrix data
var i;
var cmd = "mat( [ ";
var row;
var rows = datastring.split("\n");
var ri ;
for ( i=0; i< rows.length - 1; i++) {
ri = removeFirstSpaces(rows[i]);
if ( ri != "" ) {
row = ri.replace(/,/g," ").replace(/ +/g,",");
cmd += "new Float64Array([" + row + "]) ,";
}
}
ri = removeFirstSpaces(rows[rows.length-1]);
if ( ri != "" ) {
row = ri.replace(/,/g," ").replace(/ +/g,",");
cmd += "new Float64Array([" + row + "]) ] , true) ";
}
else {
cmd = cmd.substr(0,cmd.length-1); // remove last comma
cmd += "] , true) ";
}
return eval(cmd);
}
function removeFirstSpaces( str ) {
//remove spaces at begining of string
var i = 0;
while ( i < str.length && str[i] == " " )
i++;
if ( i<str.length ) {
// first non-space char at i
return str.slice(i);
}
else
return "";
}
//// progress /////////////////////
function notifyProgress( ratio ) {
postMessage( { "progress" : ratio } );
console.log("progress: " + ratio);
}
//////////////////////////
//// CONSTANTS and general tools
///////////////////////////
var LALOLIB_ERROR = "";
const EPS = 2.2205e-16;
function isZero(x) {
return (Math.abs(x) < EPS ) ;
}
function isInteger(x) {
return (Math.floor(x) == x ) ;
}
function tic( T ) {
if ( typeof(TICTOCstartTime) == "undefined" )
TICTOCstartTime = new Array();
if (typeof(T) == "undefined")
var T = 0;
TICTOCstartTime[T] = new Date();
}
function toc ( T ) {
if ( typeof(T) == "undefined" )
var T = 0;
if ( typeof(TICTOCstartTime) != "undefined" && typeof(TICTOCstartTime[T]) != "undefined" ) {
// Computing time
var startTime = TICTOCstartTime[T];
var endTime = new Date();
var time = ( endTime - startTime) / 1000; // in seconds
return time;
}
else
return undefined;
}
/**
* @return {string}
*/
function type( X ) {
if ( X == null )
return "undefined";
else if ( X.type )
return X.type;
else {
var t = typeof( X );
if ( t == "object") {
if ( Array.isArray(X) ) {
if ( isArrayOfNumbers(X) )
return "vector"; // for array vectors created by hand
else
return "Array";
}
else if ( X.buffer )
return "vector"; // Float64Array vector
else
return t;
}
else
return t;
}
}
/**
* @param {Array}
* @return {boolean}
*/
function isArrayOfNumbers( A ) {
for (var i=0; i < A.length; i++)
if ( typeof(A[i]) != "number" )
return false;
return true;
}
function isScalar( x ) {
switch( typeof( x ) ) {
case "string":
case "number":
case "boolean":
return true;
break;
default:
if (type(x) == "Complex")
return true;
else
return false;
break;
}
}
/**
* @param {Float64Array}
* @return {string}
*/
function printVector( x ) {
const n = x.length;
var str = "[ ";
var i = 0;
while ( i < n-1 && i < 5 ) {
str += (isInteger( x[i] ) ? x[i] : x[i].toFixed(3) ) + "; ";
i++;
}
if ( i == n-1 )
str += (isInteger( x[i] ) ? x[i] : x[i].toFixed(3) ) + " ]" ;
else
str += "... ] (length = " + n + ")";
return str;
}
//////////////////////////////
// Matrix/vector creation
//////////////////////////////
/**
* @constructor
* @struct
*/
function Matrix(m,n, values) {
/** @const */ this.length = m;
/** @const */ this.m = m;
/** @const */ this.n = n;
/** @const */ this.size = [m,n];
/** @const */ this.type = "matrix";
if ( arguments.length == 2)
this.val = new Float64Array( m * n ); // simple m x n zeros
else if (arguments.length == 3)
this.val = new Float64Array( values ); // m x n filled with values with copy
else if (arguments.length == 4)
this.val = values ; // m x n filled with values without copy
}
Matrix.prototype.get = function ( i,j) {
return this.val[i*this.n + j];
}
Matrix.prototype.set = function ( i,j, v) {
this.val[i*this.n + j] = v;
}
/**
* return a pointer-like object on a row in a matrix, not a copy!
* @param {number}
* @return {Float64Array}
*/
Matrix.prototype.row = function ( i ) {
return this.val.subarray(i*this.n, (i+1)*this.n);
}
/**
* return a copy of the matrix as an Array of Arrays
* (do not do this with too many rows...)
* @return {Array}
*/
Matrix.prototype.toArray = function ( ) {
var A = new Array(this.m);
var ri = 0;
for ( var i=0; i < this.m; i++) {
A[i] = new Array(this.n);
for ( var j=0; j < this.n; j++)
A[i][j] = this.val[ri + j];
ri += this.n;
}
return A;
}
/**
* return a view (not a copy) on the matrix as an Array of Float64Array
* (do not do this with too many rows...)
* @return {Array}
*/
Matrix.prototype.toArrayOfFloat64Array = function ( ) {
var A = new Array(this.m);
for ( var i=0; i < this.m; i++)
A[i] = this.val.subarray(i*this.n, (i+1)*this.n);
return A;
}
function array2mat( A ) {
return mat(A, true);
}
function array2vec( a ) {
return vectorCopy(a);
}
function vec2array( a ) {
return Array.apply([], a);
}
function size( A, sizealongdimension ) {
var s;
switch( type(A) ) {
case "string":
case "boolean":
case "number":
case "Complex":
s = [1,1];
break;
case "vector":
case "spvector":
case "ComplexVector":
s = [A.length, 1];
break;
case "matrix":
case "spmatrix":
case "ComplexMatrix":
s = A.size;
break;
case "object":
s = [1,1];
break;
default:
s = [1,1];
//error( "Cannot determine size of object" );
break;
}
if ( typeof(sizealongdimension) == "undefined" )
return s;
else
return s[sizealongdimension-1];
}
function ones(rows, cols) {
// Create a matrix or vector full of ONES
if ( arguments.length == 1 || cols == 1 ) {
var v = new Float64Array(rows);
for (var i = 0; i< rows; i++)
v[i] = 1;
return v;
}
else {
var M = new Matrix(rows, cols);
const mn = rows*cols;
for (var i = 0; i< mn; i++) {
M.val[i] = 1;
}
return M;
}
}
// Use zeros( m, n)
function zeros(rows, cols) {
// Create a matrix or vector of ZERO
if ( arguments.length == 1 || cols == 1 ) {
return new Float64Array(rows);
}
else {
return new Matrix(rows, cols);
}
}
function eye(m,n) {
if ( typeof(n) == "undefined")
var n = m;
if ( m == 1 && n == 1)
return 1;
var I = zeros(m,n);
const e = (m<n)?m:n;
for ( var i = 0; i< e; i ++) {
I.val[i*(n+1)] = 1;
}
return I;
}
function diag( A ) {
var i;
var typeA = type(A);
if (typeA == "vector" ) {
var M = zeros(A.length,A.length);
var j = 0;
const stride = A.length+1;
for ( i=0; i < A.length; i++) {
M.val[j] = A[i];
j += stride;
}
return M;
}
else if ( typeA =="matrix") {
var n = Math.min(A.m, A.n);
var v = new Float64Array(n);
var j = 0;
const stride2 = A.n+1;
for ( i =0; i< n;i++) {
v[i] = A.val[j];
j+=stride2;
}
return v;
}
else if (typeA == "ComplexVector" ) {
var M = new ComplexMatrix(A.length,A.length);
var j = 0;
const stride = A.length+1;
for ( i=0; i < A.length; i++) {
M.re[j] = A.re[i];
M.im[j] = A.im[i];
j += stride;
}
return M;
}
else if ( typeA == "ComplexMatrix") {
var n = Math.min(A.m, A.n);
var v = new ComplexVector(n);
var j = 0;
const stride2 = A.n+1;
for ( i =0; i< n;i++) {
v.re[i] = A.re[j];
v.im[i] = A.im[j];
j+=stride2;
}
return v;
}
}
/**
* @param {Matrix}
* @return {Float64Array}
*/
function vec( A ) {
return new Float64Array(A.val);
}
function matrixCopy( A ) {
var t = type(A) ;
switch(t) {
case "vector":
return vectorCopy(A);
break;
case "ComplexVector":
return new ComplexVector(A);
break;
case "matrix":
return new Matrix(A.m, A.n, A.val);
break;
case "ComplexMatrix":
return new ComplexMatrix(A);
break;
case "Array":
return arrayCopy ( A ) ;
break;
case "spvector":
case "spmatrix":
return A.copy();
break;
default:
error("Error in matrixCopy(A): A is not a matrix nor a vector.");
return undefined;
break;
}
}
/**
* @param {Float64Array}
* @return {Float64Array}
*/
function vectorCopy( a ) {
return new Float64Array( a );
}
/** Vector copy into another existing vector ( y = x )
* (saves memory allocation)
* @param {Float64Array}
* @param {Float64Array}
*/
function vectorCopyInto (x, y) {
y.set(x);
}
/**
* @param {Array}
* @return {Array}
*/
function arrayCopy( A ) {
var res = new Array(A.length);
for ( var i = 0; i < A.length; i++ )
if ( isScalar(A[i]) )
res[i] = A[i]; //does not copy 2D Arrays...
else
res[i] = matrixCopy( A[i] ) ;
return res;
}
/**
* Return enlarged matrix with one more row of zeros
* NOTE: both matrices share the same storage and should not be used independently
* so better use: A = appendRow(A); or just appendRow(A);
* @param{Matrix}
* @return{Matrix}
*/
function appendRow ( A ) {
var Aa = zeros(A.m+1,A.n);
Aa.val.set(A.val);
return Aa;
}
/**
* Reshape the dimensions of a vector/matrix
* @param{{Float64Array|Matrix}}
* @param{number}
* @param{number}
* @return{{Float64Array|Matrix}}
*/
function reshape ( A, m, n ) {
var R = undefined;
var tA = type( A );
if ( tA == "vector" ) {
if ( m*n != A.length ) {
error("Error in reshape(a,m,n): a.length = " + A.length + " != m*n");
}
else {
R = new Matrix(m,n,A);
}
}
else if ( tA == "matrix" ) {
if ( m*n != A.m*A.n ) {
error("Error in reshape(A,m,n): A.m * A.n = " + A.m*A.n + " != m*n");
}
else {
if ( n == 1 )
R = vectorCopy(A.val);
else
R = new Matrix(m,n,A.val);
}
}
else
error("Error in reshape(A): A is neither a vector nor a matrix.");
return R;
}
////////////////////////
// slicing functions
////////////////////////
/*
GET function : returns a copy of a subset of entries
For MATRICES:
get ( M, rows, cols ) => submatrix of M
get ( M, rows ) => subset of rows from M (equiv to rows(M,rows) )
get ( M, [], cols ) => subset of cols (equiv to cols(M, cols) )
get ( M, i, j) => M[i][j] converted to dense format (0 instead of undefined)
get ( M ) => M in dense format (with 0 instead of undefined)
For VECTORS:
get ( v, rows ) => subvector from v (equiv to rows(v,rows) )
get ( v, i ) => v[i] converted to dense format (0 instead of undefined)
get ( v ) => v in dense format (with 0 instead of undefined)
*/
function get ( A , rowsrange, colsrange) {
var typerows = typeof(rowsrange);
var typecols = typeof(colsrange);
if (arguments.length == 1 )
return matrixCopy(A);
var typeA = type ( A );
if ( typeA == "vector" ) {
if ( typerows == "number" ) {
if (rowsrange >= 0 && rowsrange < A.length)
return A[rowsrange]; // get v[i]
else {
error("Error in a[i] = get(a,i): Index i="+rowsrange+" out of bounds [0,"+(A.length-1)+"]");
return undefined;
}
}
else {
return getSubVector(A, rowsrange);
}
}
else if ( typeA == "matrix") {
if ( typerows == "number" )
rowsrange = [rowsrange];
if ( typecols == "number" )
colsrange = [colsrange];
if ( rowsrange.length == 1 && colsrange.length == 1 )
return A.val[rowsrange[0] * A.n + colsrange[0]]; // get ( A, i, j)
if ( rowsrange.length == 0 )
return getCols(A,colsrange);// get(A,[],4) <=> cols(A,4)
if (colsrange.length == 0 )
return getRows(A, rowsrange);// get(A,3,[]) <=> rows(A,3)
// otherwise:
return getSubMatrix(A, rowsrange, colsrange);
}
else if ( typeA == "Array" ) {
if ( typerows == "number" )
return A[rowsrange];
else
return getSubArray(A, rowsrange);
}
else if ( typeA == "spmatrix") {
if ( typerows == "number" )
rowsrange = [rowsrange];
if ( typecols == "number" )
colsrange = [colsrange];
if ( rowsrange.length == 1 && colsrange.length == 1 )
return A.get(rowsrange[0], colsrange[0]); // get ( A, i, j)
if ( rowsrange.length == 1 && A.rowmajor )
return A.row(rowsrange[0]);
if ( colsrange.length == 1 && !A.rowmajor )
return A.col(colsrange[0]);
if (colsrange.length == 0 )
return spgetRows(A, rowsrange);
if ( rowsrange.length == 0 )
return spgetCols(A,colsrange);
// TODO
}
else if ( typeA == "spvector" ) {
if ( typerows == "number" )
return A.get( rowsrange ); // get v[i]
else
return getSubspVector(A, rowsrange);//TODO
}
else if ( typeA == "ComplexVector") {
if ( typerows == "number" )
return A.get( rowsrange ); // get v[i]
else
return A.getSubVector(rowsrange);
}
else if ( typeA == "ComplexMatrix") {
if ( typerows == "number" )
rowsrange = [rowsrange];
if ( typecols == "number" )
colsrange = [colsrange];
if ( rowsrange.length == 1 && colsrange.length == 1 )
return A.get(i,j);
if ( rowsrange.length == 0 )
return A.getCols(colsrange);// get(A,[],4) <=> cols(A,4)
if (colsrange.length == 0 )
return A.getRows(rowsrange);// get(A,3,[]) <=> rows(A,3)
// otherwise:
return A.getSubMatrix(rowsrange, colsrange);
}
return undefined;
}
function getSubMatrix(A, rowsrange, colsrange) {
var n = colsrange.length;
var i;
var j;
var res;
if ( n == 1 ) {
res = new Float64Array(rowsrange.length);
for (i= 0; i< rowsrange.length ; i++) {
res[i] = A.val[rowsrange[i] * A.n + colsrange[0]];
}
}
else {
res = new Matrix(rowsrange.length, n);
var r = 0;
for (i= 0; i< rowsrange.length ; i++) {
var rA = rowsrange[i]*A.n;
for ( j=0; j < n; j++) {
res.val[r+j] = A.val[rA + colsrange[j]];
}
r += n;
}
}
return res;
}
function getRows(A, rowsrange) {
var n = rowsrange.length;
if ( n > 1 ) {
var res = new Matrix(n, A.n);
var r=0;
for ( var i = 0; i < n; i++) {
for (var j=0; j < A.n; j++)
res.val[r + j] = A.val[rowsrange[i]*A.n + j];
r += A.n;
}
return res;
}
else
return vectorCopy(A.val.subarray( rowsrange[0]*A.n, rowsrange[0]*A.n + A.n));
}
function getCols(A, colsrange) {
var m = A.m;
var n = colsrange.length;
if( n > 1 ) {
var res = new Matrix(m, n);
var r = 0;
var rA = 0;
for ( var i = 0; i < m; i++) {
for ( var j = 0; j < n; j++)
res.val[r + j] = A.val[rA + colsrange[j]];
r += n;
rA += A.n;
}
return res;
}
else {
var res = new Float64Array(m);
var r = 0;
for ( var i = 0; i < m; i++) {
res[i] = A.val[r + colsrange[0]];
r += A.n;
}
return res;
}
}
/**
* @param {Float64Array}
* @param {Array}
* @return {Float64Array}
*/
function getSubVector(a, rowsrange) {
const n = rowsrange.length;
var res= new Float64Array( n );
for (var i = 0; i< n; i++) {
res[i] = a[rowsrange[i]];
}
return res;
}
/**
* @param {Array}
* @param {Array}
* @return {Array}
*/
function getSubArray(a, rowsrange) {
const n = rowsrange.length;
var res= new Array( n );
for (var i = 0; i< n; i++) {
res[i] = a[rowsrange[i]];
}
return res;
}
function getrowref(A, i) {
// return a pointer-like object on a row in a matrix, not a copy!
return A.val.subarray(i*A.n, (i+1)*A.n);
}
/*
SET function : set values in a subset of entries of a matrix or vector
For MATRICES:
set ( M, rows, cols, A ) => submatrix of M = A
set ( M, rows, A ) => subset of rows from M = A
set ( M, [], cols, A ) => subset of cols from M = A
set ( M, i, [], A ) => fill row M[i] with vector A (transposed)
set ( M, i, j, A) => M[i][j] = A
For VECTORS:
set ( v, rows, a ) => subvector from v = a
set ( v, i , a) => v[i] = a
*/
function set ( A , rowsrange, colsrange, B) {
var i;
var j;
var k;
var l;
var n;
var typerows = typeof(rowsrange);
var typecols = typeof(colsrange);
if (arguments.length == 1 )
return undefined;
var typeA = type ( A );
if ( typeA == "vector" ) {
B = colsrange;
if ( typerows == "number" ) {
A[rowsrange] = B;
return B;
}
else if ( rowsrange.length == 0 )
rowsrange = range(A.length);
if ( size(B,1) == 1 ) {
setVectorScalar (A, rowsrange, B);
}
else {
setVectorVector (A, rowsrange, B);
}
return B;
}
else if ( typeA == "matrix") {
if ( typerows == "number" )
rowsrange = [rowsrange];
if ( typecols == "number" )
colsrange = [colsrange];
if ( rowsrange.length == 1 && colsrange.length == 1 ) {
A.val[rowsrange[0]*A.n + colsrange[0]] = B;
return B;
}
if ( rowsrange.length == 0 ) {
setCols(A, colsrange, B);
return B;
}
if (colsrange.length == 0 ) {
setRows( A, rowsrange, B);
return B;
}
// Set a submatrix
var sB = size(B);
var tB = type(B);
if ( sB[0] == 1 && sB[1] == 1 ) {
if ( tB == "number" )
setMatrixScalar(A, rowsrange, colsrange, B);
else if ( tB == "vector" )
setMatrixScalar(A, rowsrange, colsrange, B[0]);
else
setMatrixScalar(A, rowsrange, colsrange, B.val[0]);
}
else {
if ( colsrange.length == 1 )
setMatrixColVector(A, rowsrange, colsrange[0], B);
else if ( rowsrange.length == 1 ) {
if ( tB == "vector" )
setMatrixRowVector(A, rowsrange[0], colsrange, B);
else
setMatrixRowVector(A, rowsrange[0], colsrange, B.val);
}
else
setMatrixMatrix(A, rowsrange, colsrange, B);
}
return B;
}
else if ( typeA == "ComplexVector" ) {
B = colsrange;
if ( typerows == "number" ) {
A.set(rowsrange, B);
return B;
}
else if ( rowsrange.length == 0 )
rowsrange = range(A.length);
if ( size(B,1) == 1 ) {
A.setVectorScalar (rowsrange, B);
}
else {
A.setVectorVector (rowsrange, B);
}
return B;
}
}
function setVectorScalar(A, rowsrange, B) {
var i;
for (i = 0; i< rowsrange.length; i++)
A[rowsrange[i]] = B;
}
function setVectorVector(A, rowsrange, B) {
var i;
for (i = 0; i< rowsrange.length; i++)
A[rowsrange[i]] = B[i];
}
function setMatrixScalar(A, rowsrange, colsrange, B) {
var i;
var j;
var m = rowsrange.length;
var n = colsrange.length;
for (i = 0; i< m; i++)
for(j=0; j < n; j++)
A.val[rowsrange[i]*A.n + colsrange[j]] = B;
}
function setMatrixMatrix(A, rowsrange, colsrange, B) {
var i;
var j;
var m = rowsrange.length;
var n = colsrange.length;
for (i = 0; i< m; i++)
for(j=0; j < n; j++)
A.val[rowsrange[i]*A.n + colsrange[j]] = B.val[i*B.n +j];
}
function setMatrixColVector(A, rowsrange, col, B) {
var i;
var m = rowsrange.length;
for (i = 0; i< m; i++)
A.val[rowsrange[i]*A.n + col] = B[i];
}
function setMatrixRowVector(A, row, colsrange, B) {
var j;
var n = colsrange.length;
for(j=0; j < n; j++)
A.val[row*A.n + colsrange[j]] = B[j];
}
function setRows(A, rowsrange, B ) {
var i;
var j;
var m = rowsrange.length;
var rA;
switch( type(B) ) {
case "vector":
for ( i=0; i<m; i++) {
rA = rowsrange[i]*A.n;
for ( j=0; j<B.length; j++)
A.val[rA + j] = B[j];
}
break;
case "matrix":
var rB = 0;
for ( i=0; i<m; i++) {
rA = rowsrange[i]*A.n;
for ( j=0; j < B.n; j++)
A.val[rA + j] = B.val[rB + j];
rB += B.n;
}
break;
default:
for ( i=0; i<m; i++) {
rA = rowsrange[i] * A.n;
for(j=0; j < A.n; j++)
A.val[rA + j] = B;
}
break;
}
}
function setCols(A, colsrange, B ) {
var i;
var m = A.m;
var n = colsrange.length;
var r = 0;
switch( type(B) ) {
case "vector":
for ( i=0; i<m; i++) {
for (j=0; j < n; j++)
A.val[r + colsrange[j]] = B[i];
r += A.n;
}
break;
case "matrix":
for ( i=0; i<m; i++) {
for (j=0; j < n; j++)
A.val[r + colsrange[j]] = B.val[i* B.n + j];
r += A.n;
}
break;
default:
for ( i=0; i<m; i++) {
for(j=0; j < n; j++)
A.val[r + colsrange[j]] = B;
r += A.n;
}
break;
}
}
function dense ( A ) {
return A;
}
// Support
function supp( x ) {
const tx = type (x);
if ( tx == "vector" ) {
var indexes = [];
var i;
for ( i = 0; i < x.length; i++ ) {
if ( !isZero(x[i]) )
indexes.push(i);
}
return indexes;
}
else if (tx == "spvector" ) {
return new Float64Array(x.ind);
}
else
return undefined;
}
// Range
function range(start, end, inc) {
// python-like range function
// returns [0,... , end-1]
if ( typeof(start) == "undefined" )
return [];
if ( typeof(inc) == "undefined" )
var inc = 1;
if ( typeof(end) == "undefined" ) {
var end = start;
start = 0;
}
if ( start == end-inc) {
return start;
}
else if ( start == end) {
return [];
}
else if ( start > end ) {
if ( inc > 0)
inc *= -1;
var r = new Array( Math.floor ( ( start - end ) / Math.abs(inc) ) );
var k = 0;
for ( var i = start; i> end; i+=inc) {
r[k] = i;
k++;
}
}
else {
var r = new Array( Math.floor ( ( end - start ) / inc ) );
var k = 0;
for ( var i = start; i< end; i+=inc) {
r[k] = i;
k++;
}
}
return r;
}
// Swaping
/**
* @param {Matrix}
*/
function swaprows ( A , i, j ) {
if ( i != j ) {
var ri = i*A.n;
var rj = j*A.n;
var tmp = vectorCopy(A.val.subarray(ri, ri+A.n));
A.val.set(vectorCopy(A.val.subarray(rj, rj+A.n)), ri);
A.val.set(tmp, rj);
}
}
/**
* @param {Matrix}
*/
function swapcols ( A , j, k ) {
if ( j != k ) {
var tmp = getCols ( A, [j]);
setCols ( A, [j] , getCols ( A, [k]) );
setCols ( A, [k], tmp);
}
}
//////////////////////////
// Random numbers
////////////////////////////
// Gaussian random number (mean = 0, variance = 1;
// Gaussian noise with the polar form of the Box-Muller transformation
function randnScalar() {
var x1;
var x2;
var w;
var y1;
var y2;
do {
x1 = 2.0 * Math.random() - 1.0;
x2 = 2.0 * Math.random() - 1.0;
w = x1 * x1 + x2 * x2;
} while ( w >= 1.0 );
w = Math.sqrt( (-2.0 * Math.log( w ) ) / w );
y1 = x1 * w;
y2 = x2 * w;
return y1;
}
function randn( dim1, dim2 ) {
var res;
if ( typeof ( dim1 ) == "undefined" || (dim1 == 1 && typeof(dim2)=="undefined") || (dim1 == 1 && dim2==1)) {
return randnScalar();
}
else if (typeof(dim2) == "undefined" || dim2 == 1 ) {
res = new Float64Array(dim1);
for (var i=0; i< dim1; i++)
res[i] = randnScalar();
return res;
}
else {
res = zeros(dim1, dim2);
for (var i=0; i< dim1*dim2; i++) {
res.val[i] = randnScalar();
}
return res;
}
}
// Uniform random numbers
/*
* @param{number}
* @return{Float64Array}
*/
function randVector(dim1) {
var res = new Float64Array(dim1);
for (var i=0; i< dim1; i++) {
res[i] = Math.random();
}
return res;
}
/*
* @param{number}
* @param{number}
* @return{Matrix}
*/
function randMatrix(dim1,dim2) {
const n = dim1*dim2;
var res = new Float64Array(n);
for (var i=0; i< n; i++) {
res[i] = Math.random();
}
return new Matrix(dim1,dim2,res,true);
}
function rand( dim1, dim2 ) {
var res;
if ( typeof ( dim1 ) == "undefined" || (dim1 == 1 && typeof(dim2)=="undefined") || (dim1 == 1 && dim2==1)) {
return Math.random();
}
else if (typeof(dim2) == "undefined" || dim2 == 1) {
return randVector(dim1);
}
else {
return randMatrix(dim1,dim2);
}
}
function randnsparse(NZratio, dim1, dim2) {
// Generates a sparse random matrix with NZratio * dim1*dim2 (or NZ if NZratio > 1 ) nonzeros
var NZ;
if ( NZratio > 1 )
NZ = NZratio;
else
NZ = Math.floor(NZratio *dim1*dim2);
var indexes;
var i;
var j;
var k;
var res;
if ( typeof ( dim1 ) == "undefined" ) {
return randn();
}
else if (typeof(dim2) == "undefined" || dim2 == 1) {
indexes = randperm( dim1 );
res = zeros(dim1);
for (i=0; i< NZ; i++) {
res[indexes[i]] = randn();
}
return res;
}
else {
res = zeros(dim1, dim2);
indexes = randperm( dim1*dim2 );
for (k=0; k< NZ; k++) {
i = Math.floor(indexes[k] / dim2);
j = indexes[k] - i * dim2;
res.val[i*dim2+j] = randn();
}
return res;
}
}
function randsparse(NZratio, dim1, dim2) {
// Generates a sparse random matrix with NZratio * dim1*dim2 (or NZ if NZratio > 1 ) nonzeros
if (typeof(dim2) == "undefined")
var dim2 = 1;
var NZ;
if ( NZratio > 1 )
NZ = NZratio;
else
NZ = Math.floor(NZratio *dim1*dim2);
var indexes;
var i;
var j;
var k;
var res;
if ( typeof ( dim1 ) == "undefined" ) {
return randn();
}
else if (dim2 == 1) {
indexes = randperm( dim1 );
res = zeros(dim1);
for (i=0; i< NZ; i++) {
res[indexes[i]] = Math.random();
}
return res;
}
else {
res = zeros(dim1, dim2);
indexes = randperm( dim1*dim2 );
for (k=0; k< NZ; k++) {
i = Math.floor(indexes[k] / dim2);
j = indexes[k] - i * dim2;
res.val[i*dim2+j] = Math.random();
}
return res;
}
}
function randperm( x ) {
// return a random permutation of x (or of range(x) if x is a number)
if ( typeof( x ) == "number" ) {
var perm = range(x);
}
else {
var perm = new Float64Array(x);
}
var i;
var j;
var k;
// shuffle
for(i=perm.length - 1 ; i > 1; i--) {
j = Math.floor(Math.random() * i);
k = perm[j];
perm[j] = perm[i];
perm[i] = k;
}
return perm;
}
///////////////////////////////
/// Basic Math function: give access to Math.* JS functions
/// and vectorize them
///////////////////////////////
// automatically generate (vectorized) wrappers for Math functions
var MathFunctions = Object.getOwnPropertyNames(Math);
for ( var mf in MathFunctions ) {
if ( eval( "typeof(Math." + MathFunctions[mf] + ")") == "function") {
if ( eval( "Math." + MathFunctions[mf] + ".length") == 1 ) {
// this is a function of a scalar
// make generic function:
eval( MathFunctions[mf] + " = function (x) { return apply(Math."+ MathFunctions[mf] + " , x );};");
// make vectorized version:
eval( MathFunctions[mf] + "Vector = function (x) { return applyVector(Math."+ MathFunctions[mf] + " , x );};");
// make matrixized version:
eval( MathFunctions[mf] + "Matrix = function (x) { return applyMatrix(Math."+ MathFunctions[mf] + " , x );};");
}
}
else if ( eval( "typeof(Math." + MathFunctions[mf] + ")") == "number") {
// Math constant:
eval( MathFunctions[mf] + " = Math."+ MathFunctions[mf] ) ;
}
}
function apply( f, x ) {
// Generic wrapper to apply scalar functions
// element-wise to vectors and matrices
if ( typeof(f) != "function")
return undefined;
switch ( type( x ) ) {
case "number":
return f(x);
break;
case "Complex":
var ComplexFunctions = ["exp", "abs"];
var fc = ComplexFunctions.indexOf(f.name);
if ( fc >= 0 )
return eval(ComplexFunctions[fc] + "Complex(x);");
else {
error("This function has no Complex counterpart (yet).");
return undefined;
}
break;
case "vector":
return applyVector(f, x);
break;
case "spvector":
return applyspVector(f, x);
break;
case "ComplexVector":
if ( f.name == "abs" )
return absComplex(x);
else
return applyComplexVector(f, x);
break;
case "matrix":
return applyMatrix(f, x);
break;
case "spmatrix":
return applyspMatrix(f, x);
break;
case "ComplexMatrix":
if ( f.name == "abs" )
return absComplex(x);
else
return applyComplexMatrix(f, x);
break;
default:
return "undefined";
}
}
function applyVector( f, x ) {
const nv = x.length;
var res = new Float64Array(nv);
for (var i=0; i< nv; i++)
res[i] = f(x[i]);
return res;
}
function applyComplexVector( f, x ) {
const nv = x.length;
var res = new ComplexVector(nv);
for (var i=0; i< nv; i++)
res.set(i, f(x.get(i) ) );
return res;
}
function applyComplexMatrix( f, x ) {
const m = x.m;
const n = x.n;
var res = new ComplexMatrix(m, n);
for (var i=0; i< m; i++)
for ( var j =0; j < n; j++)
res.set(i, j, f(x.get(i,j) ) );
return res;
}
function applyMatrix(f, x) {
return new Matrix(x.m, x.n, applyVector(f, x.val), true);
}
///////////////////////////////
/// Operators
///////////////////////////////
function mul(a,b) {
var sa = size(a);
var sb = size(b);
if ( !isScalar(a) && sa[0] == 1 && sa[1] == 1 )
a = get(a, 0, 0);
if ( !isScalar(b) && sb[0] == 1 && sb[1] == 1 )
b = get(b, 0, 0);
switch( type(a) ) {
case "number":
switch( type(b) ) {
case "number":
return a*b;
break;
case "Complex":
return mulComplexReal(b,a);
break;
case "vector":
return mulScalarVector(a,b);
break;
case "spvector":
return mulScalarspVector(a,b);
break;
case "ComplexVector":
return mulScalarComplexVector(a,b);
break;
case "matrix":
return mulScalarMatrix(a,b);
break;
case "spmatrix":
return mulScalarspMatrix(a,b);
break;
case "ComplexMatrix":
return mulScalarComplexMatrix(a,b);
break;
default:
return undefined;
break;
}
break;
case "Complex":
switch( type(b) ) {
case "number":
return mulComplexReal(a,b);
break;
case "Complex":
return mulComplex(a,b);
break;
case "vector":
return mulComplexVector(a,b);
break;
case "ComplexVector":
return mulComplexComplexVector(a,b);
break;
case "spvector":
return mulComplexspVector(a,b);
break;
case "matrix":
return mulComplexMatrix(a,b);
break;
case "ComplexMatrix":
return mulComplexComplexMatrix(a,b);
break;
case "spmatrix":
return mulComplexspMatrix(a,b);
break;
default:
return undefined;
break;
}
break;
case "vector":
switch( type(b) ) {
case "number":
return mulScalarVector(b,a);
break;
case "Complex":
return mulComplexVector(b,a);
break;
case "vector":
if ( a.length != b.length ) {
error("Error in mul(a,b) (dot product): a.length = " + a.length + " != " + b.length + " = b.length.");
return undefined;
}
return dot(a,b);
break;
case "spvector":
if ( a.length != b.length ) {
error("Error in mul(a,b) (dot product): a.length = " + a.length + " != " + b.length + " = b.length.");
return undefined;
}
return dotspVectorVector(b,a);
break;
case "ComplexVector":
if ( a.length != b.length ) {
error("Error in mul(a,b) (dot product): a.length = " + a.length + " != " + b.length + " = b.length.");
return undefined;
}
return dotComplexVectorVector(b,a);
break;
case "matrix":
if ( b.m == 1)
return outerprodVectors(a , b.val );
else {
error("Inconsistent dimensions in mul(a,B): size(a) = [" + sa[0] + "," + sa[1] + "], size(B) = [" + sb[0] + "," + sb[1] + "]");
return undefined;
}
break;
case "spmatrix":
if ( b.m == 1)
return outerprodVectors(a , fullMatrix(b).val );
else {
error("Inconsistent dimensions in mul(a,B): size(a) = [" + sa[0] + "," + sa[1] + "], size(B) = [" + sb[0] + "," + sb[1] + "]");
return undefined;
}
break;
case "ComplexMatrix":
if ( b.m == 1)
return transpose(outerprodComplexVectorVector(new ComplexVector(b.re,b.im,true), a , b.val ));
else {
error("Inconsistent dimensions in mul(a,B): size(a) = [" + sa[0] + "," + sa[1] + "], size(B) = [" + sb[0] + "," + sb[1] + "]");
return undefined;
}
break;
default:
return undefined;
break;
}
break;
case "spvector":
switch( type(b) ) {
case "number":
return mulScalarspVector(b,a);
break;
case "vector":
if ( a.length != b.length ) {
error("Error in mul(a,b) (dot product): a.length = " + a.length + " != " + b.length + " = b.length.");
return undefined;
}
return dotspVectorVector(a,b);
break;
case "spvector":
if ( a.length != b.length ) {
error("Error in mul(a,b) (dot product): a.length = " + a.length + " != " + b.length + " = b.length.");
return undefined;
}
return spdot(b,a);
break;
case "matrix":
if ( b.m == 1)
return outerprodspVectorVector(a , b.val );
else {
error("Inconsistent dimensions in mul(a,B): size(a) = [" + sa[0] + "," + sa[1] + "], size(B) = [" + sb[0] + "," + sb[1] + "]");
return undefined;
}
break;
case "spmatrix":
if ( b.m == 1)
return outerprodspVectorVector(a, fullMatrix(b).val);
else {
error("Inconsistent dimensions in mul(a,B): size(a) = [" + sa[0] + "," + sa[1] + "], size(B) = [" + sb[0] + "," + sb[1] + "]");
return undefined;
}
break;
default:
return undefined;
break;
}
break;
case "ComplexVector":
switch( type(b) ) {
case "number":
return mulScalarComplexVector(b,a);
break;
case "Complex":
return mulComplexComplexVector(b,a);
break;
case "vector":
if ( a.length != b.length ) {
error("Error in mul(a,b) (dot product): a.length = " + a.length + " != " + b.length + " = b.length.");
return undefined;
}
return dotComplexVectorVector(a,b);
break;
case "spvector":
if ( a.length != b.length ) {
error("Error in mul(a,b) (dot product): a.length = " + a.length + " != " + b.length + " = b.length.");
return undefined;
}
return dotComplexVectorspVector(a,b);
break;
case "matrix":
if ( b.m == 1)
return outerprodComplexVectorVector(a , b.val );
else {
error("Inconsistent dimensions in mul(a,B): size(a) = [" + sa[0] + "," + sa[1] + "], size(B) = [" + sb[0] + "," + sb[1] + "]");
return undefined;
}
break;
case "spmatrix":
if ( b.m == 1)
return outerprodComplexVectorVector(a , fullMatrix(b).val );
else {
error("Inconsistent dimensions in mul(a,B): size(a) = [" + sa[0] + "," + sa[1] + "], size(B) = [" + sb[0] + "," + sb[1] + "]");
return undefined;
}
break;
case "ComplexMatrix":
if ( b.m == 1)
return outerprodComplexVectors(a , new ComplexVector(b.re,b.im, true) );
else {
error("Inconsistent dimensions in mul(a,B): size(a) = [" + sa[0] + "," + sa[1] + "], size(B) = [" + sb[0] + "," + sb[1] + "]");
return undefined;
}
break;
default:
return undefined;
break;
}
break;
case "matrix":
switch( type(b) ) {
case "number":
return mulScalarMatrix(b,a);
break;
case "Complex":
return mulComplexMatrix(b,a);
break;
case "vector":
if ( a.m == 1 ) {
// dot product with explicit transpose
if ( a.val.length != b.length ) {
error("Error in mul(a',b): a.length = " + a.val.length + " != " + b.length + " = b.length.");
return undefined;
}
return dot(a.val, b);
}
else {
if ( a.n != b.length ) {
error("Error in mul(A,b): A.n = " + a.n + " != " + b.length + " = b.length.");
return undefined;
}
return mulMatrixVector(a,b);
}
break;
case "spvector":
if ( a.m == 1 ) {
// dot product with explicit transpose
if ( a.val.length != b.length ) {
error("Error in mul(a',b): a.length = " + a.val.length + " != " + b.length + " = b.length.");
return undefined;
}
return dotspVectorVector(b, a.val);
}
else {
if ( a.n != b.length ) {
error("Error in mul(A,b): A.n = " + a.n + " != " + b.length + " = b.length.");
return undefined;
}
return mulMatrixspVector(a,b);
}
break;
case "ComplexVector":
if ( a.m == 1 ) {
// dot product with explicit transpose
if ( a.val.length != b.length ) {
error("Error in mul(a',b): a.length = " + a.val.length + " != " + b.length + " = b.length.");
return undefined;
}
return dotComplexVectorVector(b, a.val);
}
else {
if ( a.n != b.length ) {
error("Error in mul(A,b): A.n = " + a.n + " != " + b.length + " = b.length.");
return undefined;
}
return mulMatrixComplexVector(a,b);
}
break;
case "matrix":
if ( a.n != b.m ) {
error("Error in mul(A,B): A.n = " + a.n + " != " + b.m + " = B.m.");
return undefined;
}
return mulMatrixMatrix(a,b);
break;
case "spmatrix":
if ( a.n != b.m ) {
error("Error in mul(A,B): A.n = " + a.n + " != " + b.m + " = B.m.");
return undefined;
}
return mulMatrixspMatrix(a,b);
break;
case "ComplexMatrix":
if ( a.n != b.m ) {
error("Error in mul(A,B): A.n = " + a.n + " != " + b.m + " = B.m.");
return undefined;
}
return transpose(mulComplexMatrixMatrix(transpose(b),transpose(a)));
break;
default:
return undefined;
break;
}
break;
case "spmatrix":
switch( type(b) ) {
case "number":
return mulScalarspMatrix(b,a);
break;
case "vector":
if ( a.m == 1 ) {
// dot product with explicit transpose
if ( a.n != b.length ) {
error("Error in mul(a',b): a.length = " + a.val.length + " != " + b.length + " = b.length.");
return undefined;
}
return dot(fullMatrix(a).val, b);
}
else {
if ( a.n != b.length ) {
error("Error in mul(A,b): A.n = " + a.n + " != " + b.length + " = b.length.");
return undefined;
}
return mulspMatrixVector(a,b);
}
break;
case "spvector":
if ( a.m == 1 ) {
// dot product with explicit transpose
if ( a.n != b.length ) {
error("Error in mul(a',b): a.length = " + a.val.length + " != " + b.length + " = b.length.");
return undefined;
}
return dotspVectorVector(b, fullMatrix(a).val);
}
else {
if ( a.n != b.length ) {
error("Error in mul(A,b): A.n = " + a.n + " != " + b.length + " = b.length.");
return undefined;
}
return mulspMatrixspVector(a,b);
}
break;
case "matrix":
if ( a.n != b.m ) {
error("Error in mul(A,B): A.n = " + a.n + " != " + b.m + " = B.m.");
return undefined;
}
return mulspMatrixMatrix(a,b);
break;
case "spmatrix":
if ( a.n != b.m ) {
error("Error in mul(A,B): A.n = " + a.n + " != " + b.m + " = B.m.");
return undefined;
}
return mulspMatrixspMatrix(a,b);
break;
default:
return undefined;
break;
}
break;
case "ComplexMatrix":
switch( type(b) ) {
case "number":
return mulScalarComplexMatrix(b,a);
break;
case "Complex":
return mulComplexComplexMatrix(b,a);
break;
case "vector":
if ( a.m == 1 ) {
// dot product with explicit transpose
if ( a.val.length != b.length ) {
error("Error in mul(a',b): a.length = " + a.val.length + " != " + b.length + " = b.length.");
return undefined;
}
return dotComplexVectorVector(new ComplexVector(a.re,a.im,true), b);
}
else {
if ( a.n != b.length ) {
error("Error in mul(A,b): A.n = " + a.n + " != " + b.length + " = b.length.");
return undefined;
}
return mulComplexMatrixVector(a,b);
}
break;
case "spvector":
if ( a.m == 1 ) {
// dot product with explicit transpose
if ( a.val.length != b.length ) {
error("Error in mul(a',b): a.length = " + a.val.length + " != " + b.length + " = b.length.");
return undefined;
}
return dotComplexVectorspVector(new ComplexVector(a.re,a.im,true), b);
}
else {
if ( a.n != b.length ) {
error("Error in mul(A,b): A.n = " + a.n + " != " + b.length + " = b.length.");
return undefined;
}
return mulComplexMatrixspVector(a,b);
}
break;
case "ComplexVector":
if ( a.m == 1 ) {
// dot product with explicit transpose
if ( a.val.length != b.length ) {
error("Error in mul(a',b): a.length = " + a.val.length + " != " + b.length + " = b.length.");
return undefined;
}
return dotComplexVectors(new ComplexVector(a.re,a.im,true), b);
}
else {
if ( a.n != b.length ) {
error("Error in mul(A,b): A.n = " + a.n + " != " + b.length + " = b.length.");
return undefined;
}
return mulComplexMatrixComplexVector(a,b);
}
break;
case "matrix":
if ( a.n != b.m ) {
error("Error in mul(A,B): A.n = " + a.n + " != " + b.m + " = B.m.");
return undefined;
}
return mulComplexMatrixMatrix(a,b);
break;
case "spmatrix":
if ( a.n != b.m ) {
error("Error in mul(A,B): A.n = " + a.n + " != " + b.m + " = B.m.");
return undefined;
}
return mulComplexMatrixspMatrix(a,b);
break;
case "ComplexMatrix":
if ( a.n != b.m ) {
error("Error in mul(A,B): A.n = " + a.n + " != " + b.m + " = B.m.");
return undefined;
}
return mulComplexMatrices(a,b);
break;
default:
return undefined;
break;
}
break;
default:
return undefined;
break;
}
}
/**
* @param {number}
* @param {Float64Array}
* @return {Float64Array}
*/
function mulScalarVector( scalar, vec ) {
var i;
const n = vec.length;
var res = new Float64Array(vec);
for ( i=0; i < n; i++)
res[i] *= scalar ;
return res;
}
/**
* @param {number}
* @param {Matrix}
* @return {Matrix}
*/
function mulScalarMatrix( scalar, A ) {
var res = new Matrix(A.m,A.n, mulScalarVector(scalar, A.val), true );
return res;
}
/**
* @param {Float64Array}
* @param {Float64Array}
* @return {number}
*/
function dot(a, b) {
const n = a.length;
var i;
var res = 0;
for ( i=0; i< n; i++)
res += a[i]*b[i];
return res;
}
/**
* @param {Matrix}
* @param {Float64Array}
* @return {Float64Array}
*/
function mulMatrixVector( A, b ) {
const m = A.length;
var c = new Float64Array(m);
var r = 0;
for (var i=0; i < m; i++) {
c[i] = dot(A.val.subarray(r, r+A.n), b);
r += A.n;
}
return c;
}
/**
* @param {Matrix}
* @param {Float64Array}
* @return {Float64Array}
*/
function mulMatrixTransVector( A, b ) {
const m = A.length;
const n = A.n;
var c = new Float64Array(n);
var rj = 0;
for (var j=0; j < m; j++) {
var bj = b[j];
for (var i=0; i < n; i++) {
c[i] += A.val[rj + i] * bj;
}
rj += A.n;
}
return c;
}
/**
* @param {Matrix}
* @param {Matrix}
* @return {Matrix}
*/
function mulMatrixMatrix(A, B) {
const m = A.length;
const n = B.n;
const n2 = B.length;
var Av = A.val;
var Bv = B.val;
var C = new Float64Array(m*n);
var aik;
var Aik = 0;
var Ci = 0;
for (var i=0;i < m ; i++) {
var bj = 0;
for (var k=0; k < n2; k++ ) {
aik = Av[Aik];
for (var j =0; j < n; j++) {
C[Ci + j] += aik * Bv[bj];
bj++;
}
Aik++;
}
Ci += n;
}
return new Matrix(m,n,C, true);
}
/**
* @param {Float64Array}
* @param {Float64Array}
* @return {Float64Array}
*/
function entrywisemulVector( a, b) {
var i;
const n = a.length;
var res = new Float64Array(n);
for ( i=0; i < n; i++)
res[i] = a[i] * b[i];
return res;
}
/**
* @param {Matrix}
* @param {Matrix}
* @return {Matrix}
*/
function entrywisemulMatrix( A, B) {
var res = new Matrix(A.m,A.n, entrywisemulVector(A.val, B.val), true );
return res;
}
function entrywisemul(a,b) {
var sa = size(a);
var sb = size(b);
if (typeof(a) != "number" && sa[0] == 1 && sa[1] == 1 )
a = get(a, 0, 0);
if (typeof(b) != "number" && sb[0] == 1 && sb[1] == 1 )
b = get(b, 0, 0);
switch( type(a) ) {
case "number":
switch( type(b) ) {
case "number":
return a*b;
break;
case "Complex":
return mulComplexReal(b,a);
break;
case "vector":
return mulScalarVector(a,b);
break;
case "spvector":
return mulScalarspVector(a,b);
break;
case "ComplexVector":
return mulScalarComplexVector(b,a);
break;
case "matrix":
return mulScalarMatrix(a,b);
break;
case "spmatrix":
return mulScalarspMatrix(a,b);
break;
case "ComplexMatrix":
return mulScalarComplexMatrix(b,a);
break;
default:
return undefined;
break;
}
break;
case "vector":
switch( type(b) ) {
case "number":
return mulScalarVector(b,a);
break;
case "Complex":
return mulComplexVector(b,a);
break;
case "vector":
if ( a.length != b.length ) {
error("Error in entrywisemul(a,b): a.length = " + a.length + " != " + b.length + " = b.length.");
return undefined;
}
return entrywisemulVector(a,b);
break;
case "ComplexVector":
if ( a.length != b.length ) {
error("Error in entrywisemul(a,b): a.length = " + a.length + " != " + b.length + " = b.length.");
return undefined;
}
return entrywisemulComplexVectorVector(b,a);
break;
case "spvector":
if ( a.length != b.length ) {
error("Error in entrywisemul(a,b): a.length = " + a.length + " != " + b.length + " = b.length.");
return undefined;
}
return entrywisemulspVectorVector(b,a);
break;
case "matrix":
case "spmatrix":
case "ComplexMatrix":
error("Error in entrywisemul(a,B): a is a vector and B is a matrix.");
return undefined;
break;
default:
return undefined;
break;
}
break;
case "spvector":
switch( type(b) ) {
case "number":
return mulScalarspVector(b,a);
break;
case "vector":
if ( a.length != b.length ) {
error("Error in entrywisemul(a,b): a.length = " + a.length + " != " + b.length + " = b.length.");
return undefined;
}
return entrywisemulspVectorVector(a,b);
break;
case "spvector":
if ( a.length != b.length ) {
error("Error in entrywisemul(a,b): a.length = " + a.length + " != " + b.length + " = b.length.");
return undefined;
}
return entrywisemulspVectors(a,b);
break;
case "matrix":
error("Error in entrywisemul(a,B): a is a vector and B is a Matrix.");
return undefined;
break;
case "spmatrix":
error("Error in entrywisemul(a,B): a is a vector and B is a Matrix.");
return undefined;
break;
default:
return undefined;
break;
}
break;
case "matrix":
switch( type(b) ) {
case "number":
return mulScalarMatrix(b,a);
break;
case "Complex":
return mulComplexMatrix(b,a);
break;
case "vector":
case "spvector":
case "ComplexVector":
error("Error in entrywisemul(A,b): A is a Matrix and b is a vector.");
return undefined;
break;
case "matrix":
if ( a.m != b.m || a.n != b.n ) {
error("Error in entrywisemul(A,B): size(A) = [" + a.m + "," + a.n + "] != [" + b.m + "," + b.n + "] = size(B).");
return undefined;
}
return entrywisemulMatrix(a,b);
break;
case "spmatrix":
if ( a.m != b.m || a.n != b.n ) {
error("Error in entrywisemul(A,B): size(A) = [" + a.m + "," + a.n + "] != [" + b.m + "," + b.n + "] = size(B).");
return undefined;
}
return entrywisemulspMatrixMatrix(b,a);
break;
case "ComplexMatrix":
if ( a.m != b.m || a.n != b.n ) {
error("Error in entrywisemul(A,B): size(A) = [" + a.m + "," + a.n + "] != [" + b.m + "," + b.n + "] = size(B).");
return undefined;
}
return entrywisemulComplexMatrixMatrix(b,a);
break;
default:
return undefined;
break;
}
break;
case "spmatrix":
switch( type(b) ) {
case "number":
return mulScalarspMatrix(b,a);
break;
case "vector":
error("Error in entrywisemul(A,b): A is a Matrix and b is a vector.");
return undefined;
break;
case "spvector":
error("Error in entrywisemul(A,b): A is a Matrix and b is a vector.");
return undefined;
break;
case "matrix":
if ( a.m != b.m || a.n != b.n ) {
error("Error in entrywisemul(A,B): size(A) = [" + a.m + "," + a.n + "] != [" + b.m + "," + b.n + "] = size(B).");
return undefined;
}
return entrywisemulspMatrixMatrix(a,b);
break;
case "spmatrix":
if ( a.m != b.m || a.n != b.n ) {
error("Error in entrywisemul(A,B): size(A) = [" + a.m + "," + a.n + "] != [" + b.m + "," + b.n + "] = size(B).");
return undefined;
}
return entrywisemulspMatrices(a,b);
break;
default:
return undefined;
break;
}
break;
case "ComplexVector":
switch( type(b) ) {
case "number":
return mulScalarComplexVector(b,a);
break;
case "Complex":
return mulComplexComplexVector(b,a);
break;
case "vector":
if ( a.length != b.length ) {
error("Error in entrywisemul(a,b): a.length = " + a.length + " != " + b.length + " = b.length.");
return undefined;
}
return entrywisemulComplexVectorVector(a,b);
break;
case "ComplexVector":
if ( a.length != b.length ) {
error("Error in entrywisemul(a,b): a.length = " + a.length + " != " + b.length + " = b.length.");
return undefined;
}
return entrywisemulComplexVectors(a,b);
break;
case "spvector":
if ( a.length != b.length ) {
error("Error in entrywisemul(a,b): a.length = " + a.length + " != " + b.length + " = b.length.");
return undefined;
}
return entrywisemulComplexVectorspVector(a,b);
break;
case "matrix":
case "spmatrix":
case "ComplexMatrix":
error("Error in entrywisemul(a,B): a is a vector and B is a matrix.");
return undefined;
break;
default:
return undefined;
break;
}
break;
case "ComplexMatrix":
switch( type(b) ) {
case "number":
return mulScalarComplexMatrix(b,a);
break;
case "Complex":
return mulComplexComplexMatrix(b,a);
break;
case "vector":
case "spvector":
case "ComplexVector":
error("Error in entrywisemul(A,b): A is a Matrix and b is a vector.");
return undefined;
break;
case "matrix":
if ( a.m != b.m || a.n != b.n ) {
error("Error in entrywisemul(A,B): size(A) = [" + a.m + "," + a.n + "] != [" + b.m + "," + b.n + "] = size(B).");
return undefined;
}
return entrywisemulComplexMatrixMatrix(a,b);
break;
case "spmatrix":
if ( a.m != b.m || a.n != b.n ) {
error("Error in entrywisemul(A,B): size(A) = [" + a.m + "," + a.n + "] != [" + b.m + "," + b.n + "] = size(B).");
return undefined;
}
return entrywisemulComplexMatrixspMatrix(a,b);
break;
case "ComplexMatrix":
if ( a.m != b.m || a.n != b.n ) {
error("Error in entrywisemul(A,B): size(A) = [" + a.m + "," + a.n + "] != [" + b.m + "," + b.n + "] = size(B).");
return undefined;
}
return entrywisemulComplexMatrices(a,b);
break;
default:
return undefined;
break;
}
break;
default:
return undefined;
break;
}
}
/** SAXPY : y = y + ax
* @param {number}
* @param {Float64Array}
* @param {Float64Array}
*/
function saxpy ( a, x, y) {
const n = y.length;
for ( var i=0; i < n; i++)
y[i] += a*x[i];
}
/** GAXPY : y = y + Ax
* @param {Matrix}
* @param {Float64Array}
* @param {Float64Array}
*/
function gaxpy ( A, x, y) {
const m = A.m;
const n = A.n;
var r = 0;
for ( var i=0; i < m; i++) {
y[i] += dot(A.val.subarray(r, r + n),x);
r += n;
}
}
/**
* @param {Float64Array}
* @param {number}
* @return {Float64Array}
*/
function divVectorScalar( a, b) {
var i;
const n = a.length;
var res = new Float64Array(a);
for ( i=0; i < n; i++)
res[i] /= b;
return res;
}
/**
* @param {number}
* @param {Float64Array}
* @return {Float64Array}
*/
function divScalarVector ( a, b) {
var i;
const n = b.length;
var res = new Float64Array(n);
for ( i=0; i < n; i++)
res[i] = a / b[i];
return res;
}
/**
* @param {Float64Array}
* @param {Float64Array}
* @return {Float64Array}
*/
function divVectors( a, b) {
var i;
const n = a.length;
var res = new Float64Array(a);
for ( i=0; i < n; i++)
res[i] /= b[i];
return res;
}
/**
* @param {Matrix}
* @param {number}
* @return {Matrix}
*/
function divMatrixScalar( A, b) {
var res = new Matrix(A.m, A.n, divVectorScalar(A.val , b ), true);
return res;
}
/**
* @param {number}
* @param {Matrix}
* @return {Matrix}
*/
function divScalarMatrix( a, B) {
var res = new Matrix(B.m, B.n, divScalarVector(a, B.val ), true);
return res;
}
/**
* @param {Matrix}
* @param {Matrix}
* @return {Matrix}
*/
function divMatrices( A, B) {
var res = new Matrix(A.m, A.n, divVectors(A.val, B.val ), true);
return res;
}
function entrywisediv(a,b) {
var ta = type(a);
var tb = type(b);
switch(ta) {
case "number":
switch(tb) {
case "number":
return a/b;
break;
case "vector":
return divScalarVector(a,b);
break;
case "matrix":
return divScalarMatrix(a,b);
break;
case "spvector":
return divScalarspVector(a,b);
break;
case "spmatrix":
return divScalarspMatrix(a,b);
break;
default:
error("Error in entrywisediv(a,b): b must be a number, a vector or a matrix.");
return undefined;
}
break;
case "vector":
switch(tb) {
case "number":
return divVectorScalar(a,b);
break;
case "vector":
if ( a.length != b.length ) {
error("Error in entrywisediv(a,b): a.length = " + a.length + " != " + b.length + " = b.length.");
return undefined;
}
return divVectors(a,b);
break;
case "spvector":
error("Error in entrywisediv(a,b): b is a sparse vector with zeros.");
break;
default:
error("Error in entrywisediv(a,B): a is a vector and B is a " + tb + ".");
return undefined;
}
break;
case "spvector":
switch(tb) {
case "number":
return mulScalarspVector(1/b, a);
break;
case "vector":
if ( a.length != b.length ) {
error("Error in entrywisediv(a,b): a.length = " + a.length + " != " + b.length + " = b.length.");
return undefined;
}
return divVectorspVector(a,b);
break;
case "spvector":
error("Error in entrywisediv(a,b): b is a sparse vector with zeros.");
return undefined;
break;
default:
error("Error in entrywisediv(a,B): a is a vector and B is a " + tb + ".");
return undefined;
}
break;
case "matrix":
switch(tb) {
case "number":
return divMatrixScalar(a,b);
break;
case "matrix":
if ( a.m != b.m || a.n != b.n ) {
error("Error in entrywisediv(A,B): size(A) = [" + a.m + "," + a.n + "] != [" + b.m + "," + b.n + "] = size(B).");
return undefined;
}
return divMatrices(a,b);
break;
case "spmatrix":
error("Error in entrywisediv(A,B): B is a sparse matrix with zeros.");
return undefined;
break;
default:
error("Error in entrywisediv(A,b): a is a matrix and B is a " + tb + ".");
return undefined;
}
case "spmatrix":
switch(tb) {
case "number":
return mulScalarspMatrix(1/b,a);
break;
case "matrix":
if ( a.m != b.m || a.n != b.n ) {
error("Error in entrywisediv(A,B): size(A) = [" + a.m + "," + a.n + "] != [" + b.m + "," + b.n + "] = size(B).");
return undefined;
}
return divMatrixspMatrix(a,b);
break;
case "spmatrix":
error("Error in entrywisediv(A,B): B is a sparse matrix with zeros.");
return undefined;
break;
default:
error("Error in entrywisediv(A,b): a is a matrix and B is a " + tb + ".");
return undefined;
}
break;
default:
error("Error in entrywisediv(a,b): a must be a number, a vector or a matrix.");
return undefined;
break;
}
}
function outerprodVectors(a, b, scalar) {
var i;
var j;
var ui;
const m = a.length;
const n = b.length;
var res = new Matrix(m,n);
if( arguments.length == 3 ) {
for (i=0; i< m; i++)
res.val.set( mulScalarVector(scalar*a[i], b), i*n);
}
else {
for (i=0; i< m; i++)
res.val.set( mulScalarVector(a[i], b), i*n);
}
return res;
}
function outerprod( u , v, scalar ) {
// outer product of two vectors : res = scalar * u * v^T
if (typeof(u) == "number" ) {
if ( typeof(v) == "number" ) {
if ( arguments.length == 2 )
return u*v;
else
return u*v*scalar;
}
else {
if ( arguments.length == 2 )
return new Matrix(1,v.length, mulScalarVector(u, v), true );
else
return new Matrix(1,v.length, mulScalarVector(u*scalar, v), true );
}
}
if ( u.length == 1 ) {
if ( typeof(v) == "number" ) {
if ( arguments.length == 2 )
return u[0]*v;
else
return u[0]*v*scalar;
}
else {
if ( arguments.length == 2 )
return new Matrix(1,v.length, mulScalarVector(u[0], v) , true);
else
return new Matrix(1,v.length, mulScalarVector(u[0]*scalar, v), true );
}
}
if (typeof(v) == "number" ) {
if (arguments.length == 2 )
return mulScalarVector(v, u);
else
return mulScalarVector( scalar * v , u);
}
if ( v.length == 1) {
if ( arguments.length == 2 )
return mulScalarVector(v[0], u);
else
return mulScalarVector( scalar * v[0] , u);
}
if ( arguments.length == 2 )
return outerprodVectors(u,v);
else
return outerprodVectors(u,v, scalar);
}
/**
* @param {number}
* @param {Float64Array}
* @return {Float64Array}
*/
function addScalarVector ( scalar, vec ) {
const n = vec.length;
var res = new Float64Array(vec);
for (var i = 0 ; i< n; i++)
res[i] += scalar ;
return res;
}
/**
* @param {number}
* @param {Matrix}
* @return {Matrix}
*/
function addScalarMatrix(a, B ) {
return new Matrix(B.m, B.n, addScalarVector(a, B.val), true );
}
/**
* @param {Float64Array}
* @param {Float64Array}
* @return {Float64Array}
*/
function addVectors(a,b) {
const n = a.length;
var c = new Float64Array(a);
for (var i=0; i < n; i++)
c[i] += b[i];
return c;
}
/**
* @param {Matrix}
* @param {Matrix}
* @return {Matrix}
*/
function addMatrices(A,B) {
return new Matrix(A.m, A.n, addVectors(A.val, B.val) , true);
}
function add(a,b) {
const ta = type(a);
const tb = type(b);
if ( ta == "number" && tb == "number" || ta == "string" || tb == "string")
return a + b;
else if ( ta == "number") {
switch(tb) {
case "Complex":
return addComplexReal(b,a);
break;
case "vector":
return addScalarVector(a,b);
break;
case "matrix":
return addScalarMatrix(a,b);
break;
case "spvector":
return addScalarspVector(a,b);
break;
case "spmatrix":
return addScalarspMatrix(a,b);
break;
case "ComplexVector":
return addScalarComplexVector(a,b);
break;
case "ComplexMatrix":
return addScalarComplexMatrix(a,b);
break;
default:
return undefined;
break;
}
}
else if ( tb == "number" ) {
switch(ta) {
case "Complex":
return addComplexReal(a,b);
break;
case "vector":
return addScalarVector(b,a);
break;
case "matrix":
return addScalarMatrix(b,a);
break;
case "spvector":
return addScalarspVector(b,a);
break;
case "spmatrix":
return addScalarspMatrix(b,a);
break;
case "ComplexVector":
return addScalarComplexVector(b,a);
break;
case "ComplexMatrix":
return addScalarComplexMatrix(b,a);
break;
default:
return undefined;
break;
}
}
else if ( ta == "vector" ) {
switch(tb) {
case "vector":
// vector addition
if ( a.length != b.length ) {
error("Error in add(a,b): a.length = " + a.length + " != " + b.length + " = b.length.");
return undefined;
}
return addVectors(a,b);
break;
case "spvector":
if ( a.length != b.length ) {
error("Error in add(a,b): a.length = " + a.length + " != " + b.length + " = b.length.");
return undefined;
}
return addVectorspVector(a,b);
break;
case "ComplexVector":
if ( a.length != b.length ) {
error("Error in add(a,b): a.length = " + a.length + " != " + b.length + " = b.length.");
return undefined;
}
return addComplexVectorVector(b,a);
break;
case "matrix":
case "spmatrix":
default:
error("Error in add(a,B): a is a vector and B is a " + tb + ".");
return undefined;
break;
}
}
else if ( ta == "matrix" ) {
switch(tb) {
case "matrix":
// Matrix addition
if ( a.m != b.m || a.n != b.n ) {
error("Error in add(A,B): size(A) = [" + a.m + "," + a.n + "] != [" + b.m + "," + b.n + "] = size(B).");
return undefined;
}
return addMatrices(a,b);
break;
case "spmatrix":
// Matrix addition
if ( a.m != b.m || a.n != b.n ) {
error("Error in add(A,B): size(A) = [" + a.m + "," + a.n + "] != [" + b.m + "," + b.n + "] = size(B).");
return undefined;
}
return addMatrixspMatrix(a,b);
break;
case "ComplexMatrix":
// Matrix addition
if ( a.m != b.m || a.n != b.n ) {
error("Error in add(A,B): size(A) = [" + a.m + "," + a.n + "] != [" + b.m + "," + b.n + "] = size(B).");
return undefined;
}
return addComplexMatrixMatrix(b,a);
break;
case "vector":
case "spvector":
default:
error("Error in add(A,b): a is a matrix and B is a " + tb + ".");
return undefined;
break;
}
}
else if ( ta == "spvector" ) {
switch(tb) {
case "vector":
// vector addition
if ( a.length != b.length ) {
error("Error in add(a,b): a.length = " + a.length + " != " + b.length + " = b.length.");
return undefined;
}
return addVectorspVector(b,a);
break;
case "spvector":
if ( a.length != b.length ) {
error("Error in add(a,b): a.length = " + a.length + " != " + b.length + " = b.length.");
return undefined;
}
return addspVectors(a,b);
break;
case "matrix":
case "spmatrix":
default:
error("Error in add(a,B): a is a sparse vector and B is a " + tb + ".");
return undefined;
break;
}
}
else if ( ta == "spmatrix" ) {
switch(tb) {
case "matrix":
// Matrix addition
if ( a.m != b.m || a.n != b.n ) {
error("Error in add(A,B): size(A) = [" + a.m + "," + a.n + "] != [" + b.m + "," + b.n + "] = size(B).");
return undefined;
}
return addMatrixspMatrix(b,a);
break;
case "spmatrix":
// Matrix addition
if ( a.m != b.m || a.n != b.n ) {
error("Error in add(A,B): size(A) = [" + a.m + "," + a.n + "] != [" + b.m + "," + b.n + "] = size(B).");
return undefined;
}
return addspMatrices(a,b);
break;
case "vector":
case "spvector":
default:
error("Error in add(A,b): a is a sparse matrix and B is a " + tb + ".");
return undefined;
break;
}
}
else if ( ta == "ComplexVector" ) {
switch(tb) {
case "vector":
// vector addition
if ( a.length != b.length ) {
error("Error in add(a,b): a.length = " + a.length + " != " + b.length + " = b.length.");
return undefined;
}
return addComplexVectorVector(a,b);
break;
case "spvector":
if ( a.length != b.length ) {
error("Error in add(a,b): a.length = " + a.length + " != " + b.length + " = b.length.");
return undefined;
}
return addComplexVectorspVector(a,b);
break;
case "ComplexVector":
if ( a.length != b.length ) {
error("Error in add(a,b): a.length = " + a.length + " != " + b.length + " = b.length.");
return undefined;
}
return addComplexVectors(b,a);
break;
case "matrix":
case "spmatrix":
default:
error("Error in add(a,B): a is a vector and B is a " + tb + ".");
return undefined;
break;
}
}
else if ( ta == "ComplexMatrix" ) {
switch(tb) {
case "matrix":
// Matrix addition
if ( a.m != b.m || a.n != b.n ) {
error("Error in add(A,B): size(A) = [" + a.m + "," + a.n + "] != [" + b.m + "," + b.n + "] = size(B).");
return undefined;
}
return addComplexMatrixMatrix(a,b);
break;
case "spmatrix":
// Matrix addition
if ( a.m != b.m || a.n != b.n ) {
error("Error in add(A,B): size(A) = [" + a.m + "," + a.n + "] != [" + b.m + "," + b.n + "] = size(B).");
return undefined;
}
return addComplexMatrixspMatrix(a,b);
break;
case "ComplexMatrix":
// Matrix addition
if ( a.m != b.m || a.n != b.n ) {
error("Error in add(A,B): size(A) = [" + a.m + "," + a.n + "] != [" + b.m + "," + b.n + "] = size(B).");
return undefined;
}
return addComplexMatrices(a,b);
break;
case "vector":
case "spvector":
default:
error("Error in add(A,b): a is a matrix and B is a " + tb + ".");
return undefined;
break;
}
}
else
return undefined;
}
/**
* @param {number}
* @param {Float64Array}
* @return {Float64Array}
*/
function subScalarVector ( scalar, vec ) {
const n = vec.length;
var res = new Float64Array(n);
for (var i = 0 ; i< n; i++)
res[i] = scalar - vec[i];
return res;
}
/**
* @param {Float64Array}
* @param {number}
* @return {Float64Array}
*/
function subVectorScalar ( vec, scalar ) {
const n = vec.length;
var res = new Float64Array(vec);
for (var i = 0 ; i< n; i++)
res[i] -= scalar;
return res;
}
/**
* @param {number}
* @param {Matrix}
* @return {Matrix}
*/
function subScalarMatrix(a, B ) {
return new Matrix(B.m, B.n, subScalarVector(a, B.val), true );
}
/**
* @param {Matrix}
* @param {number}
* @return {Matrix}
*/
function subMatrixScalar(B, a ) {
return new Matrix(B.m, B.n, subVectorScalar(B.val, a) , true);
}
/**
* @param {Float64Array}
* @param {Float64Array}
* @return {Float64Array}
*/
function subVectors(a,b) {
const n = a.length;
var c = new Float64Array(a);
for (var i=0; i < n; i++)
c[i] -= b[i];
return c;
}
/**
* @param {Matrix}
* @param {Matrix}
* @return {Matrix}
*/
function subMatrices(A,B) {
return new Matrix(A.m, A.n, subVectors(A.val, B.val), true );
}
function sub(a,b) {
const ta = type(a);
const tb = type(b);
if ( ta == "number" && tb == "number" )
return a - b;
else if ( ta == "number") {
switch(tb) {
case "Complex":
return addComplexReal(minusComplex(b),a);
break;
case "vector":
return subScalarVector(a,b);
break;
case "matrix":
return subScalarMatrix(a,b);
break;
case "spvector":
return subScalarspVector(a,b);
break;
case "spmatrix":
return subScalarspMatrix(a,b);
break;
default:
return undefined;
break;
}
}
else if ( tb == "number" ) {
switch(ta) {
case "Complex":
return addComplexReal(b,-a);
break;
case "vector":
return subVectorScalar (a, b);
break;
case "matrix":
return subMatrixScalar(a,b);
break;
case "spvector":
return addScalarspVector(-b,a);
break;
case "spmatrix":
return addScalarspMatrix(-b,a);
break;
default:
return undefined;
break;
}
}
else if ( ta == "vector" ) {
switch(tb) {
case "vector":
// vector substraction
if ( a.length != b.length ) {
error("Error in sub(a,b): a.length = " + a.length + " != " + b.length + " = b.length.");
return undefined;
}
return subVectors(a,b);
break;
case "spvector":
// vector substraction
if ( a.length != b.length ) {
error("Error in sub(a,b): a.length = " + a.length + " != " + b.length + " = b.length.");
return undefined;
}
return subVectorspVector(a,b);
break;
case "matrix":
case "spmatrix":
default:
error("Error in sub(a,B): a is a vector and B is a " + tb + ".");
return undefined;
break;
}
}
else if ( ta == "matrix" ) {
switch(tb) {
case "matrix":
// Matrix sub
if ( a.m != b.m || a.n != b.n ) {
error("Error in sub(A,B): size(A) = [" + a.m + "," + a.n + "] != [" + b.m + "," + b.n + "] = size(B).");
return undefined;
}
return subMatrices(a,b);
break;
case "spmatrix":
// Matrix addition
if ( a.m != b.m || a.n != b.n ) {
error("Error in sub(A,B): size(A) = [" + a.m + "," + a.n + "] != [" + b.m + "," + b.n + "] = size(B).");
return undefined;
}
return subMatrixspMatrix(a,b);
break;
case "vector":
case "spvector":
default:
error("Error in sub(A,b): A is a matrix and b is a " + tb + ".");
return undefined;
break;
}
}
else if ( ta == "spvector" ) {
switch(tb) {
case "vector":
if ( a.length != b.length ) {
error("Error in sub(a,b): a.length = " + a.length + " != " + b.length + " = b.length.");
return undefined;
}
return subspVectorVector(a,b);
break;
case "spvector":
if ( a.length != b.length ) {
error("Error in sub(a,b): a.length = " + a.length + " != " + b.length + " = b.length.");
return undefined;
}
return subspVectors(a,b);
break;
case "matrix":
case "spmatrix":
default:
error("Error in sub(a,B): a is a sparse vector and B is a " + tb + ".");
return undefined;
break;
}
}
else if ( ta == "spmatrix" ) {
switch(tb) {
case "matrix":
if ( a.m != b.m || a.n != b.n ) {
error("Error in sub(A,B): size(A) = [" + a.m + "," + a.n + "] != [" + b.m + "," + b.n + "] = size(B).");
return undefined;
}
return subspMatrixMatrix(a,b);
break;
case "spmatrix":
if ( a.m != b.m || a.n != b.n ) {
error("Error in sub(A,B): size(A) = [" + a.m + "," + a.n + "] != [" + b.m + "," + b.n + "] = size(B).");
return undefined;
}
return subspMatrices(a,b);
break;
case "vector":
case "spvector":
default:
error("Error in sub(A,b): a is a sparse matrix and B is a " + tb + ".");
return undefined;
break;
}
}
else
return undefined;
}
function pow(a,b) {
var i;
const ta = type(a);
const tb = type(b);
if ( ta == "number" && tb == "number" )
return Math.pow(a, b);
else if ( ta == "number") {
if ( tb == "vector" ) {
var c = zeros(b.length);
if ( !isZero(a) ) {
for (i=0;i<b.length;i++) {
c[i] = Math.pow(a, b[i]);
}
}
return c;
}
else {
var c = new Matrix( b.m, b.n, pow(a, b.val), true);
return c;
}
}
else if ( tb == "number" ) {
if ( ta == "vector" ) {
var c = zeros(a.length);
for (i=0; i < a.length; i++)
c[i] = Math.pow(a[i], b);
return c;
}
else {
var c = new Matrix( a.m, a.n, pow(a.val, b), true);
return c;
}
}
else if ( ta == "vector" ) {
if ( tb == "vector" ) {
// entry-wise power
if ( a.length != b.length ) {
error("Error in pow(a,b): a.length = " + a.length + " != " + b.length + " = b.length.");
return undefined;
}
var c = zeros(a.length);
for ( i=0; i<a.length; i++ ) {
c[i] = Math.pow(a[i], b[i]);
}
return c;
}
else {
// vector + matrix
return "undefined";
}
}
else {
if ( tb == "vector" ) {
// matrix + vector
return "undefined";
}
else {
// entry-wise power
var c = new Matrix( a.m, a.n, pow(a.val, b.val), true);
return c;
}
}
}
function minus ( x ) {
switch(type(x)) {
case "number":
return -x;
break;
case "vector":
return minusVector(x);
break;
case "spvector":
return new spVector(x.length, minusVector(x.val), x.ind );
break;
case "ComplexVector":
return minusComplexVector(x);
break;
case "matrix":
return new Matrix(x.m, x.n, minusVector(x.val), true );
break;
case "spmatrix":
return new spMatrix(x.m, x.n, minusVector(x.val), x.cols, x.rows );
break;
case "ComplexMatrix":
return minusComplexMatrix(x);
break;
default:
return undefined;
}
}
/**
* @param {Float64Array}
* @return {Float64Array}
*/
function minusVector( x ) {
var res = new Float64Array(x.length);
for (var i =0; i < x.length; i++)
res[i] = -x[i];
return res;
}
/**
* @param {Matrix}
* @return {Matrix}
*/
function minusMatrix( x ) {
return new Matrix(x.m, x.n, minusVector(x.val), true );
}
// minimum
/**
* @param {Float64Array}
* @return {number}
*/
function minVector( a ) {
const n = a.length;
var res = a[0];
for (var i = 1; i < n ; i++) {
if ( a[i] < res)
res = a[i];
}
return res;
}
/**
* @param {Matrix}
* @return {number}
*/
function minMatrix( A ) {
return minVector(A.val);
}
/**
* @param {Float64Array}
* @param {number}
* @return {Float64Array}
*/
function minVectorScalar(vec, scalar ) {
var n = vec.length;
var res = new Float64Array(vec);
for (var i = 0; i < n ; i++) {
if ( scalar < vec[i])
res[i] = scalar;
}
return res;
}
/**
* @param {Matrix}
* @param {number}
* @return {Matrix}
*/
function minMatrixScalar(A, scalar ) {
return new Matrix(A.m, A.n, minVectorScalar(A.val, scalar), true);
}
/**
* @param {Matrix}
* @return {Matrix}
*/
function minMatrixRows( A ) {
const m = A.m;
const n = A.n;
var res = new Float64Array(A.val.subarray(0,n) );
var j;
var r = n;
for ( var i=1; i < m; i++) {
for ( j = 0; j < n; j++)
if( A.val[r + j] < res[j])
res[j] = A.val[r + j];
r += n;
}
return new Matrix(1,n,res, true);
}
/**
* @param {Matrix}
* @return {Float64Array}
*/
function minMatrixCols( A ) {
var m = A.m;
var res = new Float64Array(m);
var r = 0;
for ( var i=0; i < m; i++) {
res[i] = minVector(A.val.subarray(r, r+A.n) );
r += A.n;
}
return res;
}
/**
* @param {Float64Array}
* @param {Float64Array}
* @return {Float64Array}
*/
function minVectorVector(a, b) {
const n = a.length;
var res = new Float64Array(a);
for (var i = 0; i < n ; i++) {
if ( b[i] < a[i])
res[i] = b[i];
}
return res;
}
/**
* @param {Matrix}
* @param {Matrix}
* @return {Matrix}
*/
function minMatrixMatrix( A, B ) {
return new Matrix(A.m, A.n, minVectorVector(A.val, B.val), true);
}
function min(a,b) {
var ta = type(a);
if ( arguments.length == 1 ) {
switch( ta ) {
case "vector":
return minVector(a);
break;
case "spvector":
var m = minVector(a.val);
if ( m > 0 && a.val.length < a.length )
return 0;
else
return m;
break;
case "matrix":
return minMatrix(a);
break;
case "spmatrix":
var m = minVector(a.val);
if ( m > 0 && a.val.length < a.m * a.n )
return 0;
else
return m;
break;
default:
return a;
break;
}
}
var tb = type(b);
if (ta == "spvector" ) {
a = fullVector(a);
ta = "vector";
}
if (ta == "spmatrix" ) {
a = fullMatrix(a);
ta = "matrix";
}
if (tb == "spvector" ) {
b = fullVector(b);
tb = "vector";
}
if (tb == "spmatrix" ) {
b = fullMatrix(b);
tb = "matrix";
}
if ( ta == "number" && tb == "number" )
return Math.min(a,b);
else if ( ta == "number") {
if ( tb == "vector" )
return minVectorScalar(b, a ) ;
else
return minMatrixScalar(b, a ) ;
}
else if ( tb == "number" ) {
if ( ta == "vector" )
return minVectorScalar(a, b);
else {
// MAtrix , scalar
if ( b == 1)
return minMatrixRows(a); // return row vector of min of columns
else if ( b == 2 )
return minMatrixCols(a); // return column vector of min of rows
else
return minMatrixScalar(a, b);
}
}
else if ( ta == "vector" ) {
if ( tb == "vector" )
return minVectorVector(a,b);
else
return "undefined";
}
else {
if ( tb == "matrix" )
return minMatrixMatrix(a,b);
else
return "undefined";
}
}
// maximum
/**
* @param {Float64Array}
* @return {number}
*/
function maxVector( a ) {
const n = a.length;
var res = a[0];
for (var i = 1; i < n ; i++) {
if ( a[i] > res)
res = a[i];
}
return res;
}
/**
* @param {Matrix}
* @return {number}
*/
function maxMatrix( A ) {
return maxVector(A.val);
}
/**
* @param {Float64Array}
* @param {number}
* @return {Float64Array}
*/
function maxVectorScalar(vec, scalar ) {
const n = vec.length;
var res = new Float64Array(vec);
for (var i = 0; i < n ; i++) {
if ( scalar > vec[i])
res[i] = scalar;
}
return res;
}
/**
* @param {Matrix}
* @param {number}
* @return {Matrix}
*/
function maxMatrixScalar(A, scalar ) {
return maxVectorScalar(A.val, scalar);
}
/**
* @param {Matrix}
* @return {Matrix}
*/
function maxMatrixRows( A ) {
const m = A.m;
const n = A.n;
var res = new Float64Array(A.val.subarray(0,n) );
var j;
var r = n;
for ( var i=1; i < m; i++) {
for ( j = 0; j < n; j++)
if( A.val[r + j] > res[j])
res[j] = A.val[r + j];
r += n;
}
return new Matrix(1,n,res,true);
}
/**
* @param {Matrix}
* @return {Float64Array}
*/
function maxMatrixCols( A ) {
const m = A.m;
var res = new Float64Array(m);
var r = 0;
for ( var i=0; i < m; i++) {
res[i] = maxVector(A.val.subarray(r, r+A.n) );
r += A.n;
}
return res;
}
/**
* @param {Float64Array}
* @param {Float64Array}
* @return {Float64Array}
*/
function maxVectorVector(a, b) {
var n = a.length;
var res = new Float64Array(a);
for (var i = 0; i < n ; i++) {
if ( b[i] > a[i])
res[i] = b[i];
}
return res;
}
/**
* @param {Matrix}
* @param {Matrix}
* @return {Matrix}
*/
function maxMatrixMatrix( A, B ) {
return new Matrix(A.m, A.n, maxVectorVector(A.val, B.val), true);
}
function max(a,b) {
var ta = type(a);
if ( arguments.length == 1 ) {
switch( ta ) {
case "vector":
return maxVector(a);
break;
case "spvector":
var m = maxVector(a.val);
if ( m < 0 && a.val.length < a.length )
return 0;
else
return m;
break;
case "matrix":
return maxMatrix(a);
break;
case "spmatrix":
var m = maxVector(a.val);
if ( m < 0 && a.val.length < a.m * a.n )
return 0;
else
return m;
break;
default:
return a;
break;
}
}
var tb = type(b);
if (ta == "spvector" ) {
a = fullVector(a);
ta = "vector";
}
if (ta == "spmatrix" ) {
a = fullMatrix(a);
ta = "matrix";
}
if (tb == "spvector" ) {
b = fullVector(b);
tb = "vector";
}
if (tb == "spmatrix" ) {
b = fullMatrix(b);
tb = "matrix";
}
if ( ta == "number" && tb == "number" )
return Math.max(a,b);
else if ( ta == "number") {
if ( tb == "vector" )
return maxVectorScalar(b, a ) ;
else
return maxMatrixScalar(b, a ) ;
}
else if ( tb == "number" ) {
if ( ta == "vector" )
return maxVectorScalar(a, b);
else {
// MAtrix , scalar
if ( b == 1)
return maxMatrixRows(a); // return row vector of max of columns
else if ( b == 2 )
return maxMatrixCols(a); // return column vector of max of rows
else
return maxMatrixScalar(a, b);
}
}
else if ( ta == "vector" ) {
if ( tb == "vector" )
return maxVectorVector(a,b);
else
return "undefined";
}
else {
if ( tb == "matrix" )
return maxMatrixMatrix(a,b);
else
return "undefined";
}
}
/**
* @param {Matrix}
*/
function transposeMatrix ( A ) {
var i;
var j;
const m = A.m;
const n = A.n;
if ( m > 1 ) {
var res = zeros( n,m);
var Aj = 0;
for ( j=0; j< m;j++) {
var ri = 0;
for ( i=0; i < n ; i++) {
res.val[ri + j] = A.val[Aj + i];
ri += m;
}
Aj += n;
}
return res;
}
else {
return A.val;
}
}
/**
* @param {Float64Array}
* @return {Matrix}
*/
function transposeVector ( a ) {
return new Matrix(1,a.length, a);
}
function transpose( A ) {
var i;
var j;
switch( type( A ) ) {
case "number":
return A;
break;
case "vector":
var res = new Matrix(1,A.length, A);
return res; // matrix with a single row
break;
case "spvector":
return transposespVector(A);
break;
case "ComplexVector":
var res = new ComplexMatrix(1,A.length, conj(A));
return res; // matrix with a single row
break;
case "matrix":
return transposeMatrix(A);
break;
case "spmatrix":
return transposespMatrix(A);
break;
case "ComplexMatrix":
return transposeComplexMatrix(A);
break;
default:
return undefined;
break;
}
}
/**
* @param {Matrix}
* @return {number}
*/
function det( A ) {
const n = A.n;
if ( A.m != n || typeof(A.m) =="undefined")
return undefined;
if ( n == 2 ) {
return A.val[0]*A.val[3] - A.val[1]*A.val[2];
}
else {
var detA = 0;
var i,j;
for ( i=0; i < n; i++ ) {
var proddiag = 1;
for ( j=0; j < n ; j++)
proddiag *= A.val[( (i+j)%n ) * n + j];
detA += proddiag;
}
for ( i=0; i < n; i++ ) {
var proddiag = 1;
for ( j=0; j < n ; j++)
proddiag *= A.val[( (i+n-1-j)%n ) * n + j];
detA -= proddiag;
}
}
return detA;
}
function trace ( A ) {
if ( type(A) == "matrix") {
var n = A.length;
if ( A.m != n )
return "undefined";
var res = 0;
for ( var i =0; i< n;i++)
res += A.val[i*n + i];
return res;
}
else {
return undefined;
}
}
/**
* @param {Matrix}
* @return {Matrix}
*/
function triu ( A ) {
// return the upper triangular part of A
var i;
var j;
const n = A.n;
const m = A.m;
var res = zeros(m, n);
var im = m;
if ( n < m )
im = n;
var r = 0;
for (i=0; i < im; i++) {
for ( j=i; j < n; j++)
res.val[r + j] = A.val[r + j];
r += n;
}
return res;
}
/**
* @param {Matrix}
* @return {Matrix}
*/
function tril ( A ) {
// return the lower triangular part of A
var i;
var j;
const n = A.n;
const m = A.m;
var res = zeros(m, n);
var im = m;
if ( n < m )
im = n;
var r = 0;
for (i=0; i < im; i++) {
for ( j=0; j <= i; j++)
res.val[r + j] = A.val[r + j];
r += n;
}
if ( m > im ) {
for (i=im; i < m; i++) {
for ( j=0; j < n; j++)
res.val[r + j] = A.val[r + j];
r += n;
}
}
return res;
}
/**
* @param {Matrix}
* @return {boolean}
*/
function issymmetric ( A ) {
const m = A.m;
const n= A.n;
if ( m != n )
return false;
for (var i=0;i < m; i++)
for ( var j=0; j < n; j++)
if ( A.val[i*n+j] != A.val[j*n+i] )
return false;
return true;
}
/** Concatenate matrices/vectors
* @param {Array}
* @param {boolean}
* @return {Matrix}
*/
function mat( elems, rowwise ) {
var k;
var concatWithNumbers = false;
var elemtypes = new Array(elems.length);
for ( k=0; k < elems.length; k++) {
elemtypes[k] = type(elems[k]);
if ( elemtypes[k] == "number" )
concatWithNumbers = true;
}
if (typeof(rowwise ) == "undefined") {
// check if vector of numbers
if ( type(elems) == "vector" )
return new Float64Array(elems);
// check if 2D Array => toMatrix rowwise
var rowwise = true;
for (k=0; k < elems.length; k++) {
if ( !Array.isArray(elems[k] ) || elemtypes[k] == "vector" ) {
rowwise = false;
if ( elemtypes[k] == "string" )
return elems; // received vector of strings => return it directly
}
}
}
if ( elems.length == 0 ) {
return [];
}
var m = 0;
var n = 0;
var i;
var j;
if ( rowwise ) {
var res = new Array( ) ;
for ( k= 0; k<elems.length; k++) {
switch( elemtypes[k] ) {
case "matrix":
res. push( elems[k].val ) ;
m += elems[k].m;
n = elems[k].n;
break;
case "vector":
if ( concatWithNumbers ) {
// return a column by concatenating vectors and numbers
for ( var l=0; l < elems[k].length; l++)
res.push(elems[k][l]) ;
n = 1;
m += elems[k].length;
}
else {
// vector (auto transposed) as row in a matrix
res.push (elems[k]) ;
m += 1;
n = elems[k].length;
}
break;
case "number":
res.push(elems[k]) ;
m += 1;
n = 1;
break;
case "spvector":
return spmat(elems);
default:
// Array containing not only numbers...
// probably calling mat( Array2D ) => return Array2D
return elems;
break;
}
}
if ( n == 1) {
var M = new Float64Array(res);
return M;
}
var M = new Matrix( m , n ) ;
var p = 0;
for (k=0; k < res.length ; k++) {
if(res[k].buffer) {
M.val.set( res[k], p);
p += res[k].length;
}
else {
for ( j=0; j < res[k].length; j++)
M.val[p+j] = res[k][j];
p += res[k].length;
}
}
return M;
}
else {
// compute size
m = size(elems[0], 1);
for ( k= 0; k<elems.length; k++) {
if ( elemtypes[k] == "matrix")
n += elems[k].n;
else
n++;
if ( size( elems[k], 1) != m)
return "undefined";
}
// Build matrix
var res = new Matrix(m, n);
var c;
for (i=0;i<m;i++) {
c = 0; // col index
for ( k=0;k<elems.length; k++) {
switch( elemtypes[k] ) {
case "matrix":
for ( j=0; j < elems[k].n; j++) {
res.val[i*n + j+c] = elems[k].val[i*elems[k].n + j] ;
}
c += elems[k].n;
break;
case "vector": //vector
res.val[i*n +c]= elems[k][i] ;
c++;
break;
case "number":
res.val[i*n+c] = elems[k];
c++;
break;
default:
break;
}
}
}
return res;
}
}
/// Relational Operators
function isEqual( a, b) {
var i;
var j;
var res;
var ta = type(a);
var tb = type(b);
if ( ta == "number" && tb != "number" )
return isEqual(b,a);
if( ta != "number" && tb == "number" ) {
// vector/matrix + scalar
switch( ta ) {
case "vector":
res = new Float64Array(a.length);
for ( i=0; i<a.length; i++) {
if ( isZero( a[i] - b ) )
res[i] = 1;
}
return res;
break;
case "matrix":
res = new Matrix(a.m, a.n, isEqual(a.val, b), true );
return res;
break;
default:
return (a==b?1:0);
}
}
else if ( ta == tb ) {
switch( ta ) {
case "number":
return ( isZero(a - b)?1:0 );
break;
case "vector":
res = new Float64Array(a.length);
for ( i=0; i<a.length; i++) {
if ( isZero( a[i] - b[i] ) )
res[i] = 1;
}
return res;
break;
case "matrix":
res = new Matrix(a.m, a.n, isEqual(a.val, b.val) , true);
return res;
break;
default:
return (a==b?1:0);
}
}
else
return "undefined";
}
function isNotEqual( a, b) {
var i;
var j;
var res;
var ta = type(a);
var tb = type(b);
if ( ta == "number" && tb != "number" )
return isNotEqual(b,a);
if( ta != "number" && tb == "number" ) {
// vector/matrix + scalar
switch( ta ) {
case "vector":
res = new Float64Array(a.length);
for ( i=0; i<a.length; i++) {
if ( !isZero( a[i] - b ) )
res[i] = 1;
}
return res;
break;
case "matrix":
res = new Matrix(a.m, a.n, isNotEqual(a.val, b), true );
return res;
break;
default:
return (a!=b?1:0);
}
}
else if ( ta == tb ) {
switch( ta ) {
case "number":
return ( !isZero(a - b)?1:0 );
break;
case "vector":
res = new Float64Array(a.length);
for ( i=0; i<a.length; i++) {
if ( !isZero( get(a, i) - get(b,i) ) )
res[i] = 1;
}
return res;
break;
case "matrix":
res = new Matrix(a.m, a.n, isNotEqual(a.val, b.val), true );
return res;
break;
default:
return (a!=b?1:0);
}
}
else
return "undefined";
}
function isGreater( a, b) {
var i;
var j;
var res;
var ta = type(a);
var tb = type(b);
if ( ta == "number" && tb != "number" )
return isGreater(b,a);
if( ta != "number" && tb == "number" ) {
// vector/matrix + scalar
switch( ta ) {
case "vector":
res = new Float64Array(a.length);
for ( i=0; i<a.length; i++) {
if ( a[i] - b > EPS )
res[i] = 1;
}
return res;
break;
case "matrix":
res = new Matrix(a.m, a.n, isGreater(a.val, b), true );
return res;
break;
default:
return (a>b?1:0);
}
}
else if (ta == tb) {
switch( ta ) {
case "number":
return (a>b?1:0);
break;
case "vector":
res = new Float64Array(a.length);
for ( i=0; i<a.length; i++) {
if ( a[i] - b[i] > EPS )
res[i] = 1;
}
return res;
break;
case "matrix":
res = new Matrix(a.m, a.n, isGreater(a.val, b.val), true );
return res;
break;
default:
return (a>b?1:0);
}
}
else
return "undefined";
}
function isGreaterOrEqual( a, b) {
var i;
var j;
var res;
var ta = type(a);
var tb = type(b);
if ( ta == "number" && tb != "number" )
return isGreaterOrEqual(b,a);
if( ta != "number" && tb == "number" ) {
// vector/matrix + scalar
switch( ta ) {
case "vector":
res = new Float64Array(a.length);
for ( i=0; i<a.length; i++) {
if ( a[i] - b > -EPS )
res[i] = 1;
}
return res;
break;
case "matrix":
res = new Matrix(a.m, a.n, isGreaterOrEqual(a.val, b), true );
return res;
break;
default:
return (a>=b?1:0);
}
}
else if ( ta == tb ) {
switch( ta ) {
case "number":
return (a>=b);
break;
case "vector":
res = new Float64Array(a.length);
for ( i=0; i<a.length; i++) {
if ( a[i] - b[i] > -EPS )
res[i] = 1;
}
return res;
break;
case "matrix":
res = new Matrix(a.m, a.n, isGreaterOrEqual(a.val, b.val), true );
return res;
break;
default:
return (a>=b?1:0);
}
}
else
return "undefined";
}
function isLower( a, b) {
var i;
var j;
var res;
var ta = type(a);
var tb = type(b);
if ( ta == "number" && tb != "number" )
return isLower(b,a);
if( ta != "number" && tb == "number" ) {
// vector/matrix + scalar
switch( ta ) {
case "vector":
res = new Float64Array(a.length);
for ( i=0; i<a.length; i++) {
if ( b - a[i] > EPS )
res[i] = 1;
}
return res;
break;
case "matrix":
res = new Matrix(a.m, a.n, isLower(a.val, b), true );
return res;
break;
default:
return (a<b?1:0);
}
}
else if ( ta == tb ) {
switch( ta ) {
case "number":
return (a<b?1:0);
break;
case "vector":
res = new Float64Array(a.length);
for ( i=0; i<a.length; i++) {
if ( b[i] - a[i] > EPS )
res[i] = 1;
}
return res;
break;
case "matrix":
res = new Matrix(a.m, a.n, isLower(a.val, b.val), true );
return res;
break;
default:
return (a<b?1:0);
}
}
else
return "undefined";
}
function isLowerOrEqual( a, b) {
var i;
var j;
var res;
var ta = type(a);
var tb = type(b);
if ( ta == "number" && tb != "number" )
return isLowerOrEqual(b,a);
if( ta != "number" && tb == "number" ) {
// vector/matrix + scalar
switch( ta ) {
case "vector":
res = new Float64Array(a.length);
for ( i=0; i<a.length; i++) {
if ( b - a[i] > -EPS )
res[i] = 1;
}
return res;
break;
case "matrix":
res = new Matrix(a.m, a.n, isLowerOrEqual(a.val, b), true );
return res;
break;
default:
return (a<=b?1:0);
}
}
else if ( ta == tb ) {
switch( ta ) {
case "number":
return (a<=b?1:0);
break;
case "vector":
res = new Float64Array(a.length);
for ( i=0; i<a.length; i++) {
if ( b[i] - a[i] > -EPS )
res[i] = 1;
}
return res;
break;
case "matrix":
res = new Matrix(a.m, a.n, isLowerOrEqual(a.val, b.val) , true);
return res;
break;
default:
return (a<=b?1:0);
}
}
else
return "undefined";
}
function find( b ) {
// b is a boolean vector of 0 and 1.
// return the indexes of the 1's.
var i;
var n = b.length;
var res = new Array();
for ( i=0; i < n; i++) {
if ( b[i] != 0 )
res.push(i);
}
return res;
}
argmax = findmax;
function findmax( x ) {
// return the index of the maximum in x
var i;
switch ( type(x)) {
case "number":
return 0;
break;
case "vector":
var idx = 0;
var maxi = x[0];
for ( i= 1; i< x.length; i++) {
if ( x[i] > maxi ) {
maxi = x[i];
idx = i;
}
}
return idx;
break;
case "spvector":
var maxi = x.val[0];
var idx = x.ind[0];
for ( i= 1; i< x.val.length; i++) {
if ( x.val[i] > maxi ) {
maxi = x.val[i];
idx = x.ind[i];
}
}
if ( maxi < 0 && x.val.length < x.length ) {
idx = 0;
while ( x.ind.indexOf(idx) >= 0 && idx < x.length)
idx++;
}
return idx;
break;
default:
return "undefined";
}
}
argmin = findmin;
function findmin( x ) {
// return the index of the minimum in x
var i;
switch ( type(x)) {
case "number":
return 0;
break;
case "vector":
var idx = 0;
var mini = x[0];
for ( i= 1; i< x.length; i++) {
if ( x[i] < mini ) {
mini = x[i];
idx = i;
}
}
return idx;
break;
case "spvector":
var mini = x.val[0];
var idx = x.ind[0];
for ( i= 1; i< x.val.length; i++) {
if ( x.val[i] < mini ) {
mini = x.val[i];
idx = x.ind[i];
}
}
if ( mini > 0 && x.val.length < x.length ) {
idx = 0;
while ( x.ind.indexOf(idx) >= 0 && idx < x.length)
idx++;
}
return idx;
break;
default:
return "undefined";
}
}
/**
* @param {Float64Array}
* @param {boolean}
* @param {boolean}
* @return {Float64Array|Array}
*/
function sort( x, decreasingOrder , returnIndexes) {
// if returnIndexes = true : replace x with its sorted version
// otherwise return a sorted copy without altering x
if ( typeof(decreasingOrder) == "undefined")
var decreasingOrder = false;
if ( typeof(returnIndexes) == "undefined")
var returnIndexes = false;
var i;
var j;
var tmp;
const n = x.length;
if ( returnIndexes ) {
var indexes = range(n);
for ( i=0; i < n - 1; i++) {
if ( decreasingOrder )
j = findmax( get ( x, range(i,n) ) ) + i ;
else
j = findmin( get ( x, range(i,n) ) ) + i;
if ( i!=j) {
tmp = x[i];
x[i] = x[j];
x[j] = tmp;
tmp = indexes[i];
indexes[i] = indexes[j];
indexes[j] = tmp;
}
}
return indexes;
}
else {
var xs = vectorCopy(x);
for ( i=0; i < n - 1; i++) {
if ( decreasingOrder )
j = findmax( get ( xs, range(i,n) ) ) + i;
else
j = findmin( get ( xs, range(i,n) ) ) + i;
if ( i!=j) {
tmp = xs[i];
xs[i] = xs[j];
xs[j] = tmp;
}
}
return xs;
}
}
/// Stats
/**
* @param {Float64Array}
* @return {number}
*/
function sumVector ( a ) {
var i;
const n = a.length;
var res = a[0];
for ( i=1; i< n; i++)
res += a[i];
return res;
}
/**
* @param {Matrix}
* @return {number}
*/
function sumMatrix ( A ) {
return sumVector(A.val);
}
/**
* @param {Matrix}
* @return {Matrix}
*/
function sumMatrixRows( A ) {
var i;
var j;
const m = A.m;
const n = A.n;
var res = new Float64Array(n);
var r = 0;
for ( i=0; i< m; i++) {
for (j=0; j < n; j++)
res[j] += A.val[r + j];
r += n;
}
return new Matrix(1,n,res, true); // return row vector
}
/**
* @param {Matrix}
* @return {Float64Array}
*/
function sumMatrixCols( A ) {
const m = A.m;
var res = new Float64Array(m);
var r = 0;
for ( var i=0; i < m; i++) {
for (var j=0; j < A.n; j++)
res[i] += A.val[r + j];
r += A.n;
}
return res;
}
function sum( A , sumalongdimension ) {
switch ( type( A ) ) {
case "vector":
if ( arguments.length == 1 || sumalongdimension == 1 ) {
return sumVector(A);
}
else {
return vectorCopy(A);
}
break;
case "spvector":
if ( arguments.length == 1 || sumalongdimension == 1 )
return sumVector(A.val);
else
return A.copy();
break;
case "matrix":
if( arguments.length == 1 ) {
return sumMatrix( A ) ;
}
else if ( sumalongdimension == 1 ) {
return sumMatrixRows( A );
}
else if ( sumalongdimension == 2 ) {
return sumMatrixCols( A );
}
else
return undefined;
break;
case "spmatrix":
if( arguments.length == 1 ) {
return sumVector( A.val ) ;
}
else if ( sumalongdimension == 1 ) {
return sumspMatrixRows( A );
}
else if ( sumalongdimension == 2 ) {
return sumspMatrixCols( A );
}
else
return undefined;
break;
default:
return A;
break;
}
}
/**
* @param {Float64Array}
* @return {number}
*/
function prodVector ( a ) {
var i;
const n = a.length;
var res = a[0];
for ( i=1; i< n; i++)
res *= a[i];
return res;
}
/**
* @param {Matrix}
* @return {number}
*/
function prodMatrix ( A ) {
return prodVector(A.val);
}
/**
* @param {Matrix}
* @return {Matrix}
*/
function prodMatrixRows( A ) {
var i;
var j;
const m = A.m;
const n = A.n;
var res = new Float64Array(A.row(0));
var r = n;
for ( i=1; i< m; i++) {
for (j=0; j < n; j++)
res[j] *= A.val[r + j];
r += A.n;
}
return new Matrix(1,n,res, true); // return row vector
}
/**
* @param {Matrix}
* @return {Float64Array}
*/
function prodMatrixCols( A ) {
const m = A.m;
var res = new Float64Array(m);
var r = 0;
for ( var i=0; i < m; i++) {
res[i] = A.val[r];
for (var j=1; j < A.n; j++)
res[i] *= A.val[r + j];
r += A.n;
}
return res;
}
function prod( A , prodalongdimension ) {
switch ( type( A ) ) {
case "vector":
if ( arguments.length == 1 || prodalongdimension == 1 )
return prodVector(A);
else
return vectorCopy(A);
break;
case "spvector":
if ( arguments.length == 1 || prodalongdimension == 1 ) {
if ( A.val.length < A.length )
return 0;
else
return prodVector(A.val);
}
else
return A.copy();
break;
case "matrix":
if( arguments.length == 1 ) {
return prodMatrix( A ) ;
}
else if ( prodalongdimension == 1 ) {
return prodMatrixRows( A );
}
else if ( prodalongdimension == 2 ) {
return prodMatrixCols( A );
}
else
return undefined;
break;
case "spmatrix":
if( arguments.length == 1 ) {
if ( A.val.length < A.m * A.n )
return 0;
else
return prodVector( A.val ) ;
}
else if ( prodalongdimension == 1 ) {
return prodspMatrixRows( A );
}
else if ( prodalongdimension == 2 ) {
return prodspMatrixCols( A );
}
else
return undefined;
break;
default:
return A;
break;
}
}
function mean( A , sumalongdimension ) {
switch ( type( A ) ) {
case "vector":
if ( arguments.length == 1 || sumalongdimension == 1 ) {
return sumVector(A) / A.length;
}
else {
return vectorCopy(A);
}
break;
case "spvector":
if ( arguments.length == 1 || sumalongdimension == 1 )
return sumVector(A.val) / A.length;
else
return A.copy();
break;
case "matrix":
if( arguments.length == 1 ) {
return sumMatrix( A ) / ( A.m * A.n);
}
else if ( sumalongdimension == 1 ) {
return mulScalarMatrix( 1/A.m, sumMatrixRows( A ));
}
else if ( sumalongdimension == 2 ) {
return mulScalarVector( 1/A.n, sumMatrixCols( A )) ;
}
else
return undefined;
break;
case "spmatrix":
if( arguments.length == 1 ) {
return sumVector( A.val ) / ( A.m * A.n);
}
else if ( sumalongdimension == 1 ) {
return mulScalarMatrix(1/A.m, sumspMatrixRows(A));
}
else if ( sumalongdimension == 2 ) {
return mulScalarVector(1/A.n, sumspMatrixCols(A));
}
else
return undefined;
break;
default:
return A;
break;
}
}
function variance(A, alongdimension ) {
// variance = sum(A^2)/n - mean(A)^2
if ( arguments.length > 1 )
var meanA = mean(A, alongdimension);
else
var meanA = mean(A);
switch ( type( A ) ) {
case "number":
return 0;
break;
case "vector":
if ( arguments.length == 1 || alongdimension == 1 ) {
var res = ( dot(A,A) / A.length ) - meanA*meanA;
return res ;
}
else {
return zeros(A.length);
}
break;
case "spvector":
if ( arguments.length == 1 || alongdimension == 1 ) {
var res = ( dot(A.val,A.val) / A.length ) - meanA*meanA;
return res ;
}
else
return zeros(A.length);
break;
case "matrix":
case "spmatrix":
if( typeof(alongdimension) == "undefined" ) {
var res = (sum(entrywisemul(A,A)) / (A.m * A.n ) ) - meanA*meanA;
return res;
}
else if ( alongdimension == 1 ) {
// var of columns
var res = sub( entrywisediv(sum(entrywisemul(A,A),1) , A.length ) , entrywisemul(meanA,meanA) );
return res;
}
else if ( alongdimension == 2 ) {
// sum all columns, result is column vector
res = sub( entrywisediv(sum(entrywisemul(A,A),2) , A.n ) , entrywisemul(meanA,meanA) );
return res;
}
else
return undefined;
break;
default:
return undefined;
}
}
function std(A, alongdimension) {
if ( arguments.length > 1 )
return sqrt(variance(A,alongdimension));
else
return sqrt(variance(A));
}
/**
* Covariance matrix C = X'*X ./ X.m
* @param {Matrix|Float64Array|spVector}
* @return {Matrix|number}
*/
function cov( X ) {
switch ( type( X ) ) {
case "number":
return 0;
break;
case "vector":
var mu = mean(X);
return ( dot(X,X) / X.length - mu*mu);
break;
case "spvector":
var mu = mean(X);
return ( dot(X.val,X.val) / X.length - mu*mu);
break;
case "matrix":
var mu = mean(X,1).row(0);
return divMatrixScalar(xtx( subMatrices(X, outerprod(ones(X.m), mu ) ) ), X.m);
break;
case "spmatrix":
var mu = mean(X,1).row(0);
return divMatrixScalar(xtx( subspMatrixMatrix(X, outerprod(ones(X.m), mu ) ) ), X.m);
break;
default:
return undefined;
}
}
/**
* Compute X'*X
* @param {Matrix}
* @return {Matrix}
*/
function xtx( X ) {
const N = X.m;
const d = X.n;
var C = new Matrix(d,d);
for (var i=0; i < N; i++) {
var xi= X.row(i);
for(var k = 0; k < d; k++) {
var xik = xi[k];
for (var j=k; j < d; j++) {
C.val[k*d + j] += xik * xi[j];
}
}
}
// Symmetric lower triangular part:
for(var k = 0; k < d; k++) {
var kd = k*d;
for (var j=k; j < d; j++)
C.val[j*d+k] = C.val[kd+j];
}
return C;
}
function norm( A , sumalongdimension ) {
// l2-norm (Euclidean norm) of vectors or Frobenius norm of matrix
var i;
var j;
switch ( type( A ) ) {
case "number":
return Math.abs(A);
break;
case "vector":
if ( arguments.length == 1 || sumalongdimension == 1 ) {
return Math.sqrt(dot(A,A));
}
else
return abs(A);
break;
case "spvector":
if ( arguments.length == 1 || sumalongdimension == 1 ) {
return Math.sqrt(dot(A.val,A.val));
}
else
return abs(A);
break;
case "matrix":
if( arguments.length == 1 ) {
return Math.sqrt(dot(A.val,A.val));
}
else if ( sumalongdimension == 1 ) {
// norm of columns, result is row vector
const n = A.n;
var res = zeros(1, n);
var r = 0;
for (i=0; i< A.m; i++) {
for(j=0; j<n; j++)
res.val[j] += A.val[r+j]*A.val[r + j];
r += n;
}
for(j=0;j<n; j++)
res.val[j] = Math.sqrt(res.val[j]);
return res;
}
else if ( sumalongdimension == 2 ) {
// norm of rows, result is column vector
var res = zeros(A.m);
var r = 0;
for ( i=0; i < A.m; i++) {
for ( j=0; j < A.n; j++)
res[i] += A.val[r + j] * A.val[r + j];
r += A.n;
res[i] = Math.sqrt(res[i]);
}
return res;
}
else
return "undefined";
break;
case "spmatrix":
if( arguments.length == 1 ) {
return Math.sqrt(dot(A.val,A.val));
}
else if ( sumalongdimension == 1 && !A.rowmajor ) {
// norm of columns, result is row vector
const nn = A.n;
var res = zeros(1, nn);
for(j=0; j<nn; j++) {
var s = A.cols[j];
var e = A.cols[j+1];
for ( var k=s; k < e; k++)
res.val[j] += A.val[k]*A.val[k];
res.val[j] = Math.sqrt(res.val[j]);
}
return res;
}
else if ( sumalongdimension == 2 && A.rowmajor ) {
// norm of rows, result is column vector
var res = zeros(A.m);
for ( i=0; i < A.m; i++) {
var s = A.rows[i];
var e = A.rows[i+1];
for ( var k=s; k < e; k++)
res[i] += A.val[k] * A.val[k];
res[i] = Math.sqrt(res[i]);
}
return res;
}
else
return "undefined";
break;
default:
return "undefined";
}
}
function norm1( A , sumalongdimension ) {
// l1-norm of vectors and matrices
if ( arguments.length == 1 )
return sum(abs(A));
else
return sum(abs(A), sumalongdimension);
}
function norminf( A , sumalongdimension ) {
// linf-norm of vectors and max-norm of matrices
if ( arguments.length == 1 )
return max(abs(A));
else
return max(abs(A), sumalongdimension);
}
function normp( A , p, sumalongdimension ) {
// lp-norm of vectors and matrices
if ( arguments.length == 2 )
return Math.pow( sum(pow(abs(A), p) ), 1/p);
else
return pow(sum(pow(abs(A), p), sumalongdimension), 1/p);
}
function normnuc( A ) {
// nuclear norm
switch( type(A) ) {
case "matrix":
return sumVector(svd(A));
break;
case "spmatrix":
return sumVector(svd(fullMatrix(A)));
break;
case "number":
return A;
break;
case "vector":
case "spvector":
return 1;
break;
default:
return undefined;
break;
}
}
function norm0( A , sumalongdimension, epsilonarg ) {
// l0-pseudo-norm of vectors and matrices
// if epsilon > 0, consider values < epsilon as 0
var epsilon = EPS;
if ( arguments.length == 3 )
epsilon = epsilonarg;
var i;
var j;
switch ( type( A ) ) {
case "number":
return (Math.abs(A) > epsilon);
break;
case "vector":
if ( arguments.length == 1 || sumalongdimension == 1 ) {
return norm0Vector(A, epsilon);
}
else
return isGreater(abs(a), epsilon);
break;
case "spvector":
if ( arguments.length == 1 || sumalongdimension == 1 ) {
return norm0Vector(A.val, epsilon);
}
else
return isGreater(abs(a), epsilon);
break;
case "matrix":
if( arguments.length == 1 ) {
return norm0Vector(A.val, epsilon);
}
else if ( sumalongdimension == 1 ) {
// norm of columns, result is row vector
var res = zeros(1, A.n);
for (i=0; i< A.m; i++) {
for(j = 0; j < A.n; j++)
if ( Math.abs(A[i*A.n + j]) > epsilon )
res.val[j]++;
}
return res;
}
else if ( sumalongdimension == 2 ) {
// norm of rows, result is column vector
var res = zeros(A.m);
for (i=0; i< A.m; i++) {
for(j = 0; j < A.n; j++)
if ( Math.abs(A[i*A.n + j]) > epsilon )
res[i]++;
}
return res;
}
else
return undefined;
break;
case "spmatrix":
if( arguments.length == 1 ) {
return norm0Vector(A.val, epsilon);
}
else if ( sumalongdimension == 1 ) {
// norm of columns, result is row vector
var res = zeros(1, A.n);
if ( A.rowmajor ) {
for ( var k=0; k < A.val.length; k++)
if (Math.abs(A.val[k]) > epsilon)
res.val[A.cols[k]] ++;
}
else {
for ( var i=0; i<A.n; i++)
res.val[i] = norm0Vector(A.col(i).val, epsilon);
}
return res;
}
else if ( sumalongdimension == 2 ) {
// norm of rows, result is column vector
var res = zeros(A.m);
if ( A.rowmajor ) {
for ( var i=0; i<A.m; i++)
res[i] = norm0Vector(A.row(i).val, epsilon);
}
else {
for ( var k=0; k < A.val.length; k++)
if (Math.abs(A.val[k]) > epsilon)
res[A.rows[k]]++;
}
return res;
}
else
return undefined;
break;
default:
return undefined;
}
}
/**
* @param {Float64Array}
* @param {number}
* @return {number}
*/
function norm0Vector( x, epsilon ) {
const n = x.length;
var res = 0;
for (var i=0; i < n; i++)
if ( Math.abs(x[i]) > epsilon )
res++;
return res;
}
///////////////////////////////////////////:
// Linear systems of equations
///////////////////////////////////////
function solve( A, b ) {
/* Solve the linear system Ax = b */
var tA = type(A);
if ( tA == "vector" || tA == "spvector" || (tA == "matrix" && A.m == 1) ) {
// One-dimensional least squares problem:
var AtA = mul(transpose(A),A);
var Atb = mul(transpose(A), b);
return Atb / AtA;
}
if ( tA == "spmatrix" ) {
/*if ( A.m == A.n )
return spsolvecg(A, b); // assume A is positive definite
else*/
return spcgnr(A, b);
}
if( type(b) == "vector" ) {
if ( A.m == A.n )
return solveGaussianElimination(A, b) ;
else
return solveWithQRcolumnpivoting(A, b) ;
}
else
return solveWithQRcolumnpivotingMultipleRHS(A, b) ; // b is a matrix
}
/**
* Solve the linear system Ax = b given the Cholesky factor L of A
* @param {Matrix}
* @param {Float64Array}
* @return {Float64Array}
*/
function cholsolve ( L, b ) {
var z = forwardsubstitution(L, b);
var x = backsubstitution(transposeMatrix(L), z);
return x;
}
/**
* @param {Matrix}
* @param {Float64Array}
* @return {Float64Array}
*/
function solveWithQRfactorization ( A, b ) {
const m = A.length;
const n = A.n;
var QRfact = qr(A);
var R = QRfact.R;
var beta = QRfact.beta;
var btmp = vectorCopy(b);
var j;
var i;
var k;
var v;
var smallb;
for (j=0;j<n-1; j++) {
v = get(R, range(j,m), j) ; // get Householder vectors
v[0] = 1;
// b(j:m) = (I - beta v v^T ) * b(j:m)
smallb = get(btmp, range(j,m) );
set ( btmp, range(j,m), sub ( smallb , mul( beta[j] * mul( v, smallb) , v ) ) );
}
// last iteration only if m>n
if ( m > n ) {
j = n-1;
v = get(R, range(j,m), j) ; // get Householder vectors
v[0] = 1;
// b(j:m) = (I - beta v v^T ) * b(j:m)
smallb = get(btmp, range(j,m) );
set ( btmp, range(j,m), sub ( smallb , mul( beta[j] * mul( v, smallb) , v ) ) );
}
// Solve R x = b with backsubstitution (R is upper triangular, well it is not really here because we use the lower part to store the vectors v):
return backsubstitution ( R , get ( btmp, range(n)) );
// return backsubstitution ( get ( R, range(n), range(n) ) , rows ( btmp, range(1,n)) );
// we can spare the get and copy of R : backsubstitution will only use this part anyway
}
/**
* @param {Matrix}
* @param {Float64Array}
* @return {Float64Array}
*/
function backsubstitution ( U, b ) {
// backsubstitution to solve a linear system U x = b with upper triangular U
const n = b.length;
var j = n-1;
var x = zeros(n);
if ( ! isZero(U.val[j*n+j]) )
x[j] = b[j] / U.val[j*n+j];
j = n-2;
if ( !isZero(U.val[j*n+j]) )
x[j] = ( b[j] - U.val[j*n+n-1] * x[n-1] ) / U.val[j*n+j];
for ( j=n-3; j >= 0 ; j-- ) {
if ( ! isZero(U.val[j*n+j]) )
x[j] = ( b[j] - dot( U.row(j).subarray(j+1,n) , x.subarray(j+1,n) ) ) / U.val[j*n+j];
}
// solution
return x;
}
/**
* @param {Matrix}
* @param {Float64Array}
* @return {Float64Array}
*/
function forwardsubstitution ( L, b ) {
// forward substitution to solve a linear system L x = b with lower triangular L
const n = b.length;
var j;
var x = zeros(n);
if ( !isZero(L.val[0]) )
x[0] = b[0] / L.val[0];
if ( ! isZero(L.val[n+1]) )
x[1] = ( b[1] - L.val[n] * x[0] ) / L.val[n+1];
for ( j=2; j < n ; j++ ) {
if ( ! isZero(L.val[j*n+j]) )
x[j] = ( b[j] - dot( L.row(j).subarray(0,j) , x.subarray(0,j) ) ) / L.val[j*n+j];
}
// solution
return x;
}
/**
* @param {Matrix}
* @param {Float64Array}
* @return {Float64Array}
*/
function solveWithQRcolumnpivoting ( A, b ) {
var m;
var n;
var R;
var V;
var beta;
var r;
var piv;
if ( type( A ) == "matrix" ) {
// Compute the QR factorization
m = A.m;
n = A.n;
var QRfact = qr(A);
R = QRfact.R;
V = QRfact.V;
beta = QRfact.beta;
r = QRfact.rank;
piv = QRfact.piv;
}
else {
// we get the QR factorization in A
R = A.R;
r = A.rank;
V = A.V;
beta = A.beta;
piv = A.piv;
m = R.m;
n = R.n;
}
var btmp = vectorCopy(b);
var j;
var i;
var k;
var smallb;
// b = Q' * b
for (j=0;j < r; j++) {
// b(j:m) = (I - beta v v^T ) * b(j:m)
smallb = get(btmp, range(j,m) );
set ( btmp, range(j,m), sub ( smallb , mul( beta[j] * mul( V[j], smallb) , V[j] ) ) );
}
// Solve R x = b with backsubstitution
var x = zeros(n);
if ( r > 1 ) {
set ( x, range(0,r), backsubstitution ( R , get ( btmp, range(r)) ) );
// note: if m < n, backsubstitution only uses n columns of R.
}
else {
x[0] = btmp[0] / R.val[0];
}
// and apply permutations
for ( j=r-1; j>=0; j--) {
if ( piv[j] != j ) {
var tmp = x[j] ;
x[j] = x[piv[j]];
x[piv[j]] = tmp;
}
}
return x;
}
/**
* @param {Matrix}
* @param {Matrix}
* @return {Matrix}
*/
function solveWithQRcolumnpivotingMultipleRHS ( A, B ) {
var m;
var n;
var R;
var V;
var beta;
var r;
var piv;
if ( type( A ) == "matrix" ) {
// Compute the QR factorization
m = A.m;
n = A.n;
var QRfact = qr(A);
R = QRfact.R;
V = QRfact.V;
beta = QRfact.beta;
r = QRfact.rank;
piv = QRfact.piv;
}
else {
// we get the QR factorization in A
R = A.R;
r = A.rank;
V = A.V;
beta = A.beta;
piv = A.piv;
m = R.m;
n = R.n;
}
var btmp = matrixCopy(B);
var j;
var i;
var k;
var smallb;
// B = Q' * B
for (j=0;j < r; j++) {
// b(j:m) = (I - beta v v^T ) * b(j:m)
smallb = get(btmp, range(j,m), [] );
set ( btmp, range(j,m), [], sub ( smallb , mul(mul( beta[j], V[j]), mul( transpose(V[j]), smallb) ) ) );
}
// Solve R X = B with backsubstitution
var X = zeros(n,m);
if ( r > 1 ) {
for ( j=0; j < m; j++)
set ( X, range(0,r), j, backsubstitution ( R , get ( btmp, range(r), j) ) );
// note: if m < n, backsubstitution only uses n columns of R.
}
else {
set(X, 0, [], entrywisediv(get(btmp, 0, []) , R.val[0]) );
}
// and apply permutations
for ( j=r-1; j>=0; j--) {
if ( piv[j] != j ) {
swaprows(X, j, piv[j]);
}
}
return X;
}
function solveGaussianElimination(Aorig, borig) {
// Solve square linear system Ax = b with Gaussian elimination
var i;
var j;
var k;
var A = matrixCopy( Aorig ).toArrayOfFloat64Array(); // useful to quickly switch rows
var b = vectorCopy( borig );
const m = Aorig.m;
const n = Aorig.n;
if ( m != n)
return undefined;
// Set to zero small values... ??
for (k=0; k < m ; k++) {
// Find imax = argmax_i=k...m |A_i,k|
var imax = k;
var Aimaxk = Math.abs(A[imax][k]);
for (i=k+1; i<m ; i++) {
var Aik = Math.abs( A[i][k] );
if ( Aik > Aimaxk ) {
imax = i;
Aimaxk = Aik;
}
}
if ( isZero( Aimaxk ) ) {
console.log("** Warning in solve(A,b), A is square but singular, switching from Gaussian elimination to QR method.");
return solveWithQRcolumnpivoting(A,b);
}
if ( imax != k ) {
// Permute the rows
var a = A[k];
A[k] = A[imax];
A[imax] = a;
var tmpb = b[k];
b[k] = b[imax];
b[imax] = tmpb;
}
var Ak = A[k];
// Normalize row k
var Akk = Ak[k];
b[k] /= Akk;
//Ak[k] = 1; // not used afterwards
for ( j=k+1; j < n; j++)
Ak[j] /= Akk;
if ( Math.abs(Akk) < 1e-8 ) {
console.log("** Warning in solveGaussianElimination: " + Akk + " " + k + ":" + m );
}
// Substract the kth row from others to get 0s in kth column
var Aik ;
var bk = b[k];
for ( i=0; i< m; i++) {
if ( i != k ) {
var Ai = A[i];
Aik = Ai[k];
for ( j=k+1; j < n; j++) { // Aij = 0 with j < k and Aik = 0 after this operation but is never used
Ai[j] -= Aik * Ak[j];
}
b[i] -= Aik * bk;
}
}
}
// Solution:
return b;
}
function inv( M ) {
if ( typeof(M) == "number" )
return 1/M;
// inverse matrix with Gaussian elimination
var i;
var j;
var k;
const m = M.length;
const n = M.n;
if ( m != n)
return "undefined";
// Make extended linear system:
var A = matrixCopy(M) ;
var B = eye(n);
for (k=0; k < m ; k++) {
var kn = k*n;
// Find imax = argmax_i=k...m |A_i,k|
var imax = k;
var Aimaxk = Math.abs(A.val[imax*n + k]);
for (i=k+1; i<m ; i++) {
if ( Math.abs( A.val[i*n + k] ) > Aimaxk ) {
imax = i;
Aimaxk = Math.abs(A.val[i * n + k]);
}
}
if ( Math.abs( Aimaxk ) < 1e-12 ) {
return "singular";
}
if ( imax != k ) {
// Permute the rows
swaprows(A, k, imax);
swaprows(B,k, imax);
}
// Normalize row k
var Akk = A.val[kn + k];
for ( j=0; j < n; j++) {
A.val[kn + j] /= Akk;
B.val[kn + j] /= Akk;
}
if ( Math.abs(Akk) < 1e-8 )
console.log("!! Warning in inv(): " + Akk + " " + k + ":" + m );
// Substract the kth row from others to get 0s in kth column
var Aik ;
for ( i=0; i< m; i++) {
if ( i != k ) {
var ri = i*n;
Aik = A.val[ri+k];
if ( ! isZero(Aik) ) {
for ( j=0; j < n; j++) {
A.val[ri + j] -= Aik * A.val[kn+j];
B.val[ri + j] -= Aik * B.val[kn+j] ;
}
}
}
}
}
// Solution:
return B;
}
function chol( A ) {
// Compute the Cholesky factorization A = L L^T with L lower triangular
// for a positive definite and symmetric A
// returns L or undefined if A is not positive definite
const n = A.m;
if ( A.n != n) {
error("Cannot compute the cholesky factorization: the matrix is not square.");
return undefined;
}
const n2= n*n;
const Aval = A.val;
var L = new Float64Array(n2);
var i,j;
// first column = A(:,0) / sqrt(L(0,0)
var sqrtLjj = Math.sqrt(Aval[0]);
for ( i=0; i < n2 ; i+=n) { // i = i*n = ptr to row i
L[i] = Aval[i] / sqrtLjj;
}
// other colums
j = 1;
var jn = n;
while ( j < n && !isNaN(sqrtLjj)) {
for ( i = jn; i < n2; i+=n ) { // i = i*n
var Lij = Aval[i+j];
for ( var k=0; k < j; k++) {
Lij -= L[jn + k] * L[i + k];
}
if (i == jn)
sqrtLjj = Math.sqrt(Lij);
L[i +j] = Lij / sqrtLjj;
}
j++;
jn += n;
}
if ( isNaN(sqrtLjj) )
return undefined; // not positive definite
else
return new Matrix(n,n,L,true);
}
function ldlsymmetricpivoting ( Aorig ) {
// LDL factorization for symmetric matrices
var A = matrixCopy( Aorig );
var n = A.length;
if ( A.m != n ) {
error("Error in ldl(): the matrix is not square.");
return undefined;
}
var k;
var piv = zeros(n);
var alpha;
var v;
for ( k=0; k < n-1; k++) {
piv[k] = findmax(get(diag(A ), range(k,n) ));
swaprows(A, k, piv[k] );
swapcols(A, k, piv[k] );
alpha = A.val[k*n + k];
v = getCols ( A, [k]).subarray(k+1,n);
for ( var i=k+1;i < n; i++)
A.val[i*n + k] /= alpha;
set( A, range(k+1,n),range(k+1,n), sub (get(A,range(k+1,n), range(k+1,n)), outerprod(v,v, 1/alpha)));
}
// Make it lower triangular
for (var j=0; j < n-1; j++) {
for (var k=j+1; k < n ; k++)
A.val[j*n + k] = 0;
}
return {L: A, piv: piv};
}
/**
* @param {Float64Array}
* @return {{v: Float64Array, beta: number}}
*/
function house ( x ) {
// Compute Houselholder vector v such that
// P = (I - beta v v') is orthogonal and Px = ||x|| e_1
const n = x.length;
var i;
var mu;
var beta;
var v = zeros(n);
var v0;
var sigma ;
var x0 = x[0];
var xx = dot(x,x);
// sigma = x(2:n)^T x(2:n)
sigma = xx -x0*x0;
if ( isZero( sigma ) ) {
// x(2:n) is zero => v=[1,0...0], beta = 0
beta = 0;
v[0] = 1;
}
else {
mu = Math.sqrt(xx); // norm(x) ; //Math.sqrt( x0*x0 + sigma );
if ( x0 < EPS ) {
v0 = x0 - mu;
}
else {
v0 = -sigma / (x0 + mu);
}
beta = 2 * v0 * v0 / (sigma + v0 * v0 );
// v = [v0,x(2:n)] / v0
v[0] = 1;
for ( i=1; i< n; i++)
v[i] = x[i] / v0;
}
return { "v" : v , "beta" : beta};
}
/**
* @param {Matrix}
* @return {{Q: (Matrix|undefined), R: Matrix, beta: Float64Array}
*/
function qroriginal( A, compute_Q ) {
// QR factorization based on Householder reflections WITHOUT column pivoting
// A with m rows and n cols; m >= n
// test with A = [[12,-51,4],[6,167,-68],[-4,24,-41]]
// then R = [ [14 -21 -14 ], [ -3, 175, -70], [2, -0.75, 35]]
var m = A.length;
var n = A.n;
if ( n > m)
return "QR factorization unavailable for n > m.";
var i;
var j;
var k;
var householder;
var R = matrixCopy(A);
var beta = zeros(n);
var outer;
var smallR;
var Q;
var V = new Array(); // store householder vectors
for ( j=0; j < n - 1 ; j++) {
householder = house( get( R, range(j,m), j) );
// R(j:m,j:n) = ( I - beta v v' ) * R(j:m,j:n) = R - (beta v) (v'R)
smallR = get(R, range(j,m), range(j,n) );
set ( R, range(j,m), range(j,n) , subMatrices ( smallR , outerprodVectors( householder.v, mulMatrixVector( transposeMatrix(smallR), householder.v) , householder.beta ) ) ) ;
V[j] = householder.v;
beta[j] = householder.beta;
}
// Last iteration only if m > n: if m=n, (I - beta v v' ) = 1 => R(n,n) is unchanged
if ( m > n ) {
j = n-1;
smallR = get( R, range(j,m), j)
householder = house( smallR );
// R(j:m,n) = ( I - beta v v' ) * R(j:m, n) = R(j:m,n) - (beta v) (v'R(j:m,n) ) = Rn - ( beta *(v' * Rn) )* v
set ( R, range(j,m), n-1 , subVectors ( smallR , mulScalarVector( dot( householder.v, smallR ) * householder.beta, householder.v ) ) ) ;
V[j] = vectorCopy(householder.v);
beta[j] = householder.beta;
}
if ( compute_Q ) {
var r;
if ( typeof( compute_Q ) == "number") {
// compute only first r columns of Q
r = compute_Q;
Q = eye(m,r);
}
else {
Q = eye(m);
r = m;
}
var smallQ;
var nmax = n-1;
if ( m<=n)
nmax = n-2;
if ( nmax >= r )
nmax = r-1;
for ( j=nmax; j >=0; j--) {
smallQ = get(Q, range(j,m), range(j,r) );
if ( r > 1 ) {
if ( j == r-1)
set ( Q, range(j,m), [j] , subVectors ( smallQ , mulScalarVector( dot( smallQ, V[j]) * beta[j], V[j] ) ) );
else
set ( Q, range(j,m), range(j,r), sub ( smallQ , outerprod( V[j], mul( transpose( smallQ), V[j]), beta[j] ) ) );
}
else
Q = subVectors ( smallQ , mulScalarVector( dot( smallQ, V[j]) * beta[j], V[j] ) );
}
}
return {"Q" : Q, "R" : R, "beta" : beta };
}
/**
* @param {Matrix}
* @return {{Q: (Matrix|undefined), R: Matrix, V: Array, beta: Float64Array, piv: Float64Array, rank: number}
*/
function qr( A, compute_Q ) {
// QR factorization with column pivoting AP = QR based on Householder reflections
// A with m rows and n cols; m >= n (well, it also works with m < n)
// piv = vector of permutations : P = P_rank with P_j = identity with swaprows ( j, piv(j) )
// Implemented with R transposed for faster computations on rows instead of columns
/* TEST
A = [[12,-51,4],[6,167,-68],[-4,24,-41]]
QR = qr(A)
QR.R
*/
const m = A.m;
const n = A.n;
/*
if ( n > m)
return "QR factorization unavailable for n > m.";
*/
var i;
var j;
var householder;
var R = transpose(A);// transposed for faster implementation
var Q;
var V = new Array(); // store householder vectors in this list (not a matrix)
var beta = zeros(n);
var piv = zeros(n);
var smallR;
var r = -1; // rank estimate -1
var normA = norm(A);
var normR22 = normA;
var Rij;
const TOL = 1e-5;
var TOLnormR22square = TOL * normA;
TOLnormR22square *= TOLnormR22square;
var tau = 0;
var k = 0;
var c = zeros (n);
for ( j=0; j < n ; j++) {
var Rj = R.val.subarray(j*R.n,j*R.n + R.n);
c[j] = dot(Rj,Rj);
if ( c[j] > tau ) {
tau = c[j];
k = j;
}
}
var updateR = function (r, v, beta) {
// set ( R, range(r,n), range(r,m) , subMatrices ( smallR , outerprodVectors( mulMatrixVector( smallR, householder.v), householder.v, householder.beta ) ) ) ;
// most of the time is spent here...
var i,j,l;
var m_r = m-r;
for ( i=r; i < n; i++) {
var smallRiv = 0;
var Ri = i*m + r; // = i * R.n + r
var Rval = R.val.subarray(Ri,Ri+m_r);
for ( l = 0 ; l < m_r ; l ++)
smallRiv += Rval[l] * v[l]; //smallRiv += R.val[Ri + l] * v[l];
smallRiv *= beta ;
for ( j=0; j < m_r ; j ++) {
Rval[j] -= smallRiv * v[j]; // R.val[Ri + j] -= smallRiv * v[j];
}
}
};
// Update c
var updateC = function(r) {
var j;
for (j=r+1; j < n; j++) {
var Rjr = R.val[j*m + r];
c[j] -= Rjr * Rjr;
}
// tau, k = max ( c[r+1 : n] )
k=r+1;
tau = c[r+1];
for ( j=r+2; j<n;j++) {
if ( c[j] > tau ) {
tau = c[j];
k = j;
}
}
};
// Compute norm of residuals
var computeNormR22 = function(r) {
//normR22 = norm(get ( R, range(r+1,n), range(r+1,m), ) );
var normR22 = 0;
var i = r+1;
var ri = i*m;
var j;
while ( i < n && normR22 <= TOLnormR22square ) {
for ( j=r+1; j < m; j++) {
var Rij = R.val[ri + j];
normR22 += Rij*Rij;
}
i++;
ri += m;
}
return normR22;
}
while ( tau > EPS && r < n-1 && normR22 > TOLnormR22square ) {
r++;
piv[r] = k;
swaprows ( R, r, k);
c[k] = c[r];
c[r] = tau;
if ( r < m-1) {
householder = house( R.val.subarray(r*R.n + r,r*R.n + m) ); // house only reads vec so subarray is ok
}
else {
householder.v = [1];
householder.beta = 0;
//smallR = R[m-1][m-1];
}
if (r < n-1) {
// smallR is a matrix
updateR(r, householder.v, householder.beta);
}
else {
// smallR is a row vector (or a number if m=n):
if ( r < m-1) {
updateR(r, householder.v, householder.beta);
/*
var r_to_m = range(r,m);
smallR = get(R, r, r_to_m);
set ( R, r , r_to_m, sub ( smallR , transpose(mul( householder.beta * mul( smallR, householder.v) ,householder.v ) )) ) ;*/
}
else {
//var smallRnumber = R.val[(m-1)*R.n + m-1]; // beta is zero, so no update
//set ( R, r , r, sub ( smallRnumber , transpose(mul( householder.beta * mul( smallRnumber, householder.v) ,householder.v ) )) ) ;
}
}
// Store householder vectors and beta
V[r] = vectorCopy( householder.v );
beta[r] = householder.beta;
if ( r<n-1 ) {
// Update c
updateC(r);
// stopping criterion for rank estimation
if ( r < m-1 )
normR22 = computeNormR22(r);
else
normR22 = 0;
}
}
if ( compute_Q ) {
Q = eye(m);
var smallQ;
var nmax = r;
if ( m > r+1)
nmax = r-1;
for ( j=nmax; j >=0; j--) {
if ( j == m-1 ) {
Q.val[j*m+j] -= beta[j] * V[j][0] * V[j][0] * Q.val[j*m+j];
}
else {
var j_to_m = range(j,m);
smallQ = get(Q, j_to_m, j_to_m );// matrix
set ( Q, j_to_m, j_to_m, subMatrices ( smallQ , outerprodVectors( V[j], mulMatrixVector( transposeMatrix(smallQ), V[j]), beta[j] ) ) );
}
}
}
return {"Q" : Q, "R" : transpose(R), "V": V, "beta" : beta, "piv" : piv, "rank" : r+1 };
}
function qrRnotTransposed( A, compute_Q ) {
// QR factorization with column pivoting AP = QR based on Householder reflections
// A with m rows and n cols; m >= n (well, it also works with m < n)
// piv = vector of permutations : P = P_rank with P_j = identity with swaprows ( j, piv(j) )
// original implementation working on columns
/* TEST
A = [[12,-51,4],[6,167,-68],[-4,24,-41]]
QR = qr(A)
QR.R
*/
var m = A.m;
var n = A.n;
/*
if ( n > m)
return "QR factorization unavailable for n > m.";
*/
var i;
var j;
var householder;
var R = matrixCopy(A);
var Q;
var V = new Array(); // store householder vectors in this list (not a matrix)
var beta = zeros(n);
var piv = zeros(n);
var smallR;
var r = -1; // rank estimate -1
var normA = norm(A);
var normR22 = normA;
var TOL = 1e-6;
var tau = 0;
var k = 0;
var c = zeros (n);
for ( j=0; j < n ; j++) {
var Aj = getCols ( A, [j]);
c[j] = dot(Aj, Aj);
if ( c[j] > tau ) {
tau = c[j];
k = j;
}
}
while ( tau > EPS && r < n-1 && normR22 > TOL * normA ) {
r++;
piv[r] = k;
swapcols ( R, r, k);
c[k] = c[r];
c[r] = tau;
if ( r < m-1) {
householder = house( get( R, range(r,m), r) );
smallR = get(R, range(r,m), range(r,n) );
}
else {
householder.v = [1];
householder.beta = 0;
smallR = R[m-1][m-1];
}
if (r < n-1) {
// smallR is a matrix
set ( R, range(r,m), range(r,n) , subMatrices ( smallR , outerprodVectors( householder.v, mulMatrixVector( transposeMatrix(smallR), householder.v) , householder.beta ) ) ) ;
}
else {
// smallR is a vector (or a number if m=n):
set ( R, range(r,m), r , sub ( smallR , mul( householder.beta * mul( smallR, householder.v) ,householder.v ) ) ) ;
}
// Store householder vectors and beta
if ( m > r+1 )
V[r] = vectorCopy( householder.v );
beta[r] = householder.beta;
if ( r<n-1 ) {
// Update c
for ( j=r+1; j < n; j++) {
c[j] -= R[r][j] * R[r][j];
}
// tau, k = max ( c[r+1 : n] )
k=r+1;
tau = c[r+1];
for ( j=r+2; j<n;j++) {
if ( c[j] > tau ) {
tau = c[j];
k = j;
}
}
// stopping criterion for rank estimation
if ( r < m-1 ) {
//normR22 = norm(get ( R, range(r+1,m),range(r+1,n) ) );
normR22 = 0;
for ( i=r+1; i < m; i++) {
for ( j=r+1; j < n; j++) {
Rij = R[i][j];
normR22 += Rij*Rij;
}
}
normR22 = Math.sqrt(normR22);
}
else
normR22 = 0;
}
}
if ( compute_Q ) {
Q = eye(m);
var smallQ;
var nmax = r;
if ( m>r+1)
nmax = r-1;
for ( j=nmax; j >=0; j--) {
if ( j == m-1 ) {
Q.val[j*m+j] -= beta[j] * V[j][0] * V[j][0] * Q.val[j*m+j];
}
else {
smallQ = get(Q, range(j,m), range(j,m) );
set ( Q, range(j,m), range(j,m) , subMatrices ( smallQ , outerprodVectors( V[j], mulMatrixVector( transposeMatrix(smallQ), V[j]), beta[j] ) ) );
}
}
}
return {"Q" : Q, "R" : R, "V": V, "beta" : beta, "piv" : piv, "rank" : r+1 };
}
/** Conjugate gradient method for solving the symmetyric positive definite system Ax = b
* @param{{Matrix|spMatrix}}
* @param{Float64Array}
* @return{Float64Array}
*/
function solvecg ( A, b) {
if( A.type == "spmatrix" )
return spsolvecg(A,b);
else
return solvecgdense(A,b);
}
/** Conjugate gradient method for solving the symmetyric positive definite system Ax = b
* @param{Matrix}
* @param{Float64Array}
* @return{Float64Array}
*/
function solvecgdense ( A, b) {
/*
TEST
A = randn(2000,1000)
x = randn(1000)
b = A*x + 0.01*randn(2000)
tic()
xx = solve(A,b)
t1 = toc()
ee = norm(A*xx - b)
tic()
xh=solvecg(A'*A, A'*b)
t2 = toc()
e = norm(A*xh - b)
*/
const n = A.n;
const m = A.m;
var x = randn(n); //vectorCopy(x0);
var r = subVectors(b, mulMatrixVector(A, x));
var rhoc = dot(r,r);
const TOL = 1e-8;
var delta2 = TOL * norm(b);
delta2 *= delta2;
// first iteration:
var p = vectorCopy(r);
var w = mulMatrixVector(A,p);
var mu = rhoc / dot(p, w);
saxpy( mu, p, x);
saxpy( -mu, w, r);
var rho_ = rhoc;
rhoc = dot(r,r);
var k = 1;
var updateP = function (tau, r) {
for ( var i=0; i < m; i++)
p[i] = r[i] + tau * p[i];
}
while ( rhoc > delta2 && k < n ) {
updateP(rhoc/rho_, r);
w = mulMatrixVector(A,p);
mu = rhoc / dot(p, w);
saxpy( mu, p, x);
saxpy( -mu, w, r);
rho_ = rhoc;
rhoc = dot(r,r);
k++;
}
return x;
}
/** Conjugate gradient normal equation residual method for solving the rectangular system Ax = b
* @param{{Matrix|spMatrix}}
* @param{Float64Array}
* @return{Float64Array}
*/
function cgnr ( A, b) {
if( A.type == "spmatrix" )
return spcgnr(A,b);
else
return cgnrdense(A,b);
}
/** Conjugate gradient normal equation residual method for solving the rectangular system Ax = b
* @param{Matrix}
* @param{Float64Array}
* @return{Float64Array}
*/
function cgnrdense ( A, b) {
/*
TEST
A = randn(2000,1000)
x = randn(1000)
b = A*x + 0.01*randn(2000)
tic()
xx = solve(A,b)
t1 = toc()
ee = norm(A*xx - b)
tic()
xh=cgnr(A, b)
t2 = toc()
e = norm(A*xh - b)
*/
const n = A.n;
const m = A.m;
var x = randn(n); // vectorCopy(x0);
var At = transposeMatrix(A);
var r = subVectors(b, mulMatrixVector(A, x));
const TOL = 1e-8;
var delta2 = TOL * norm(b);
delta2 *= delta2;
// first iteration:
var z = mulMatrixVector(At, r);
var rhoc = dot(z,z);
var p = vectorCopy(z);
var w = mulMatrixVector(A,p);
var mu = rhoc / dot(w, w);
saxpy( mu, p, x);
saxpy( -mu, w, r);
z = mulMatrixVector(At, r);
var rho_ = rhoc;
rhoc = dot(z,z);
var k = 1;
var updateP = function (tau, z) {
for ( var i=0; i < m; i++)
p[i] = z[i] + tau * p[i];
}
while ( rhoc > delta2 && k < n ) {
updateP(rhoc/rho_, z);
w = mulMatrixVector(A,p);
mu = rhoc / dot(w, w);
saxpy( mu, p, x);
saxpy( -mu, w, r);
z = mulMatrixVector(At, r);
rho_ = rhoc;
rhoc = dot(z,z);
k++;
}
return x;
}
/** Lanczos algorithm
* @param{Matrix}
*/
function lanczos ( A, q1 ) {
const maxIters = 300;
const TOL = EPS * norm(A);
const n = A.n;
var i;
var k = 0;
var w = vectorCopy(q1);
var v = mulMatrixVector(A, w);
var alpha = dot(w,v);
saxpy(-alpha, w, v);
beta = norm(b);
while ( beta > TOL && k < maxIters ) {
for ( i=0; i < n; i++) {
var t = w[i];
w[i] = v[i] / beta;
v[i] = -beta / t;
}
var Aw = mulMatrixVector(A,w);
for ( i=0; i < n; i++)
v[i] += Aw[i];
alpha = dot(w,v);
saxpy(-alpha,w,v);
beta = norm(v);
k++;
}
}
/**
* @param{Matrix}
* @param{boolean}
* @return{Matrix}
*/
function tridiagonalize( A, returnQ ) {
// A : a square and symmetric matrix
// T = Q A Q' , where T is tridiagonal and Q = (H1 ... Hn-2)' is the product of Householder transformations.
// if returnQ, then T overwrites A
var k;
const n = A.length;
var T;
var Q;
var Pk;
if ( returnQ ) {
T = A;
Q = eye(n);
var beta = [];
var V = [];
}
else
T = matrixCopy(A);
var p;
var w;
var vwT;
var normTkp1k;
var householder;
for (k=0; k < n-2; k++) {
Tkp1k = get ( T, range(k+1, n), k);
Tkp1kp1 = get ( T, range(k+1,n), range(k+1, n));
householder = house ( Tkp1k );
p = mulScalarVector( householder.beta , mulMatrixVector( Tkp1kp1, householder.v ) );
w = subVectors ( p, mulScalarVector( 0.5*householder.beta * dot(p, householder.v ), householder.v) );
/*
T[k+1][k] = norm ( Tkp1k );
T[k][k+1] = T[k+1][k];
*/
// make T really tridiagonal: the above does not modify the other entries to set them to 0
normTkp1k = zeros(n-k-1);
normTkp1k[0] = norm ( Tkp1k );
set ( T, k, range(k+1,n ), normTkp1k );
set ( T, range(k+1,n), k, normTkp1k);
vwT = outerprodVectors(householder.v,w);
set ( T, range(k+1,n), range(k+1, n), subMatrices( subMatrices ( Tkp1kp1, vwT) , transpose(vwT)) );
if ( returnQ ) {
V[k] = householder.v;
beta[k] = householder.beta;
}
}
if ( returnQ ) {
var updateQ = function(j, v, b) {
// Q = Q - b* v (Q'v)'
//smallQ = get(Q, range(j,n), range(j,n) );// matrix
//set ( Q, range(j,n), range(j,n) , subMatrices ( smallQ , outerprodVectors( V[k], mulMatrixVector( transposeMatrix(smallQ), V[k]), beta[k] ) ) );
var i,k;
var Qtv = zeros(n-j);
var n_j = n-j;
for ( i=0; i<n_j; i++) {
var Qi = (i+j)*n + j;
for ( k=0;k<n_j; k++)
Qtv[k] += v[i] * Q.val[Qi + k];
}
for ( i=0; i < n_j; i++) {
var Qi = (i+j)*n + j;
var betavk = b * v[i];
for ( k=0; k < n_j ; k++) {
Q.val[Qi + k] -= betavk * Qtv[k];
}
}
};
// Backaccumulation of Q
for ( k=n-3; k >=0; k--) {
updateQ(k+1,V[k], beta[k]);
}
return Q;
}
else
return T;
}
function givens(a,b,Gi,Gk,n) {
// compute a Givens rotation:
var c;
var s;
var tau;
var G;
// Compute c and s
if ( b == 0) {
c = 1;
s = 0;
}
else {
if ( Math.abs(b) > Math.abs(a) ) {
tau = -a / b;
s = 1 / Math.sqrt(1+tau*tau);
c = s*tau;
}
else {
tau = -b / a;
c = 1 / Math.sqrt(1+tau*tau);
s = c * tau;
}
}
if ( arguments.length == 5 ) {
// Build Givens matrix G from c and s:
G = eye(n) ;
G.val[Gi*n+Gi] = c;
G.val[Gi*n+Gk] = s;
G.val[Gk*n+Gi] = -s;
G.val[Gk*n+Gk] = c;
return G;
}
else {
return [c,s];
}
}
/**
* @param {number}
* @param {number}
* @param {number}
* @param {number}
* @param {Matrix}
*/
function premulGivens ( c, s, i, k, A) {
// apply a Givens rotation to A : A([i,k],:) = G' * A([i,k],:)
// with G = givens (a,b,i,k) and [c,s]=givens(a,b)
// NOTE: this modifies A
const n = A.n;
var j;
const ri = i*n;
const rk = k*n;
var t1;
var t2;
for ( j=0; j < n; j++) {
t1 = A.val[ri + j];
t2 = A.val[rk + j];
A.val[ri + j] = c * t1 - s * t2;
A.val[rk + j] = s * t1 + c * t2;
}
}
/**
* @param {number}
* @param {number}
* @param {number}
* @param {number}
* @param {Matrix}
*/
function postmulGivens ( c, s, i, k, A) {
// apply a Givens rotation to A : A(:, [i,k]) = A(:, [i,k]) * G
// with G = givens (a,b,i,k) and [c,s]=givens(a,b)
// NOTE: this modifies A
const m = A.length;
var j;
var t1;
var t2;
var rj = 0;
for ( j=0; j < m; j++) {
t1 = A.val[rj + i];
t2 = A.val[rj + k];
A.val[rj + i] = c * t1 - s * t2;
A.val[rj + k] = s * t1 + c * t2;
rj += A.n;
}
}
function implicitSymQRWilkinsonShift( T , computeZ) {
// compute T = Z' T Z
// if computeZ: return {T,cs} such that T = Z' T Z with Z = G1.G2...
// and givens matrices Gk of parameters cs[k]
const n = T.length;
const rn2 = n*(n-2);
const rn1 = n*(n-1);
const d = ( T.val[rn2 + n-2] - T.val[rn1 + n-1] ) / 2;
const t2 = T.val[rn1 + n-2] * T.val[rn1 + n-2] ;
const mu = T.val[rn1 + n-1] - t2 / ( d + Math.sign(d) * Math.sqrt( d*d + t2) );
var x = T.val[0] - mu; // T[0][0]
var z = T.val[n]; // T[1][0]
var cs;
if ( computeZ)
var csArray = new Array(n-1);
//var Z = eye(n);
var k;
for ( k = 0; k < n-1; k++) {
/*
G = givens(x,z, k, k+1, n);
T = mul(transpose(G), mul(T, G) ); // can do this much faster
if ( computeZ ) {
Z = mul(Z, G );
}
*/
cs = givens(x,z);
postmulGivens(cs[0], cs[1], k, k+1, T);
premulGivens(cs[0], cs[1], k, k+1, T);
if( computeZ )
csArray[k] = [cs[0], cs[1]];
//postmulGivens(cs[0], cs[1], k, k+1, Z);
if ( k < n-2 ) {
var r = n*(k+1) + k;
x = T.val[r];
z = T.val[r + n]; // [k+2][k];
}
}
if ( computeZ) {
return {"T": T, "cs": csArray} ;
// return {"T": T, "Z": Z} ;
}
else
return T;
}
function eig( A , computeEigenvectors ) {
// Eigendecomposition of a symmetric matrix A (QR algorithm)
var Q;
var D;
if ( computeEigenvectors ) {
D = matrixCopy(A);
Q = tridiagonalize( D, true );
}
else {
D = tridiagonalize( A );
}
var q;
var p;
const n = A.length;
var i;
const TOL = 1e-12; //10 * EPS;
do {
for ( i=0; i<n-1; i++) {
if ( Math.abs( D.val[i*n + i+1] ) < TOL * ( Math.abs(D.val[i*n+i] ) + Math.abs(D.val[(i+1)*n+i+1] ) ) ) {
D.val[i*n+i+1] = 0;
D.val[(i+1)*n+i] = 0;
}
}
// find largest q such that D[n-p-q:n][n-p-q:n] is diagonal:
if ( !isZero( D.val[(n-1)*n+n-2] ) || !isZero( D.val[(n-2)*n + n-1] ) )
q = 0;
else {
q = 1;
while ( q < n-1 && isZero( D.val[(n-q-1)*n+ n-q-2] ) && isZero( D.val[(n-q-2)*n + n-q-1] ) )
q++;
if ( q >= n-1 )
q = n;
}
// find smallest p such that D[p:q][p:q] is unreduced ( without zeros on subdiagonal?)
p = -1;
var zerosOnSubdiagonal ;
do {
p++;
zerosOnSubdiagonal = false;
k=p;
while (k<n-q-1 && zerosOnSubdiagonal == false) {
if ( isZero ( D.val[(k+1)*n + k] ) )
zerosOnSubdiagonal = true;
k++;
}
} while ( zerosOnSubdiagonal && p + q < n );
// Apply implicit QR iteration
if ( q < n ) {
if ( computeEigenvectors ) {
var res = implicitSymQRWilkinsonShift( get ( D, range(p,n-q), range(p,n-q)), true);
set( D, range(p,n-q), range(p,n-q), res.T );
for ( var kk = 0; kk < n-q-p-1; kk++)
postmulGivens(res.cs[kk][0], res.cs[kk][1], p+kk, p+kk+1, Q);
//Z = eye(n);
//set(Z, range(p,n-q), range(p,n-q), DZ22.Z );
// Q = mulMatrixMatrix ( Q, Z );
}
else {
set( D, range(p,n-q), range(p,n-q), implicitSymQRWilkinsonShift( get ( D, range(p,n-q), range(p,n-q)) , false)) ;
}
}
} while (q < n ) ;
if ( computeEigenvectors ) {
return { "V" : diag(D), "U": Q};
}
else
return diag(D);
}
function eigs( A, r, smallest ) {
// Compute r largest or smallest eigenvalues and eigenvectors
if( typeof(r) == "undefined")
var r = 1;
if( typeof(smallest) == "undefined" || smallest == false || smallest !="smallest" ) {
if ( r == 1)
return eig_powerIteration ( A );
else
return eig_orthogonalIteration ( A , r) ;
}
else {
// look for smallest eigenvalues
if ( r == 1)
return eig_inverseIteration ( A , 0);
else
return eig_bisect( A, r);
//return eig_inverseOrthogonalIteration ( A , r) ;
}
}
function eig_powerIteration ( A , u0) {
// Compute the largest eigenvalue and eigenvector with the power method
const maxIters = 1000;
var k;
const n = A.length;
// init with a random u or an initial guess u0
var u;
if ( typeof(u0) == "undefined")
u = randn(n);
else
u = u0;
u = mulScalarVector(1/norm(u), u);
var lambda = 1;
for ( k=0; k< maxIters; k++) {
// Apply the iteration : u = Au / norm(Au)
u = mulMatrixVector(A, u) ;
lambda = norm(u);
u = mulScalarVector(1/ lambda, u);
}
return { "v" : lambda, "u" : u};
}
function eig_orthogonalIteration ( A, r ) {
if ( r == 1 )
return eig_powerIteration ( A );
// Compute the r largest eigenvalue and eigenvector with the power method (orthogonal iteration)
const maxIters = 1000;
var k;
const n = A.length;
// init with a random Q
var Q = randn(n,r);
var normQ = norm(Q,1);
Q = entrywisediv(Q, mul(ones(n),normQ) );
var QR;
var Z;
const TOL = 1e-11;
var V;
for ( k=0; k< maxIters; k++) {
// Z = AQ
Z = mulMatrixMatrix(A, Q);
if ( Math.floor(k / 50) == k / 50) {
// convergence test
V = mulMatrixMatrix(transpose(Q), Z);
if ( norm ( subMatrices ( Z, mulMatrixMatrix(Q, diag(diag(V)) ) ) ) < TOL )
break;
}
// QR = Z // XXX maybe not do this at every iteration...
Q = qroriginal(Z,r).Q;
}
V = mulMatrixMatrix(transpose(Q), mulMatrixMatrix(A, Q) );
return {"V": diag(V ), "U" : Q};
}
function eig_inverseIteration ( A, lambda ) {
// Compute an eigenvalue-eigenvector pair from an approximate eigenvalue with the inverse iteration
var perturbation = 0.0001*lambda;
if ( typeof(maxIters) == "undefined" )
var maxIters = 100;
var k;
const n = A.length;
// apply power iteration with (A - lambda I)^-1 instead of A
var A_lambdaI = sub(A, mul(lambda + perturbation, eye(n) ));
var QR = qr( A_lambdaI ); // and precompute QR factorization
while (QR.rank < n) { // check if not singular
perturbation *= 10;
A_lambdaI = sub(A, mul(lambda + perturbation, eye(n) ));
QR = qr( A_lambdaI ); // and precompute QR factorization
//console.log(perturbation);
}
// init
var u = sub(mul(2,rand(n)),1); //ones(n); //
u = mulScalarVector( 1/norm(u), u );
var v;
var r;
var norminfA = norminf(A);
k = 0;
do {
// u = solve(A_lambdaI , u) ;
u = solveWithQRcolumnpivoting ( QR, u ); // QR factorization precomputed
v = norm(u);
u = entrywisediv(u , v);
r = mulMatrixVector(A_lambdaI, u);
k++;
} while ( k < maxIters && maxVector(absVector(r)) < 1e-10 * norminfA); // && Math.abs(v * perturbation - 1 ) < EPS );
return u;
}
function eigenvector ( A, lambda ) {
return eig_inverseIteration(A, lambda, 2);
}
function eig_inverseOrthogonalIteration ( A, r ) {
if ( r == 1 )
return eig_inverseIteration ( A );
// Compute the r smallest eigenvalue and eigenvectors with the inverse power method
// (orthogonal iteration)
const maxIters = 1000;
var k;
const n = A.length;
var QR = qr( A ); // precompute QR factorization
// init with a random Q
var Q = randn(n,r);
var normQ = norm(Q,1);
Q = entrywisediv(Q, mul(ones(n),normQ) );
var QR;
var Z;
const TOL = 1e-11;
var V;
for ( k=0; k< maxIters; k++) {
// Z = A^-1 Q
Z = solveWithQRcolumnpivotingMultipleRHS ( QR, Q );
if ( Math.floor(k / 50) == k / 50) {
// convergence test
V = mulMatrixMatrix(transpose(Q), Z);
if ( norm ( subMatrices ( Z, mulMatrixMatrix(Q, V ) ) ) < TOL )
break;
}
// QR = Z // XXX maybe not do this at every iteration...
Q = qroriginal(Z,r).Q;
}
V = mulMatrixMatrix(transpose(Q), mulMatrixMatrix(A, Q) );
return {"V": diag(V ), "U" : Q, "iters": k};
}
function eig_bisect( A, K ) {
// find K smallest eigenvalues
/*
TEST
//Symmetric eigenvalue decomposition
X = rand(5,5)
A = X*X'
v = eig(A)
eig_bisect(A,3)
*/
var x,y,z;
// Tridiagonalize A
var T = tridiagonalize( A );
const n = T.n;
var a = diag(T);
var b = zeros(n);
var i;
for ( i=0; i < n-1; i++)
b[i] = T.val[i*n + i + 1];
// Initialize [y,z] with Gershgorin disk theorem
var y0 = a[0] - b[0];
var z0 = a[0] + b[0];
for ( var i=1; i < n; i++) {
var yi = a[i] - b[i] - b[i-1];
var zi = a[i] + b[i] + b[i-1];
if( yi < y0 )
y0 = yi;
if( zi > z0 )
z0 = zi;
}
/*
// polynomial evaluation and counting sign changes (original method)
var polya = function (x,a,b,n) {
var pr_2 = 1;
var pr_1 = a[0] - x;
var pr;
var signchanges = 0;
if ( pr_1 < EPS )
signchanges = 1;
var r;
for ( r = 1; r < n ; r++) {
pr = (a[r] - x) * pr_1 - b[r-1] * b[r-1] * pr_2;
if ( Math.abs(pr) < EPS || (pr > 0 && pr_1 < 0 ) || (pr < 0) && (pr_1 > 0) )
signchanges ++;
pr_2 = pr_1;
pr_1 = pr;
}
return signchanges;
};
*/
// ratio of polynomials evaluation and counting sign changes
// (modification discussed in Barth et al., 1967 for better stability due to pr ~ 0 in the above)
var polyq = function (x,a,b,n) {
var qi_1 = a[0] - x;
var qi;
var signchanges = 0;
if ( qi_1 < EPS )
signchanges = 1;
var i;
for ( i = 1; i < n ; i++) {
qi = (a[i] - x) - b[i-1] * b[i-1] / qi_1;
if ( qi < EPS )
signchanges ++;
if ( Math.abs(qi) < EPS )
qi_1 = EPS;
else
qi_1 = qi;
}
return signchanges;
};
// Start bisection
const TOL = 1e-10;
var lambda = zeros(K);
var xu = entrywisemul(z0,ones(K)); // upper bounds on lambdas
y = y0;
var n_lowerthan_x;// nb of eigenvalues lower than x
for ( var k = 1; k <= K ; k++ ) {
// k is the number of desired eigenvalues in this sweep
z = xu[k-1];
//y=y; from previous sweep
// find the (n-k+1)th eigenvalue
while ( Math.abs(z - y) > TOL*(Math.abs(y) + Math.abs(z)) ) {
x = (y+z)/2;
n_lowerthan_x = polyq(x,a,b,n);
if(n_lowerthan_x >= k )
z = x; // enough eigenvalues below x, decrease upper bound to x
else
y = x; // not enough ev below x, increase lower bound to x
// update boudns on other lambdas
for ( var j=k+1; j <= K; j++)
if ( n_lowerthan_x >= j )
xu[j-1] = x;
}
lambda[k-1] = (y+z)/2;
}
//return lambda;
// Compute eigenvectors: XXX can be faster by using inverse iteration on the tridiagonal matrix
// with faster system solving
var u = eigenvector( A, lambda[0] );
var U = mat([u],false);
for ( k = 1; k < K; k++) {
// deal with too close eigenvalues
var perturbtol = 10 * Math.max(EPS, Math.abs(EPS * lambda[k-1]));
if ( lambda[k] < lambda[k-1] + perturbtol )
lambda[k] = lambda[k-1] + perturbtol;
u = eigenvector( A, lambda[k] );
U = mat([U, u], false );
U = qroriginal( U, U.n ).Q; // orthogonalize
}
return {U: U, V: lambda};
}
function bidiagonalize( A, computeU, thinU , computeV ) {
// B = U' A V , where B is upper bidiagonal
var j;
const m = A.length;
const n = A.n;
var B;
B = matrixCopy( A );
var householder;
if ( computeU ) {
if ( thinU ) {
var U = eye(m,n);
var nU = n;
}
else {
var U = eye(m);
var nU = m;
}
}
if ( computeV ) {
var V = eye(n);
}
var updateB1 = function (j, v, beta) {
// B = B - (beta v) ( v'* B) = B-outer(beta v, B'*v)
//Bjmjn = get ( B, range(j,m), range(j, n));
//set ( B, range(j,m), range(j,n), sub ( Bjmjn , outerprod ( householder.v, mul(transpose(Bjmjn), householder.v), householder.beta) ) );
var i,k;
var Btv = zeros(n-j);
var n_j = n-j;
var m_j = m-j;
for ( i=0; i<m_j; i++) {
var Bi = (i+j)*n + j;
for ( k=0;k<n_j; k++)
Btv[k] += v[i] * B.val[Bi+k];
}
for ( i=0; i < m_j; i++) {
var betavk = beta * v[i];
var Bi = (i+j)*n + j;
for ( k=0; k < n_j ; k++) {
B.val[Bi+k] -= betavk * Btv[k];
}
}
};
var updateB2 = function (j, v, beta) {
// B = B - beta (Bv) v' (with B = B_j:m, j+1:n)
//Bjmjn = get ( B, range(j,m), range(j+1, n));
//set ( B, range(j,m), range(j+1,n) , sub( Bjmjn, outerprod( mul(Bjmjn, householder.v), householder.v, householder.beta) ) );
var i,k;
var n_j_1 = n-j-1;
for ( i=j; i < m; i++) {
var Bi = i*n + j + 1;
var Bv = 0;
for ( k=0;k<n_j_1; k++)
Bv += B.val[Bi + k] * v[k] ;
var betaBvk = beta * Bv;
for ( k=0; k < n_j_1 ; k++) {
B.val[Bi + k] -= betaBvk * v[k];
}
}
};
if ( computeV ) {
var updateV = function (j, v, beta) {
//smallV = get ( V, range(0,n), range(j+1, n));
//set ( V, range(0,n), range(j+1,n) , sub( smallV, outerprod( mul(smallV, householder.v), householder.v, householder.beta) ) );
var i,k;
var n_j_1 = n-j-1;
for ( i=0; i < n; i++) {
var Vi = i*n + j + 1;
var Vv = 0;
for ( k=0;k<n_j_1; k++)
Vv += V.val[Vi + k] * v[k] ;
var betaVvk = beta * Vv;
for ( k=0; k < n_j_1 ; k++) {
V.val[Vi + k] -= betaVvk * v[k];
}
}
};
}
if ( computeU ) {
var hv=new Array(n);// Householder vectors and betas
var hb=new Array(n);
}
for (j=0; j < n ; j++) {
if ( j < m-1) {
householder = house( get ( B, range(j, m), j) );
updateB1(j, householder.v, householder.beta);
if ( computeU ) {
hv[j] = vectorCopy(householder.v);
hb[j] = householder.beta;
// updateU(j, householder.v, householder.beta);
}
}
if ( j < n-2) {
householder = house ( B.row(j).subarray(j+1, n) ) ;
updateB2(j, householder.v, householder.beta);
if( computeV ) {
updateV(j, householder.v, householder.beta);
}
}
}
if (computeU) {
// Back accumulation of U (works with less than m columns)
// Un_1 = (I-beta v v')Un = Un - beta v (v' Un)
/*for (j=n-1;j>=0; j--) {
if (j<m-1){
smallU = get(U,range(j,m),[]);
set(U,range(j,m),[], sub(smallU, mul(bv[j],mul(hv[j], mul(transpose(hv[j]) , smallU)))));
}
}*/
var updateU = function (j, v, beta) {
var i,k;
var vtU = zeros(nU);
for ( i=j; i<m; i++) {
var Ui = i*nU;
var i_j = i-j;
for ( k=0;k<nU; k++)
vtU[k] += v[i_j] * U.val[Ui + k];
}
for ( i=j; i < m; i++) {
var betavk = beta * v[i-j];
var Ui = i*nU;
for ( k=0; k < nU ; k++) {
U.val[Ui + k] -= betavk * vtU[k];
}
}
};
var nj = Math.min(n-1,m-2);
for (j=nj;j>=0; j--) {
updateU(j,hv[j], hb[j]);
}
}
if ( computeU && computeV ) {
return { "U" : U, "V": V, "B": B};
}
else if (computeV )
return { "V": V, "B": B};
else if (computeU)
return { "U" : U, "B": B};
else
return B;
}
function GolubKahanSVDstep ( B, i, j, m, n, computeUV ) {
// Apply GolubKahanSVDstep to B(i:i+m, j:j+n)
// Note: working on Utrans
if (type ( B ) != "matrix" )
return B;
if ( n < 2 )
return B;
const rn2 = (i+n-2)*B.n + j;
const dm = B.val[rn2 + n-2];
const fm = B.val[rn2 + n-1];
var fm_1 ;
if ( n>2)
fm_1 = B.val[(i+n-3)*B.n + j + n-2];
else
fm_1 = 0;
const dn = B.val[(i+n-1)*B.n + j + n-1];
const d = ( dm*dm + fm_1*fm_1 - dn*dn - fm*fm ) / 2;
const t2 = dm*fm * dm*fm;
const mu = dn*dn+fm*fm - t2 / ( d + Math.sign(d) * Math.sqrt( d*d + t2) );
var k;
//var B0 = getCols ( B, [0]);
//var B1 = getCols ( B, [1]) ;
//var y = mul( B0, B0 ) - mu;
//var z = mul( B0, B1 );
var y = - mu;
var z = 0.0;
var r0 = i*B.n + j;
for ( k = 0; k< n; k++) {
y += B.val[r0] * B.val[r0];
z += B.val[r0] * B.val[r0+1];
r0 += B.n;
}
var G;
var cs;
var postmulgivens = function ( c, s, k1, k2) {
// apply a Givens rotation to a subset of rows of B : B(i:i+m, [k1,k2]) = B(i:i+m, [k1,k2]) * G
var jj;
var t1;
var t2;
var rj = i*B.n + j;
for ( jj=0; jj < m; jj++) {
t1 = B.val[rj + k1];
t2 = B.val[rj + k2];
B.val[rj + k1] = c * t1 - s * t2;
B.val[rj + k2] = s * t1 + c * t2;
rj += B.n;
}
}
var premulgivens = function ( c, s, k1, k2) {
// apply a Givens rotation to a subset of cols of B : B([k1,k2],j:j+n) = G' * B([k1,k2],j:j+n)
var jj;
const ri = (i+k1)*B.n + j;
const rk = (i+k2)*B.n + j;
var t1;
var t2;
for ( jj=0; jj < n; jj++) {
t1 = B.val[ri + jj];
t2 = B.val[rk + jj];
B.val[ri + jj] = c * t1 - s * t2;
B.val[rk + jj] = s * t1 + c * t2;
}
}
if ( computeUV) {
//var U = eye(m);
//var V = eye(n);
var csU = new Array(n-1);
var csV = new Array(n-1);
}
for ( k = 0; k < n-1 ; k++) {
cs = givens(y,z);
postmulgivens(cs[0],cs[1], k, k+1);
if ( computeUV ) {
csV[k] = [cs[0], cs[1]];
// postmulGivens(cs[0],cs[1], k, k+1, V);
}
y = B.val[(i+k)*B.n + j + k];
z = B.val[(i+k+1)*B.n + j + k];
cs = givens(y,z);
premulgivens(cs[0],cs[1], k, k+1);
if ( computeUV ) {
csU[k] = [cs[0], cs[1]];
//premulGivens(cs[0],cs[1], k, k+1, U);
}
if ( k < n-2 ) {
y = B.val[(i+k)*B.n + j + k+1];
z = B.val[(i+k)*B.n + j + k+2];
}
}
if ( computeUV)
return {csU: csU, csV: csV};
}
function svd( A , computeUV ) {
/* TEST:
A=[ [-149,-50,-154],[537,180,546],[-27,-9,-25]]
s=svd(A)
should return [ 817.7597, 2.4750, 0.0030]
*/
if ( type(A) == "vector" || (type(A) == "matrix" && A.n == 1) ) {
return { "U" : matrixCopy(A), "S" : ones(1,1), "V" : ones(1,1), "s" : [1] };
}
if ( A.m == 1) {
return { "U" : ones(1,1), "S" : ones(1,1), "V" : transpose(A), "s" : [1] };
}
var i;
var m = A.length;
var n = A.n;
var Atransposed = false;
if ( n > m ) {
Atransposed = true;
var At = transposeMatrix(A);
n = m;
m = At.length;
}
var computeU = false;
var computeV = false;
var thinU = false;
if ( typeof( computeUV) != "undefined" && computeUV!==false) {
if ( computeUV === "full" ) {
computeU = true;
computeV = true;
thinU = false;
}
else if (computeUV === true || computeUV === "thin" ) {
computeU = true;
computeV = true;
thinU = true;
}
else if ( typeof(computeUV) == "string") {
if ( computeUV.indexOf("U") >=0 )
computeU = true;
if ( computeUV.indexOf("V") >=0 )
computeV = true;
if ( computeUV.indexOf("thin") >=0 )
thinU = true;
}
var UBV;
if ( Atransposed ) {
var tmp = computeU;
computeU = computeV;
computeV = tmp;
UBV = bidiagonalize( At, computeU, thinU, computeV );
}
else
UBV = bidiagonalize( A, computeU, thinU, computeV );
if ( computeU ) {
var U = transpose(UBV.U);//Utrans
}
else
var U = undefined;
if( computeV ) {
var V = UBV.V;
var Vt = transposeMatrix(V);
}
else
var V = undefined;
var B = UBV.B;
}
else {
if ( Atransposed )
var B = bidiagonalize( At, false, false, false );
else
var B = bidiagonalize( matrixCopy(A), false, false, false );
}
var B22;
var U22;
var V22;
var cs;
var q;
var p;
var k;
const TOL = 1e-11;
do {
for ( i=0; i<n-1; i++) {
if ( Math.abs( B.val[i*B.n + i+1] ) < TOL * ( Math.abs(B.val[i*B.n + i]) + Math.abs(B.val[(i+1) * B.n + i+1]) ) ) {
B.val[i*B.n + i+1] = 0;
}
}
// find largest q such that B[n-p-q:n][n-p-q:n] is diagonal:
if ( ( Math.abs( B.val[(n-1)*B.n + n-2] ) > TOL ) || (Math.abs(B.val[(n-2)*B.n + n-1]) > TOL ) ) {
q = 0;
}
else {
q = 1;
while ( q < n-1 && Math.abs( B.val[(n-q-1)*B.n + n-q-2] ) < TOL && Math.abs( B.val[(n-q-2)*B.n + n-q-1] ) < TOL ) {
q++;
}
if ( q >= n-1 )
q = n;
}
// find smallest p such that B[p:q][p:q] has no zeros on superdiag
p=n-q-1;
while ( p > 0 && ! isZero ( B.val[(p-1)*B.n + p] ) )
p--;
if ( q < n ) {
var DiagonalofB22isZero = -1;
for ( k=p; k< n-q-1 ; k++) {
if ( Math.abs( B.val[k*B.n + k] ) < TOL ) {
DiagonalofB22isZero = k;
break;
}
}
if ( DiagonalofB22isZero >= 0 ) {
if ( DiagonalofB22isZero < n-q-1 ) {
// Zero B(k,k+1) and entire row k...
for (j=DiagonalofB22isZero+1; j < n; j++) {
cs = givens(- B.val[j*B.n + j] , B.val[DiagonalofB22isZero * B.n + j] );
premulGivens(cs[0],cs[1], DiagonalofB22isZero, j, B);
if ( computeU )
premulGivens(cs[0],cs[1], DiagonalofB22isZero, j, U);
}
}
else {
// Zero B(k-1,k) and entire row k...
for (j=DiagonalofB22isZero - 1; j >= p; j--) {
cs = givens(B.val[j*B.n * j] , B.val[j*B.n + n-q-1] );
postmulGivens(cs[0],cs[1], j, n-q-1, B);
if ( computeV )
premulGivens(cs[0],cs[1], j, n-q-1, Vt);
// postmulGivens(cs[0],cs[1], j, n-q-1, V);
}
}
}
else {
//B22 = get ( B, range(p , n - q ) , range (p , n-q ) );
if ( computeUV ) {
// UBV = GolubKahanSVDstep( B22, true ) ;
// set ( U, range(p,n-q), [], mul(UBV.U, get(U, range(p,n-q), []) ) );
// set ( Vt, range(p,n-q), [], mul(transpose(UBV.V), getRows(Vt, range(p,n-q)) ) );
var GKstep = GolubKahanSVDstep( B, p, p, n-q-p, n-q-p, true ) ;// this updates B22 inside B
for ( var kk=0; kk < n-q-p-1; kk++) {
if ( computeU )
premulGivens(GKstep.csU[kk][0], GKstep.csU[kk][1], p+kk, p+kk+1, U);
if ( computeV )
premulGivens(GKstep.csV[kk][0], GKstep.csV[kk][1], p+kk, p+kk+1, Vt); // premul because Vtransposed
}
}
else {
GolubKahanSVDstep( B, p, p, n-q-p, n-q-p ) ;
}
//set ( B , range(p , n - q ) , range (p , n-q ), B22 );
}
}
} while ( q < n ) ;
if (computeUV ) {
if ( computeV)
V = transposeMatrix(Vt);
// Correct sign of singular values:
var s = diag(B);
var signs = zeros(n);
for ( i=0; i< n; i++) {
if (s[i] < 0) {
if ( computeV )
set(V, [], i, minus(get(V,[],i)));
s[i] = -s[i];
}
}
// Rearrange in decreasing order:
var indexes = sort(s,true, true);
if(computeV)
V = get( V, [], indexes);
if(computeU) {
if ( !thinU) {
for ( i=n; i < m; i++)
indexes.push(i);
}
U = get(U, indexes,[]) ;
}
if ( thinU )
var S = diag(s) ;
else
var S = mat([diag(s), zeros(m-n,n)],true) ;
var Ut = undefined;
if ( computeU )
Ut = transpose(U);
if ( Atransposed ) {
if ( thinU )
return { "U" : V, "S" : S, "V" : Ut, "s" : s };
else
return { "U" : V, "S" : transpose(S), "V" : Ut, "s" : s };
}
else {
return { "U" : Ut, "S" : S, "V" : V, "s" : s };
}
}
else
return sort(abs(diag(B)), true);
}
function rank( A ) {
const s = svd(A);
var rank = 0;
var i;
for ( i=0;i < s.length;i++)
if ( s[i] > 1e-10 )
rank++;
return rank;
}
function nullspace( A ) {
// Orthonormal basis for the null space of A
const s = svd( A, "V" ) ;
const n = A.n;
var rank = 0;
const TOL = 1e-8;
while ( rank < n && s.s[rank] > TOL )
rank++;
if ( rank < n )
return get ( s.V, [], range(rank, n) );
else
return zeros(n);
}
function orth( A ) {
// Orthonormal basis for the range of A
const s = svd( A, "thinU" ) ;
const n = A.n;
var rank = 0;
const TOL = 1e-8;
while ( rank < n && s.s[rank] > TOL )
rank++;
return get ( s.U, [], range(0,rank) );
}
/////////////////////////////
//// Sparse matrix and vectors
/////////////////////////////
/**
*
* new spVector(n) => allocate for n nonzeros with dim n
* new spVector(n, nnz) => allocate for nnz nonzeros out of n
* new spVector(n,values,indexes) => allocate for values.length nonzeros
*
* @constructor
* @struct
*/
function spVector(n, values, indexes) {
/** @const */ this.length = n;
/** @const */ this.size = [n,1];
/** @const */ this.type = "spvector";
if ( arguments.length <= 2) {
if ( arguments.length == 1)
var nnz = n; // too large but more efficient at some point...
else
var nnz = values;
/** @type{Float64Array} */ this.val = new Float64Array(nnz); // nz values
/** @type{Uint32Array} */ this.ind = new Uint32Array(nnz); // ind[k] = index of val[k]
}
else {
var nnz = values.length;
/** @type{Float64Array} */ this.val = new Float64Array(values); // nz values
/** @type{Uint32Array} */ this.ind = new Uint32Array(indexes); // ind[k] = index of val[k]
}
/** @const */ this.nnz = nnz;
}
/*
* @param{number}
* @return{number}
*/
spVector.prototype.get = function ( i ) {
var k = this.ind.indexOf(i);
if ( k < 0 )
return 0;
else
return this.val[k];
}
/*
* @param{number}
* @param{number}
*/
spVector.prototype.set = function ( i, value ) {
// Inefficient do not use this, use sparse(x) instead
if ( i > this.n ) {
error( "Error in spVector.set(i,value): i > this.length)");
return undefined;
}
var k = this.ind.indexOf(i);
if ( k < 0 ) {
var ind = new Uint32Array(this.nnz + 1);
var val = new Float64Array(this.nnz + 1);
k = 0;
while ( this.ind[k] < i ) { // copy values until i
ind[k] = this.ind[k]; // making sure this.ind remains sorted
val[k] = this.val.ind[k];
k++;
}
ind[k] = i;// insert value
val[k] = value;
ind.set(this.ind.subarray(k), k+1);// copy rest of vector
val.set(this.val.subarray(k), k+1);
this.nnz++;
}
else
this.val[k] = value;
return value;
}
/*
* @return{spVector}
*/
spVector.prototype.copy = function () {
return new spVector(this.n, this.val, this.ind);
}
/**
*
* new spMatrix(m,n) => allocate for m*n nonzeros
* new spMatrix(m,n, nnz) => allocate for nnz nonzeros
* new spMatrix(m,n,values,cols,rows) => allocate for values.length nonzeros
*
* @constructor
* @struct
*/
function spMatrix(m,n, values, cols, rows) {
/** @const */ this.length = m;
/** @const */ this.m = m;
/** @const */ this.n = n;
/** @const */ this.size = [m,n];
/** @const */ this.type = "spmatrix";
if ( arguments.length <= 3) {
if ( arguments.length == 2)
var nnz = m*n; // too large but more efficient at some point...
else
var nnz = values;
/** @type{boolean} */ this.rowmajor = true;
/** @type{Float64Array} */ this.val = new Float64Array(nnz); // nnz values
/** @type{Uint32Array} */ this.cols = new Uint32Array(nnz); // cols[j] = starting index of col j in val and rows
/** @type{Uint32Array} */ this.rows = new Uint32Array(m+1); // rows[k] = row of val[k]
}
else {
var nnz = values.length;
if ( rows.length == nnz && cols.length == n+1 && cols[cols.length-1] == nnz ) {
/** @type{boolean} */ this.rowmajor = false;
/** @type{Float64Array} */ this.val = new Float64Array(values); // nz values
/** @type{Uint32Array} */ this.cols = new Uint32Array(cols); // cols[j] = starting index of col j in val and rows
/** @type{Uint32Array} */ this.rows = new Uint32Array(rows); // rows[k] = row of val[k]
}
else {
/** @type{boolean} */ this.rowmajor = true;
/** @type{Float64Array} */ this.val = new Float64Array(values); // nz values
/** @type{Uint32Array} */ this.cols = new Uint32Array(cols); // cols[k] = col of val[k]
/** @type{Uint32Array} */ this.rows = new Uint32Array(rows); // rows[i] = starting index of row i in val and cols
}
}
/** @const */ this.nnz = nnz;
}
/*
* @return{spMatrix}
*/
spMatrix.prototype.copy = function () {
return new spMatrix(this.m, this.n, this.val, this.cols, this.rows);
}
/*
* @return{spMatrix}
*/
spMatrix.prototype.toRowmajor = function () {
if ( this.rowmajor )
return this.copy();
else {
return sparseMatrixRowMajor( fullMatrix(this) );
}
}
/*
* Get a pointer to the spVector for row i
* @return{spVector}
*/
spMatrix.prototype.row = function ( i ) {
if ( this.rowmajor ) {
return new spVector(this.n, this.val.subarray(this.rows[i], this.rows[i+1]), this.cols.subarray(this.rows[i], this.rows[i+1]));
/*
var s = this.rows[i];
var e = this.rows[i+1];
var vec = new spVector(this.n);
vec.val.set(this.val.subarray(s,e));
vec.ind.set(this.cols.subarray(s,e));
return vec;*/
}
else {
error ("Cannot extract sparse column from a sparse matrix in row major format.");
return undefined;
}
}
/*
* Get a pointer to the spVector for column j
* @return{spVector}
*/
spMatrix.prototype.col = function ( j ) {
if ( ! this.rowmajor )
return new spVector(this.m, this.val.subarray(this.cols[j], this.cols[j+1]), this.rows.subarray(this.cols[j], this.cols[j+1]));
else {
error ("Cannot extract sparse column from a sparse matrix in row major format.");
return undefined;
}
}
/*
* @param{number}
* @param{number}
* @return{number}
*/
spMatrix.prototype.get = function ( i, j ) {
if ( this.rowmajor ) {
var rowind = this.cols.subarray(this.rows[i], this.rows[i+1]);
var k = rowind.indexOf(j);
if ( k < 0 )
return 0;
else
return this.val[this.rows[i] + k];
}
else {
var colind = this.rows.subarray(this.cols[j], this.cols[j+1]);
var k = colind.indexOf(i);
if ( k < 0 )
return 0;
else
return this.val[this.cols[j] + k];
}
}
function spgetRows(A, rowsrange) {
var n = rowsrange.length;
if ( A.rowmajor) {
if ( n > 1 ) {
var rowsidx = sort(rowsrange);
var Ai = new Array(n);
var nnz = 0;
for ( var i = 0; i < n; i++) {
Ai[i] = A.row(rowsidx[i]);
nnz += Ai[i].val.length;
}
var val = new Float64Array( nnz );
var cols = new Uint32Array( nnz );
var rows = new Uint32Array( n+1 );
var k = 0;
for ( var i = 0; i < n; i++) {
rows[i] = k;
val.set(Ai[i].val, k);
cols.set(Ai[i].ind, k);
k += Ai[i].val.length;
}
rows[i] = k;
return new spMatrix(n, A.n, val, cols, rows);
}
else
return A.row( rowsrange[0] ) ;
}
else {
return getRows(fullMatrix(A), rowsrange);
}
}
/**
* Return the full/dense version of the vector
* @param{spVector}
* @return{Float64Array}
*/
function fullVector (x) {
var k;
const n = x.length;
const nnz = x.val.length;
var a = new Float64Array(n);
for ( k=0; k < nnz; k++)
a[x.ind[k]] = x.val[k];
return a;
}
/**
* Return the full/dense version of the matrix
* @param{spMatrix}
* @return{Matrix}
*/
function fullMatrix (S) {
const n = S.n;
if ( S.rowmajor ) {
var k;
const m = S.m;
var A = new Float64Array(m * n);
var ri = 0;
for (var i = 0; i < m; i++) {
var s = S.rows[i];
var e = S.rows[i+1];
for ( k=s; k < e; k++) {
A[ri + S.cols[k] ] = S.val[k];
}
ri += n;
}
return new Matrix(m, n, A, true);
}
else {
var k;
var A = new Float64Array(S.m * n);
for (var j = 0; j < n; j++) {
var s = S.cols[j];
var e = S.cols[j+1];
for ( k=s; k < e; k++) {
var i = S.rows[k];
A[i*n + j] = S.val[k];
}
}
return new Matrix(S.m, n, A, true);
}
}
function full( A ) {
switch(type(A)) {
case "spvector":
return fullVector(A);
break;
case "spmatrix":
return fullMatrix(A);
break;
default:
return A;
break;
}
}
/**
* @param{Float64Array}
* @return{spVector}
*/
function sparseVector( a ) {
var i,k;
const n = a.length;
var val = new Array();
var ind = new Array();
for ( i=0; i < n; i++) {
if (!isZero(a[i]) ) {
val.push(a[i]);
ind.push(i);
}
}
return new spVector(n,val,ind);
}
/**
* @param{Matrix}
* @return{spMatrix}
*/
function sparseMatrix( A ) {
var i,j;
const m = A.m;
const n = A.n;
var val = new Array();
var rows = new Array();
var cols = new Uint32Array(n+1);
var k;
for ( j=0; j< n; j++) {
k = j;
for ( i=0; i < m; i++) {
// k = i*n+j;
if (!isZero(A.val[k]) ) {
val.push(A.val[k]);
rows.push(i);
cols[j+1]++;
}
k += n;
}
}
for ( j=1; j< n; j++)
cols[j+1] += cols[j];
return new spMatrix(m,n,val,cols,rows);
}
/**
* @param{Matrix}
* @return{spMatrix}
*/
function sparseMatrixRowMajor( A ) {
var i,j;
const m = A.m;
const n = A.n;
var val = new Array();
var cols = new Array();
var rows = new Uint32Array(m+1);
var k = 0;
for ( i=0; i < m; i++) {
for ( j=0; j< n; j++) {
// k = i*n+j;
if (!isZero(A.val[k]) ) {
val.push(A.val[k]);
rows[i+1]++;
cols.push(j);
}
k++;
}
}
for ( i=1; i< m; i++)
rows[i+1] += rows[i];
return new spMatrix(m,n,val,cols,rows);
}
function sparse( A , rowmajor ) {
if(typeof(rowmajor) == "undefined" )
var rowmajor = true;
switch(type(A)) {
case "vector":
return sparseVector(A);
break;
case "matrix":
if ( rowmajor )
return sparseMatrixRowMajor(A);
else
return sparseMatrix(A);
break;
case "spvector":
case "spmatrix":
return A.copy();
break;
default:
return A;
break;
}
}
/**
* @param{number}
* @return{spMatrix}
*/
function speye(m,n) {
if ( typeof(n) == "undefined" )
var n = m;
if ( m == 1 && n == 1)
return 1;
var e = (m<n)?m:n;
var val = ones(e);
var rows = range(e+1);
var cols = rows.slice(0,e);
return new spMatrix(m,n,val,cols,rows);
}
/**
* @param{Float64Array}
* @return{spMatrix}
*/
function spdiag(val) {
var n = val.length;
var rows = range(n+1);
var cols = rows.slice(0,n);
var tv = type(val);
if ( tv == "vector")
return new spMatrix(n,n,val,cols,rows);
else {
error("Error in spdiag( x ): x is a " + tv + " but should be a vector.");
return undefined;
}
}
/**
* @param{spVector}
* @return{Matrix}
*/
function transposespVector (a) {
return new Matrix(1,a.length, fullVector(a), true);
}
/**
* @param{spMatrix}
* @return{spMatrix}
*/
function transposespMatrix (A) {
return new spMatrix(A.n, A.m, A.val, A.rows, A.cols);
/*
const m = A.m;
const n = A.n;
var At = zeros(n, m);
for ( var j=0; j < n; j++) {
var s = A.cols[j];
var e = A.cols[j+1];
for ( var k=s;k < e; k++) {
At[ rj + A.rows[k] ] = A.val[k];
}
rj += m;
}
return sparseMatrix(At);
*/
}
/** Concatenate sparse matrices/vectors
* @param {Array}
* @param {boolean}
* @return {spMatrix}
*/
function spmat( elems, rowwise ) {
var k;
var elemtypes = new Array(elems.length);
for ( k=0; k < elems.length; k++) {
elemtypes[k] = type(elems[k]);
}
if ( typeof(rowwise) == "undefined")
var rowwise = true;
if ( elems.length == 0 ) {
return [];
}
var m = 0;
var n = 0;
var nnz = 0;
var i;
var j;
if ( rowwise ) {
var res = new Array( ) ;
for ( k= 0; k<elems.length; k++) {
switch( elemtypes[k] ) {
case "vector": // vector (auto transposed)
var v = sparseVector(elems[k]);
res.push ( v ) ;
m += 1;
n = elems[k].length;
nnz += v.val.length;
break;
case "spvector":
res.push(elems[k]);
n = elems[k].length;
m += 1;
nnz += elems[k].val.length;
break;
case "spmatrix":
for ( var r=0; r < elems[k].m; r++)
res.push(elems[k].row(r));
res.push(elems[k]);
n = elems[k].length;
m += 1;
nnz += elems[k].val.length;
break;
default:
return undefined;
break;
}
}
var M = new spMatrix( m , n , nnz ) ;
var p = 0;
M.rows[0] = 0;
for (k=0; k < res.length ; k++) {
if ( res[k].val.length > 1 ) {
M.val.set( new Float64Array(res[k].val), p);
M.cols.set( new Uint32Array(res[k].ind), p);
M.rows[k+1] = M.rows[k] + res[k].val.length;
p += res[k].val.length;
}
else if (res[k].val.length == 1) {
M.val[p] = res[k].val[0];
M.cols[p] = res[k].ind[0];
M.rows[k+1] = M.rows[k] + 1;
p += 1;
}
}
return M;
}
else {
// not yet...
error("spmat(..., false) for columnwise concatenation of sparse vectors not yet implemented");
return res;
}
}
/**
* @param{number}
* @param{spVector}
* @return{spVector}
*/
function mulScalarspVector (a, b) {
const nnz = b.val.length;
var c = b.copy();
for ( var k=0;k < nnz; k++)
c.val[k] *= a;
return c;
}
/**
* @param{number}
* @param{spMatrix}
* @return{spMatrix}
*/
function mulScalarspMatrix (a, B) {
const nnz = B.nnz;
var C = B.copy();
for ( var k=0;k < nnz; k++)
C.val[k] *= a;
return C;
}
/**
* @param{spVector}
* @param{spVector}
* @return{number}
*/
function spdot (a, b) {
const nnza = a.val.length;
const nnzb = b.val.length;
var c = 0;
var ka = 0;
var kb = 0;
while ( ka < nnza && kb < nnzb ){
var i = a.ind[ka];
while ( b.ind[kb] < i && kb < nnzb)
kb++;
if(b.ind[kb] == i)
c += a.val[ka] * b.val[kb];
ka++;
}
return c;
}
/**
* @param{spVector}
* @param{Float64Array}
* @return{number}
*/
function dotspVectorVector (a, b) {
const nnza = a.val.length;
var c = 0;
for ( var ka=0;ka < nnza; ka++)
c += a.val[ka] * b[a.ind[ka]];
return c;
}
/**
* @param{Matrix}
* @param{spVector}
* @return{Float64Array}
*/
function mulMatrixspVector (A, b) {
const m = A.m;
const n = A.n;
const nnz = b.val.length;
var c = zeros(m);
var ri = 0;
for ( var i=0;i < n; i++) {
for ( var k=0; k < nnz; k++)
c[i] += A.val[ri + b.ind[k]] * b.val[k];
ri+=n;
}
return c;
}
/**
* @param{spMatrix}
* @param{Float64Array}
* @return{Float64Array}
*/
function mulspMatrixVector (A, b) {
const m = A.m;
const n = A.n;
var c = zeros(m);
if ( A.rowmajor) {
for(var i=0; i < m; i++) {
var s = A.rows[i];
var e = A.rows[i+1];
for(var k = s; k < e; k++) {
c[i] += A.val[k] * b[A.cols[k]];
}
}
}
else {
for ( var j=0;j < n; j++) {
var s = A.cols[j];
var e = A.cols[j+1];
var bj = b[j];
for ( var k= s; k < e; k++) {
c[A.rows[k]] += A.val[k] * bj;
}
}
}
return c;
}
/**
* @param{spMatrix}
* @param{Float64Array}
* @return{Float64Array}
*/
function mulspMatrixTransVector (A, b) {
const m = A.m;
const n = A.n;
var c = zeros(n);
if ( A.rowmajor ) {
for ( var j=0;j < m; j++) {
var s = A.rows[j];
var e = A.rows[j+1];
var bj = b[j];
for ( var k= s; k < e; k++) {
c[A.cols[k]] += A.val[k] * bj;
}
}
}
else {
for ( var j=0;j < n; j++) {
var s = A.cols[j];
var e = A.cols[j+1];
for ( var k= s; k < e; k++) {
c[j] += A.val[k] * b[A.rows[k]];
}
}
}
return c;
}
/**
* @param{spMatrix}
* @param{spVector}
* @return{Float64Array}
*/
function mulspMatrixspVector (A, b) {
const m = A.m;
const n = A.n;
var c = zeros(m);
const nnzb = b.val.length;
if ( A.rowmajor) {
for(var i=0; i < m; i++) {
c[i] = spdot(A.row(i), b);
}
}
else {
for ( var kb=0;kb < nnzb; kb++) {
var j = b.ind[kb];
var bj = b.val[kb];
var s = A.cols[j];
var e = A.cols[j+1];
for ( var k= s; k < e; k++) {
c[A.rows[k]] += A.val[k] * bj;
}
}
}
return c;
}
/**
* @param{spMatrix}
* @param{spVector}
* @return{Float64Array}
*/
function mulspMatrixTransspVector (A, b) {
const m = A.m;
const n = A.n;
var c = zeros(n);
const nnzb = b.val.length;
if (A.rowmajor) {
for ( var kb=0;kb < nnzb; kb++) {
var j = b.ind[kb];
var bj = b.val[kb];
var s = A.rows[j];
var e = A.rows[j+1];
for ( var k= s; k < e; k++) {
c[A.cols[k]] += A.val[k] * bj;
}
}
}
else {
for ( var i= 0; i < n; i++) {
var kb = 0;
var s = A.cols[i];
var e = A.cols[i+1];
for ( var ka=s;ka < e; ka++) {
var j = A.rows[ka];
while ( b.ind[kb] < j && kb < nnzb)
kb++;
if(b.ind[kb] == i)
c[i] += A.val[ka] * b.val[kb];
}
}
}
return c;
}
/**
* @param{spMatrix}
* @param{spMatrix}
* @return{Matrix}
*/
function mulspMatrixspMatrix (A, B) {
const m = A.m;
const n = A.n;
const n2 = B.n;
var c = zeros(m, n2);
if ( A.rowmajor ) {
if ( B.rowmajor ) {
for ( var ic = 0; ic < m; ic++) {
var sa = A.rows[ic];
var ea = A.rows[ic+1];
for ( var ka = sa; ka < ea; ka++) {
var j = A.cols[ka];
var aj = A.val[ka];
var s = B.rows[j];
var e = B.rows[j+1];
var rc = ic * n2 ;
for (var k= s; k < e; k++) {
c.val[rc + B.cols[k] ] += aj * B.val[k] ;
}
}
}
}
else {
var kc = 0;
for ( var i=0; i < m; i++) {
for ( var j=0; j < n2; j++) {
c.val[kc] = spdot(A.row(i), B.col(j));
kc++;
}
}
}
}
else {
if ( B.rowmajor ) {
for (var ja=0;ja < n; ja++) {
var sa = A.cols[ja];
var ea = A.cols[ja+1];
var sb = B.rows[ja];
var eb = B.rows[ja+1];
for ( var ka = sa; ka < ea; ka++) {
var rc = A.rows[ka] * n2;
var aij = A.val[ka];
for(var kb = sb; kb < eb; kb++) {
c.val[rc + B.cols[kb]] += aij * B.val[kb];
}
}
}
}
else {
for ( var jc = 0; jc < n2; jc++) {
var sb = B.cols[jc];
var eb = B.cols[jc+1];
for ( var kb = sb; kb < eb; kb++) {
var j = B.rows[kb];
var bj = B.val[kb];
var s = A.cols[j];
var e = A.cols[j+1];
for (var k= s; k < e; k++) {
c.val[A.rows[k] * n2 + jc] += A.val[k] * bj;
}
}
}
}
}
return c;
}
/**
* @param{Matrix}
* @param{spMatrix}
* @return{Matrix}
*/
function mulMatrixspMatrix (A, B) {
const m = A.m;
const n = A.n;
const n2 = B.n;
var c = zeros(m, n2);
if ( B.rowmajor ) {
for (var ja=0;ja < n; ja++) {
var sb = B.rows[ja];
var eb = B.rows[ja+1];
for ( var i = 0; i < m; i++) {
var rc = i * n2;
var aij = A.val[i * n + ja];
for(var kb = sb; kb < eb; kb++) {
c.val[rc + B.cols[kb]] += aij * B.val[kb];
}
}
}
}
else {
for ( var jc = 0; jc < n2; jc++) {
var sb = B.cols[jc];
var eb = B.cols[jc+1];
for ( var kb = sb; kb < eb; kb++) {
var j = B.rows[kb];
var bj = B.val[kb];
for ( i= 0; i < m; i++) {
c.val[i * n2 + jc] += A.val[i*n + j] * bj;
}
}
}
}
return c;
}
/**
* @param{spMatrix}
* @param{Matrix}
* @return{Matrix}
*/
function mulspMatrixMatrix (A, B) {
const m = A.m;
const n = A.n;
const n2 = B.n;
var c = zeros(m, n2);
if ( A.rowmajor ) {
for(var i=0; i < m; i++) {
var sa = A.rows[i];
var ea = A.rows[i+1];
for(var ka = sa; ka < ea; ka++) {
var ai = A.val[ka];
var rb = A.cols[ka] * n2;
var rc = i*n2;
for ( j=0; j < n2; j++) {
c.val[rc + j] += ai * B.val[rb + j];
}
}
}
}
else {
for(var j=0; j < n; j++) {
var s = A.cols[j];
var e = A.cols[j+1];
for ( var k= s; k < e; k++) {
var i = A.rows[k];
for ( var jc = 0; jc < n2; jc++)
c.val[i*n2 + jc ] += A.val[k] * B.val[j*n2 + jc];
}
}
}
return c;
}
/**
* @param{spVector}
* @param{spVector}
* @return{spVector}
*/
function entrywisemulspVectors (a, b) {
const nnza = a.val.length;
const nnzb = b.val.length;
var val = new Array();
var ind = new Array();
var ka = 0;
var kb = 0;
while ( ka < nnza && kb < nnzb ){
var i = a.ind[ka];
while ( b.ind[kb] < i && kb < nnzb)
kb++;
if(b.ind[kb] == i) {
var aibi = a.val[ka] * b.val[kb];
if ( !isZero(aibi) ) {
val.push(aibi);
ind.push(i);
}
}
ka++;
}
return new spVector(a.length, val, ind);
}
/**
* @param{spVector}
* @param{Float64Array}
* @return{spVector}
*/
function entrywisemulspVectorVector (a, b) {
// fast operation but might not yield optimal nnz:
var c = a.copy();
const nnz = a.val.length;
for ( var k = 0; k< nnz; k++) {
c.val[k] *= b[a.ind[k]];
}
return c;
}
/**
* @param{spMatrix}
* @param{spMatrix}
* @return{spMatrix}
*/
function entrywisemulspMatrices (A, B) {
if ( A.rowmajor ) {
if ( B.rowmajor ) {
var val = new Array();
var cols = new Array();
var rows = new Uint32Array(A.m+1);
var ka;
var kb;
var i;
for ( i=0; i < A.m; i++) {
ka = A.rows[i];
kb = B.rows[i];
var ea = A.rows[i+1];
var eb = B.rows[i+1];
while ( ka < ea & kb < eb ){
var j = A.cols[ka];
while ( B.cols[kb] < j && kb < eb)
kb++;
if(B.cols[kb] == j) {
val.push(A.val[ka] * B.val[kb]);
cols.push(j);
rows[i+1]++;
}
ka++;
}
}
for(i=1; i < A.m; i++)
rows[i+1] += rows[i];
return new spMatrix(A.m, A.n, val, cols, rows);
}
else {
return entrywisemulspMatrixMatrix(B, fullMatrix(A)); // perhaps not the fastest
}
}
else {
if ( B.rowmajor ) {
return entrywisemulspMatrixMatrix(A, fullMatrix(B)); // perhaps not the fastest
}
else {
var val = new Array();
var cols = new Uint32Array(A.n+1);
var rows = new Array();
var ka;
var kb;
var j;
for ( j=0; j < A.n; j++) {
ka = A.cols[j];
kb = B.cols[j];
var ea = A.cols[j+1];
var eb = B.cols[j+1];
while ( ka < ea & kb < eb ){
var i = A.rows[ka];
while ( B.rows[kb] < i && kb < eb)
kb++;
if(B.rows[kb] == i) {
val.push(A.val[ka] * B.val[kb]);
rows.push(i);
cols[j+1]++;
}
ka++;
}
}
for ( j=1; j< A.n; j++)
cols[j+1] += cols[j];
return new spMatrix(A.m, A.n, val, cols, rows);
}
}
}
/**
* @param{spMatrix}
* @param{Matrix}
* @return{spMatrix}
*/
function entrywisemulspMatrixMatrix (A, B) {
var c = A.copy();
const nnz = A.val.length;
const n = A.n;
const m = A.m;
if ( A.rowmajor ) {
for ( i=0;i< m; i++) {
var s = c.rows[i];
var e = c.rows[i+1];
var r = i*n;
for ( var k = s; k< e; k++) {
c.val[k] *= B.val[r + c.cols[k] ];
}
}
}
else {
for ( j=0;j< n; j++) {
var s = c.cols[j];
var e = c.cols[j+1];
for ( var k = s; k< e; k++) {
c.val[k] *= B.val[c.rows[k] * n + j];
}
}
}
return c;
}
/**
* @param{number}
* @param{spVector}
* @return{Float64Array}
*/
function addScalarspVector (a, b) {
const nnzb = b.val.length;
const n = b.length;
var c = zeros(n);
var k;
for ( k=0;k < n; k++)
c[k] = a;
for ( k=0;k < nnzb; k++)
c[b.ind[k]] += b.val[k];
return c;
}
/**
* @param{Float64Array}
* @param{spVector}
* @return{Float64Array}
*/
function addVectorspVector (a, b) {
const nnzb = b.val.length;
const n = b.length;
var c = new Float64Array(a);
for (var k=0;k < nnzb; k++)
c[b.ind[k]] += b.val[k];
return c;
}
/**
* @param{spVector}
* @param{spVector}
* @return{spVector}
*/
function addspVectors (a, b) {
const nnza = a.val.length;
const nnzb = b.val.length;
var c = zeros(a.length);
var k;
for ( k=0;k < nnza; k++)
c[a.ind[k]] = a.val[k];
for ( k=0;k < nnzb; k++)
c[b.ind[k]] += b.val[k];
return sparseVector(c);
}
/**
* @param{number}
* @param{spMatrix}
* @return{Matrix}
*/
function addScalarspMatrix (a, B) {
const nnzb = B.val.length;
const m = B.m;
const n = B.n;
const mn = m*n;
var C = zeros(m,n);
var i;
for (i = 0; i < mn; i++)
C.val[i] = a;
if ( B.rowmajor ) {
var ri = 0;
for (i = 0; i < m; i++) {
var s = B.rows[i];
var e = B.rows[i+1];
for (var k= s; k < e; k++)
C.val[ri + B.cols[k]] += B.val[k];
ri += n;
}
}
else {
for (i = 0; i < n; i++) {
var s = B.cols[i];
var e = B.cols[i+1];
for (var k= s; k < e; k++)
C.val[B.rows[k] * n + i] += B.val[k];
}
}
return C;
}
/**
* @param{Matrix}
* @param{spMatrix}
* @return{Matrix}
*/
function addMatrixspMatrix (A, B) {
const nnzb = B.val.length;
const m = B.m;
const n = B.n;
const mn = m*n;
var C = matrixCopy(A);
var i;
if ( B.rowmajor ) {
var ri = 0;
for (i = 0; i < m; i++) {
var s = B.rows[i];
var e = B.rows[i+1];
for (var k= s; k < e; k++)
C.val[ri + B.cols[k]] += B.val[k];
ri += n;
}
}
else {
for (i = 0; i < n; i++) {
var s = B.cols[i];
var e = B.cols[i+1];
for (var k= s; k < e; k++)
C.val[B.rows[k] * n + i] += B.val[k];
}
}
return C;
}
/**
* @param{spMatrix}
* @param{spMatrix}
* @return{spMatrix}
*/
function addspMatrices (A, B) {
const nnza = A.val.length;
const nnzb = B.val.length;
const m = A.m;
const n = A.n;
var C = fullMatrix(A);
var i;
if ( B.rowmajor ) {
var ri = 0;
for (i = 0; i < m; i++) {
var s = B.rows[i];
var e = B.rows[i+1];
for (var k= s; k < e; k++)
C.val[ri + B.cols[k]] += B.val[k];
ri += n;
}
}
else {
for (i = 0; i < n; i++) {
var s = B.cols[i];
var e = B.cols[i+1];
for (var k= s; k < e; k++)
C.val[B.rows[k] * n + i] += B.val[k];
}
}
return sparseMatrixRowMajor(C);
}
/** sparse SAXPY : y = y + ax with x sparse and y dense
* @param {number}
* @param {spVector}
* @param {Float64Array}
*/
function spsaxpy ( a, x, y) {
const nnz = x.val.length;
for (var k=0;k < nnz; k++)
y[x.ind[k]] += a * x.val[k];
}
/**
* @param{number}
* @param{spVector}
* @return{Float64Array}
*/
function subScalarspVector (a, b) {
const nnzb = b.val.length;
const n = b.length;
var c = zeros(n);
var k;
for ( k=0;k < n; k++)
c[k] = a;
for ( k=0;k < nnzb; k++)
c[b.ind[k]] -= b.val[k];
return c;
}
/**
* @param{Float64Array}
* @param{spVector}
* @return{Float64Array}
*/
function subVectorspVector (a, b) {
const nnzb = b.val.length;
const n = b.length;
var c = new Float64Array(a);
for (var k=0;k < nnzb; k++)
c[b.ind[k]] -= b.val[k];
return c;
}
/**
* @param{spVector}
* @param{Float64Array}
* @return{Float64Array}
*/
function subspVectorVector (a, b) {
return subVectors(fullVector(a), b);
}
/**
* @param{spVector}
* @param{spVector}
* @return{spVector}
*/
function subspVectors (a, b) {
const nnza = a.val.length;
const nnzb = b.val.length;
var c = zeros(a.length);
var k;
for ( k=0;k < nnza; k++)
c[a.ind[k]] = a.val[k];
for ( k=0;k < nnzb; k++)
c[b.ind[k]] -= b.val[k];
return sparseVector(c);
}
/**
* @param{number}
* @param{spMatrix}
* @return{Matrix}
*/
function subScalarspMatrix (a, B) {
const nnzb = B.val.length;
const m = B.m;
const n = B.n;
const mn = m*n;
var C = zeros(m,n);
var i;
for (i = 0; i < mn; i++)
C.val[i] = a;
if ( B.rowmajor ) {
var ri = 0;
for (i = 0; i < m; i++) {
var s = B.rows[i];
var e = B.rows[i+1];
for (var k= s; k < e; k++)
C.val[ri + B.cols[k]] -= B.val[k];
ri += n;
}
}
else {
for (i = 0; i < n; i++) {
var s = B.cols[i];
var e = B.cols[i+1];
for (var k= s; k < e; k++)
C.val[B.rows[k] * n + i] -= B.val[k];
}
}
return C;
}
/**
* @param{spMatrix}
* @param{Matrix}
* @return{Matrix}
*/
function subspMatrixMatrix (A, B) {
return subMatrices(fullMatrix(A), B);
}
/**
* @param{Matrix}
* @param{spMatrix}
* @return{Matrix}
*/
function subMatrixspMatrix (A, B) {
const nnzb = B.val.length;
const m = B.m;
const n = B.n;
const mn = m*n;
var C = matrixCopy(A);
var i;
if ( B.rowmajor ) {
var ri = 0;
for (i = 0; i < m; i++) {
var s = B.rows[i];
var e = B.rows[i+1];
for (var k= s; k < e; k++)
C.val[ri + B.cols[k]] -= B.val[k];
ri += n;
}
}
else {
for (i = 0; i < n; i++) {
var s = B.cols[i];
var e = B.cols[i+1];
for (var k= s; k < e; k++)
C.val[B.rows[k] * n + i] -= B.val[k];
}
}
return C;
}
/**
* @param{spMatrix}
* @param{spMatrix}
* @return{spMatrix}
*/
function subspMatrices (A, B) {
const nnza = A.val.length;
const nnzb = B.val.length;
const m = A.m;
const n = A.n;
var C = fullMatrix(A);
var i;
if ( B.rowmajor ) {
var ri = 0;
for (i = 0; i < m; i++) {
var s = B.rows[i];
var e = B.rows[i+1];
for (var k= s; k < e; k++)
C.val[ri + B.cols[k]] -= B.val[k];
ri += n;
}
}
else {
for (i = 0; i < n; i++) {
var s = B.cols[i];
var e = B.cols[i+1];
for (var k= s; k < e; k++)
C.val[B.rows[k] * n + i] -= B.val[k];
}
}
return sparseMatrixRowMajor(C);
}
/**
* @param{function}
* @param{spVector}
* @return{Float64Array}
*/
function applyspVector( f, x ) {
const nnz = x.val.length;
const n = x.length;
var res = new Float64Array(n);
var i;
const f0 = f(0);
for ( i=0; i< n; i++)
res[i] = f0;
for ( i=0; i< nnz; i++)
res[x.ind[i]] = f(x.val[i]);
return res;
}
/**
* @param{function}
* @param{spMatrix}
* @return{Matrix}
*/
function applyspMatrix( f, X ) {
const nnz = X.val.length;
const m = X.m;
const n = X.n;
const mn = m*n;
const f0 = f(0);
var C = zeros(m,n);
var i;
if ( !isZero(f0) ) {
for (i = 0; i < mn; i++)
C.val[i] = f0;
}
if ( X.rowmajor ) {
var ri = 0;
for (i = 0; i < m; i++) {
var s = X.rows[i];
var e = X.rows[i+1];
for (var k= s; k < e; k++)
C.val[ri + X.cols[k]] = f(X.val[k]);
ri += n;
}
}
else {
for (i = 0; i < n; i++) {
var s = X.cols[i];
var e = X.cols[i+1];
for (var k= s; k < e; k++)
C.val[X.rows[k] * n + i] += f(X.val[k]);
}
}
return C;
}
/**
* @param{spVector}
* @return{number}
*/
function sumspVector( a ) {
return sumVector(a.val);
}
/**
* @param{spMatrix}
* @return{number}
*/
function sumspMatrix( A ) {
return sumVector(A.val);
}
/**
* @param{spMatrix}
* @return{Matrix}
*/
function sumspMatrixRows( A ) {
var res = zeros(A.n);
if ( A.rowmajor ) {
for ( var k=0; k < A.val.length; k++)
res[A.cols[k]] += A.val[k];
}
else {
for ( var i=0; i<A.n; i++)
res[i] = sumspVector(A.col(i));
}
return new Matrix(1,A.n, res, true);
}
/**
* @param{spMatrix}
* @return{Float64Array}
*/
function sumspMatrixCols( A ) {
var res = zeros(A.m);
if ( A.rowmajor ) {
for ( var i=0; i<A.m; i++)
res[i] = sumspVector(A.row(i));
}
else {
for ( var k=0; k < A.val.length; k++)
res[A.rows[k]] += A.val[k];
}
return res;
}
/**
* @param{spMatrix}
* @return{Matrix}
*/
function prodspMatrixRows( A ) {
if ( A.rowmajor ) {
var res = ones(A.n);
for ( var i=0; i < A.m; i++) {
var s = A.rows[i];
var e = A.rows[i+1];
for ( var j=0; j < A.n; j++)
if ( A.cols.subarray(s,e).indexOf(j) < 0 )
res[j] = 0;
for ( var k=s; k < e; k++)
res[A.cols[k]] *= A.val[k];
}
}
else {
var res = zeros(A.n);
for ( var i=0; i<A.n; i++) {
var a = A.col(i);
if ( a.val.length == a.length )
res[i] = prodVector(a.val);
}
}
return new Matrix(1,A.n, res, true);
}
/**
* @param{spMatrix}
* @return{Float64Array}
*/
function prodspMatrixCols( A ) {
if ( A.rowmajor ) {
var res = zeros(A.m);
for ( var i=0; i<A.m; i++) {
var a = A.row(i);
if ( a.val.length == a.length )
res[i] = prodVector(a.val);
}
}
else {
var res = ones(A.m);
for ( var j=0; j < A.n; j++) {
var s = A.cols[j];
var e = A.cols[j+1];
for ( var i=0; i < A.m; i++)
if ( A.rows.subarray(s,e).indexOf(i) < 0 )
res[i] = 0;
for ( var k=s; k < e; k++)
res[A.rows[k]] *= A.val[k];
}
}
return res;
}
///////////////////////////
/// Sparse linear systems
///////////////////////////
/** Sparse Conjugate gradient method for solving the symmetric positie definite system Ax = b
* @param{spMatrix}
* @param{Float64Array}
* @return{Float64Array}
*/
function spsolvecg ( A, b) {
const n = A.n;
const m = A.m;
var x = randn(n);
var r = subVectors(b, mulspMatrixVector(A, x));
var rhoc = dot(r,r);
const TOL = 1e-8;
var delta2 = TOL * norm(b);
delta2 *= delta2;
// first iteration:
var p = vectorCopy(r);
var w = mulspMatrixVector(A,p);
var mu = rhoc / dot(p, w);
saxpy( mu, p, x);
saxpy( -mu, w, r);
var rho_ = rhoc;
rhoc = dot(r,r);
var k = 1;
var updateP = function (tau, r) {
for ( var i=0; i < m; i++)
p[i] = r[i] + tau * p[i];
}
while ( rhoc > delta2 && k < n ) {
updateP(rhoc/rho_, r);
w = mulspMatrixVector(A,p);
mu = rhoc / dot(p, w);
saxpy( mu, p, x);
saxpy( -mu, w, r);
rho_ = rhoc;
rhoc = dot(r,r);
k++;
}
return x;
}
/** Sparse Conjugate gradient normal equation residual method for solving the rectangular system Ax = b
* @param{spMatrix}
* @param{Float64Array}
* @return{Float64Array}
*/
function spcgnr ( A, b) {
/*
TEST
A = randnsparse(0.3,10000,1000)
x = randn(1000)
b = A*x + 0.01*randn(10000)
tic()
xx = cgnr(A,b)
t1 = toc()
ee = norm(A*xx - b)
tic()
xh=spcgnr(sparse(A), b)
t2 = toc()
e = norm(A*xh - b)
*/
const n = A.n;
const m = A.m;
var x = randn(n);
var r = subVectors(b, mulspMatrixVector(A, x));
const TOL = 1e-8;
var delta2 = TOL * norm(b);
delta2 *= delta2;
// first iteration:
var z = mulspMatrixTransVector(A, r);
var rhoc = dot(z,z);
var p = vectorCopy(z);
var w = mulspMatrixVector(A,p);
var mu = rhoc / dot(w, w);
saxpy( mu, p, x);
saxpy( -mu, w, r);
z = mulspMatrixTransVector(A, r);
var rho_ = rhoc;
rhoc = dot(z,z);
var k = 1;
var updateP = function (tau, z) {
for ( var i=0; i < m; i++)
p[i] = z[i] + tau * p[i];
}
while ( rhoc > delta2 && k < n ) {
updateP(rhoc/rho_, z);
w = mulspMatrixVector(A,p);
mu = rhoc / dot(w, w);
saxpy( mu, p, x);
saxpy( -mu, w, r);
z = mulspMatrixTransVector(A, r);
rho_ = rhoc;
rhoc = dot(z,z);
k++;
}
return x;
}
/* glpk.js is now included (cat) in lalolib.js
if ( self.hasOwnProperty("window") ) {
// in main window
}
else {
// in worker
importScripts("glpk.js");
//importScripts("glpk.min.js");
}*/
// Install glpk as lp function:
if ( typeof(lp) == "undefined" ) {
lp = glp;
linprog = glp;
}
function glp (c, A, b, Aeq, beq, lb , ub, integer_variables, verbose) {
/*
Call GLPK to solve
min c' x s.t. Ax<= b, Aeq = beq, lb<= x <= ub, x[integer_variables] in Z
*/
/* TESTS:
Aineq = [[1, 1]; [-1,1]]
Bineq = [2; 1]
costineq = [-1; -2]
lb = [0;0]
xsol = glp(costineq, Aineq, Bineq, [], [], lb)
A = [[3,2,1,1,0],[2,5,3,0,1]]
b=[10,15]
c=[-2,-3,-4,0,0]
lb = zeros(5)
xsol = glp(c, [],[],A, b,lb,[])
*/
var prob = glp_create_prob();
glp_set_obj_dir ( prob, GLP_MIN ) ;
if ( typeof(Aeq) == "undefined" )
var Aeq = [];
glp_add_cols(prob, c.length);
if ( A.length + Aeq.length > 0 )
glp_add_rows(prob, A.length + Aeq.length);
var i;
var j;
var indexes ;
var values;
var n = c.length;
if ( lb ) {
var lbdense = vectorCopy(lb);
for ( i=0; i < lbdense.length; i++){
if ( !isFinite( lbdense[i] ) )
lbdense[i] = NaN;
}
}
else
var lbdense = [];
if ( ub ) {
var ubdense = vectorCopy(ub);
for ( i=0; i < ubdense.length; i++){
if ( !isFinite( ubdense[i] ) )
lbdense[i] = NaN;
}
}
else
var ubdense = [];
for ( i=0; i < c.length; i++) {
// variable bounds
var lbi = NaN;
var ubi = NaN;
if ( lbdense.length > 0)
lbi = lbdense[i];
if ( ubdense.length > 0 )
ubi = ubdense[i] ;
if ( !isNaN(lbi) && !isNaN(ubi))
glp_set_col_bnds( prob, i+1, GLP_DB, lbi , ubi );
else if ( !isNaN(lbi) )
glp_set_col_bnds( prob, i+1, GLP_LO, lbi );
else if ( !isNaN(ubi) )
glp_set_col_bnds( prob, i+1, GLP_UP, 0, ubi );
else
glp_set_col_bnds( prob, i+1, GLP_FR );
// cost
glp_set_obj_coef ( prob, i+1, c[i] );
}
// Integer variables
if ( integer_variables ) {
for ( i=0; i< integer_variables.length ; i++)
glp_set_col_kind(prob, integer_variables[i]+1, GLP_IV );
}
// inequalities
if ( A.length == 1 && typeof(b) == "number")
b = [b];
for ( i=0; i<A.length; i++) {
// RHS
glp_set_row_bnds(prob, i+1, GLP_UP, 0, b[i] ); // pass lb=0 otherwise ub undefined!!
// LHS
indexes = new Array();
values = new Array();
indexes.push(0); // to make it start at 1
values.push(0);
for ( j = 0; j < n; j++ ) {
if ( !isZero(A.val[i*n+j] )) {
indexes.push(j+1);
values.push( A.val[i*n+j] );
}
}
glp_set_mat_row( prob, i+1, indexes.length -1, indexes, values) ;
}
// equality constraints
if ( Aeq.length == 1 && typeof(beq) == "number")
beq = [beq];
for ( i=0; i<Aeq.length; i++) {
// RHS
glp_set_row_bnds(prob, A.length+i+1, GLP_FX, beq[i] );
// LHS
indexes = new Array();
values = new Array();
indexes.push(0); // to make it start at 1
values.push(0);
for ( j = 0; j < n; j++ ) {
if ( !isZero(Aeq.val[i*n+j] )) {
indexes.push(j+1);
values.push( Aeq.val[i*n+j] );
}
}
glp_set_mat_row( prob,A.length+ i+1, indexes.length -1, indexes, values) ;
}
//glp_write_lp(prob, undefined, function (str) {console.log(str);});
var rc;
if ( integer_variables && integer_variables.length > 0) {
// Solve with MILP solver
var iocp = new IOCP({presolve: GLP_ON});
glp_scale_prob(prob, GLP_SF_AUTO);
rc = glp_intopt(prob, iocp);
// get solution
if ( rc == 0 ) {
var sol = zeros(n);
for ( i=0; i<n; i++) {
sol[i] = glp_mip_col_val( prob, i+1);
}
if ( verbose) {
var obj = glp_mip_obj_val(prob);
console.log("Status : " + glp_mip_status(prob) );
console.log("Obj : " + obj);
}
return sol;
}
else
return "Status : " + glp_get_prim_stat(prob);
}
else {
// Parameters
var smcp = new SMCP({presolve: GLP_ON});
// Solve with Simplex
glp_scale_prob(prob, GLP_SF_AUTO);
rc = glp_simplex(prob, smcp);
// get solution
if ( rc == 0 ) {
var sol = zeros(n);
for ( i=0; i<n; i++) {
sol[i] = glp_get_col_prim( prob, i+1);
}
if ( verbose) {
var obj = glp_get_obj_val(prob);
console.log("Status : " + glp_get_status(prob) + "(OPT=" + GLP_OPT + ",FEAS=" + GLP_FEAS + ",INFEAS=" + GLP_INFEAS + ",NOFEAS=" + GLP_NOFEAS + ",UNBND=" + GLP_UNBND + ",UNDEF=" + GLP_UNDEF + ")" );
console.log("Obj : " + obj);
}
return sol;
}
else {
GLPLASTLP = "";
glp_write_lp(prob, undefined, function (str) {GLPLASTLP += str + "<br>";});
return "RC=" + rc + " ; Status : " + glp_get_status(prob) + "(OPT=" + GLP_OPT + ",FEAS=" + GLP_FEAS + ",INFEAS=" + GLP_INFEAS + ",NOFEAS=" + GLP_NOFEAS + ",UNBND=" + GLP_UNBND + ",UNDEF=" + GLP_UNDEF + ")" ;
}
}
}
///////////////////////////////:
/////// L1-minimization and sparse recovery //////////
///////////
function minl1 ( A, b) {
/*
Solves min ||x||_1 s.t. Ax = b
as
min sum a_i s.t. -a <= x <= a and Ax = b
example:
A = randn(10,20)
r = zeros(20)
r[0:3] = randn(3)
x=minl1(A,A*r)
*/
const n = A.n;
var Aineq = zeros ( 2*n, 2*n ) ;
var i;
//set ( Aineq, range(0,n),range(0,n) , I) ;
//set ( Aineq, range(0,n),range(n,2*n) , I_) ;
//set ( Aineq, range(n,2*n),range(0,n) , I_) ;
//set ( Aineq, range(n,2*n),range(n,2*n) , I_) ;
for ( i=0; i < n; i++) {
Aineq.val[i*Aineq.n + i] = 1;
Aineq.val[i*Aineq.n + n+i] = -1;
Aineq.val[(n+i)*Aineq.n + i] = -1;
Aineq.val[(n+i)*Aineq.n + n+i] = -1;
}
var bineq = zeros ( 2*n);
var Aeq = zeros(A.length, 2*n);
set ( Aeq , [], range( 0,n), A );
var cost = zeros(2*n);
set ( cost, range(n,2*n), ones(n) );
var lb = zeros(2*n); // better to constraint a>=0
set ( lb, range(n), mulScalarVector(-Infinity , ones( n )) ) ;
//console.log( cost, Aineq, bineq, Aeq, b, lb);
// var lpsol = lp( cost, Aineq, bineq, Aeq, b, lb, [], 0 , 1e-6 );
var lpsol = glp( cost, Aineq, bineq, Aeq, b, lb);
return get(lpsol, range(n) );
}
function minl0 ( A, b, M) {
/*
Solves min ||x||_0 s.t. Ax = b -M <= x <= M
as a mixed integer linear program
min sum a_i s.t. -M a <= x <= M a , Ax = b and a_i in {0,1}
example:
A = randn(10,20)
r = zeros(20)
r[0:3] = randn(3)
x=minl0(A,A*r)
*/
if ( typeof(M) == "undefined" )
var M = 10;
var n = A.n;
var Aineq = zeros ( 2*n, 2*n ) ;
//set ( Aineq, range(0,n),range(0,n) , I) ;
//set ( Aineq, range(0,n),range(n,2*n) , mul(M, I_) ) ;
//set ( Aineq, range(n,2*n),range(0,n) , I_) ;
//set ( Aineq, range(n,2*n),range(n,2*n) ,mul(M, I_) ) ;
var i;
for ( i=0; i < n; i++) {
Aineq.val[i*Aineq.n + i] = 1;
Aineq.val[i*Aineq.n + n+i] = -M;
Aineq.val[(n+i)*Aineq.n + i] = -1;
Aineq.val[(n+i)*Aineq.n + n+i] = -M;
}
var bineq = zeros ( 2*n);
var Aeq = zeros(A.length, 2*n);
set ( Aeq , [], range( 0,n), A );
var cost = zeros(2*n);
set ( cost, range(n,2*n), ones(n) );
var lb = zeros(2*n); // better to constraint a>=0
set ( lb, range(n), mulScalarVector(-M , ones( n )) ) ;
var ub = ones(2*n) ;
set(ub, range(n), mulScalarVector(M, ones(n) ) );
var lpsol = glp( cost, Aineq, bineq, Aeq, b, lb, ub, range(n,2*n) ); // glptweak??
// set to 0 the x corresponding to 0 binary variables:
var x = entrywisemulVector( getSubVector(lpsol, range(n) ), getSubVector(lpsol, range(n,2*n) ) );
return x;
}
///////////////////////////////////////////
/// Quadratic Programming
////////////////
quadprog = qp;
function qp(Q,c,A,b,Aeq,beq,lb,ub,x0, epsilon) {
// Solve quad prog by Frank-Wolfe algorithm
/*
min 0.5 x' * Q * x c' * x
s.t. Ax <= b and lu <= x <= ub
NOTE: all variables should be bounded or constrained,
otherwise the LP might be unbounded even if the QP is well-posed
*/
if (typeof(epsilon) === 'undefined')
var epsilon = 1e-3;
var normdiff;
var normgrad;
var grad;
var y;
var gamma;
var direction;
var x;
if ( typeof(x0) === 'undefined' ) {
//console.log ("providing an initial x0 might be better for qp.");
x = glp(zeros(c.length),A, b, Aeq, beq, lb, ub, [], false) ;
if ( typeof(x) == "string")
return "infeasible";
}
else {
x = vectorCopy(x0);
}
var iter = 0;
do {
// Compute gradient : grad = Qx + c
grad = add( mul( Q, x) , c );
normgrad = norm(grad);
// Find direction of desecnt : direction = argmin_y y'*grad s.t. same constraints as QP
y = glp(grad, A, b, Aeq, beq, lb, ub, [], false) ;
/* if ( typeof(y) == "string")
return x; // error return current solution;
*/
// Step size: gamma = -(y - x)' [ Qx + c] / (y-x)'Q(y-x) = numerator / denominator
direction = sub (y, x);
numerator = - mul(direction, grad);
denominator = mul(direction, mul(Q, direction) );
if ( Math.abs(denominator) > 1e-8 && denominator > 0)
gamma = numerator / denominator;
else
gamma = 0;
if ( gamma > 1 )
gamma = 1;
// Update x <- x + gamma * direction
if ( gamma > 0 ) {
x = add(x, mul(gamma, direction) );
normdiff = gamma * norm(direction) ;
}
else
normdiff = 0;
iter++;
} while ( normdiff > epsilon && normgrad > epsilon && iter < 10000) ;
return x;
}
/////////////////////////////////////////:
//// Unconstrained Minimization
/////////////////////////////////////////
function minimize( f, grad, x0 ) {
/*
function loss(x) {
return (norm(b - A*x)^2)
}
function grad(x) {
return (2*A'*A*x - 2*A'*b)
}
x = randn(10)
A = randn(100,10)
b = A*x + 0.01*randn(100)
xh = minimize(A.n, loss, grad)
norm(x - xh)
*/
var x;
var n = 1; // dimension of x
if ( arguments.length == 3 ) {
if ( typeof(x0) == "number" ) {
if( x0 > 0 && Math.floor(x0) == x0 ) {
n = x0;
x = sub(mul(20,rand(n)), 10);
}
else {
n = 1;
x = x0;
}
}
else {
n = x0.length;
x = x0;
}
}
else {
n = 1;
x = 20 * Math.random() - 10;
}
if ( n == 1 )
return secant(f, grad, x);
else if ( n > 500 )
return steepestdescent(f, grad, x);
else
return bfgs(f, grad, x);
}
function secant( f, grad, x0 ) {
// for a unidimensional function f
// find a root to f'(x) = 0 with the secant method
const TOLx = 1e-6;
var x = x0;
var g = grad(x);
var dx = -0.01*g;
x += dx;
var gprev,dg;
do {
gprev = g;
g = grad(x);
dg = g-gprev;
dx *= -g / dg;
x += dx;
} while ( Math.abs(dx) > TOLx);
return x;
}
function steepestdescent(f, grad, x0) {
// assume x is a vector
const TOLobj = 1e-8;
const TOLx = 1e-6;
const TOLgrad = 1e-4;
var x = x0;
var xprev;
var obj = f(x);
var g = grad(x);
var normg = norm(g);
var iter = 0;
do {
// line search
var linesearch = armijo(f, x, obj, g, normg);
// take the step
xprev = vectorCopy(x);
prevobj = obj;
x = linesearch.x;
obj = linesearch.obj;
g = grad(x);
normg = norm(g);
iter++;
//console.log(linesearch.lambda, x, obj, g);
} while ( normg > TOLgrad && prevobj - obj > TOLobj && norm(subVectors(x, xprev) ) > TOLx ) ;
console.log(" OBJ: " + obj + ", norm(grad): " + normg, "prevobj - obj", prevobj - obj, "iter: ", iter );
return x;
}
function bfgs( f, grad, x0 ) {
// assume x is a vector
const n = x0.length;
const TOLobj = 1e-8;
const TOLx = 1e-6;
const TOLgrad = 1e-4;
var x = x0;
var xprev;
var obj = f(x);
var H = eye(n);
var g,direction, delta, gamma, ls;
var normg;
var Hgamma;
var dH;
var iter = 0;
do {
g = grad(x);
normg = norm(g);
direction = minusVector( mulMatrixVector(H, g ) );
// line search
var linesearch = armijodir (f, x, obj, g, direction );
// take the step
xprev = vectorCopy(x);
prevobj = obj;
x = linesearch.x;
obj = linesearch.obj;
// update Hessian inverse approximation
delta = subVectors(x,xprev);
gamma = subVectors(grad(x) , g);
Hgamma = mulMatrixVector(H, gamma);
var deltagamma = dot(delta,gamma);
var delta_ = mulScalarVector(1/deltagamma, delta);
var deltagammaH = outerprodVectors(delta_, Hgamma);
dH = subMatrices(outerprodVectors(delta_, delta, 1+ dot(gamma, Hgamma)/deltagamma) , addMatrices(deltagammaH, transposeMatrix(deltagammaH) ) );
//--
H = add(H, dH);
iter++;
} while ( normg > TOLgrad && prevobj - obj > TOLobj && norm(subVectors(x, xprev) ) > TOLx ) ;
console.log(" OBJ: " + obj + ", norm(grad): " + normg, "prevobj - obj", prevobj - obj, "iters: ", iter );
return x;
}
/**
* Return minimizer of p(x) = p0 + p1 x + p2 x^2 + p3 x^3 with p(x1) = px1, p(x2) = px2
* within [lb, ub]
*
* @param {number}
* @param {number}
* @param {number}
* @param {number}
* @param {number}
* @param {number}
* @param {number}
* @param {number}
* @return {number}
*/
function mincubic(p0, p1, x1, px1, x2, px2, lb, ub) {
const x1square = x1*x1;
const x2square = x2*x2;
var A = new Matrix(2,2, [x1square, x1*x1square, x2square, x2*x2square]);
var b = new Float64Array([px1 - p0 - p1*x1, px2 - p0 - p1*x2]);
var c = solve(A,b);
var x = (-c[0] + Math.sqrt(c[0]*c[0] - 3 *c[1] * p1))/(3*c[1]);
return Math.min(ub, Math.max(lb, x));
}
/**
* Return minimizer of p(x) = p0 + p1 x + p2 x^2 with p(x1) = px1 (x1 ~ 1)
* within [lb, ub]
*
* @param {number}
* @param {number}
* @param {number}
* @param {number}
* @param {number}
* @param {number}
* @return {number}
*/
function minquadratic(p0, p1, px1, x1, lb, ub) {
var x = - p1/(2 * x1 * (px1 - p0 - p1) );
return Math.min(ub, Math.max(lb, x));
}
/**
* Armijo line search with objective function f
* and starting point xc, fc, g
*
* @param {function}
* @param {{Float64Array|number}}
* @param {number}
* @param {{Float64Array|number}}
* @param {number}
* @return {{Float64Array|number}}
*/
function armijo (f, xc, fc, g, normg ) {
// Armijo's rule line search in the direction of gradient g
const alpha = 0.0001;
const blow = 0.1;
const bhigh = 0.5;
const normg2 = normg * normg;
var lambda = Math.min(1,100/(1+normg));
var fgoal = fc - alpha * lambda * normg2;
var lambda1 = lambda;
var xt = subVectors(xc, mulScalarVector(lambda, g) );
var ft_1 = fc;
var ft = f(xt);
var iter = 1;
// first iter
lambda = minquadratic(fc, -normg2, lambda1, ft, blow*lambda1, bhigh*lambda1);
var ft_1 = ft;
var lambda2 = lambda1;
lambda1 = lambda;
iter++;
// next iterations
while(ft > fgoal && iter <= 10) {
lambda = mincubic(fc, -normg2, lambda1, ft, lambda2, ft_1, blow*lambda1, bhigh*lambda1);
lambda2 = lambda1;
lambda1 = lambda;
xt = subVectors(xc, mulScalarVector(lambda, g) );
ft_1 = ft;
ft = f(xt);
fgoal = fc - alpha * lambda * normg2;
iter++;
}
return {"lambda": lambda, "x": xt, "obj": ft};
}
function armijodir (f, xc, fc, g, d ) {
// Armijo's rule line search in the direction d
const alpha = 0.0001;
const blow = 0.1;
const bhigh = 0.5;
const p1 = dot( g, d);
var lambda = Math.min(1,100/(1+norm(g)));
var fgoal = fc + alpha * lambda * p1;
var lambda1 = lambda;
var xt = addVectors(xc, mulScalarVector(lambda, d) );
var ft_1 = fc;
var ft = f(xt);
var iter = 1;
// first iter
lambda = minquadratic(fc, p1, lambda1, ft, blow*lambda1, bhigh*lambda1);
var ft_1 = ft;
var lambda2 = lambda1;
lambda1 = lambda;
iter++;
// next iterations
while(ft > fgoal && iter <= 10) {
lambda=mincubic(fc, p1, lambda1, ft, lambda2, ft_1, blow*lambda1, bhigh*lambda1 );
lambda2 = lambda1;
lambda1 = lambda;
xt = addVectors(xc, mulScalarVector(lambda, d) );
ft_1 = ft;
ft = f(xt);
fgoal = fc + alpha * lambda * p1;
iter++;
}
return {"lambda": lambda, "x": xt, "obj": ft};
}
/*! glpk.js - v4.49.0
* https://github.com/hgourvest/glpk.js
* Copyright (c) 2013 Henri Gourvest; Licensed GPLv2 */
(function(exports) {
var s=Number.MAX_VALUE,aa=Number.MIN_VALUE;function w(a){throw Error(a);}function x(){}exports.glp_get_print_func=function(){return x};exports.glp_set_print_func=function(a){x=a};function da(a,b){for(var c in b)a[c]=b[c]}function ga(a,b,c,d,e){for(;0<e;b++,d++,e--)a[b]=c[d]}function ha(a,b,c,d){for(;0<d;b++,d--)a[b]=c}function ia(a,b,c){for(;0<c;b++,c--)a[b]={}}function ja(){return(new Date).getTime()}function la(a){return(ja()-a)/1E3}
function ma(a,b,c){var d=Array(b);ga(d,0,a,1,b);d.sort(c);ga(a,1,d,0,b)}var na={},ra=exports.glp_version=function(){return pa+"."+qa};function ta(a){a="string"==typeof a?a.charCodeAt(0):-1;return 0<=a&&31>=a||127==a}function ua(a){a="string"==typeof a?a.charCodeAt(0):-1;return 65<=a&&90>=a||97<=a&&122>=a}function va(a){a="string"==typeof a?a.charCodeAt(0):-1;return 65<=a&&90>=a||97<=a&&122>=a||48<=a&&57>=a}function wa(a){a="string"==typeof a?a.charCodeAt(0):-1;return 48<=a&&57>=a}
function xa(){function a(a,d,e,k,l,p,m){a>>>=0;e=e&&a&&{2:"0b",8:"0",16:"0x"}[d]||"";a=e+c(a.toString(d),p||0,"0",!1);return b(a,e,k,l,m)}function b(a,b,d,e,l,p){var m=e-a.length;0<m&&(a=d||!l?c(a,e,p,d):a.slice(0,b.length)+c("",m,"0",!0)+a.slice(b.length));return a}function c(a,b,c,d){c||(c=" ");b=a.length>=b?"":Array(1+b-a.length>>>0).join(c);return d?a+b:b+a}var d=arguments,e=0;return d[e++].replace(/%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuideEfFgG])/g,function(f,
g,h,k,l,p,m){var q,r;if("%%"==f)return"%";var n=!1;r="";var t=l=!1;q=" ";for(var y=h.length,E=0;h&&E<y;E++)switch(h.charAt(E)){case " ":r=" ";break;case "+":r="+";break;case "-":n=!0;break;case "'":q=h.charAt(E+1);break;case "0":l=!0;break;case "#":t=!0}k=k?"*"==k?+d[e++]:"*"==k.charAt(0)?+d[k.slice(1,-1)]:+k:0;0>k&&(k=-k,n=!0);if(!isFinite(k))throw Error("sprintf: (minimum-)width must be finite");p=p?"*"==p?+d[e++]:"*"==p.charAt(0)?+d[p.slice(1,-1)]:+p:-1<"fFeE".indexOf(m)?6:"d"==m?0:void 0;g=g?
d[g.slice(0,-1)]:d[e++];switch(m){case "s":return m=String(g),null!=p&&(m=m.slice(0,p)),b(m,"",n,k,l,q);case "c":return m=String.fromCharCode(+g),null!=p&&(m=m.slice(0,p)),b(m,"",n,k,l,void 0);case "b":return a(g,2,t,n,k,p,l);case "o":return a(g,8,t,n,k,p,l);case "x":return a(g,16,t,n,k,p,l);case "X":return a(g,16,t,n,k,p,l).toUpperCase();case "u":return a(g,10,t,n,k,p,l);case "i":case "d":return q=+g||0,q=Math.round(q-q%1),f=0>q?"-":r,g=f+c(String(Math.abs(q)),p,"0",!1),b(g,f,n,k,l);case "e":case "E":case "f":case "F":case "g":case "G":return q=
+g,f=0>q?"-":r,r=["toExponential","toFixed","toPrecision"]["efg".indexOf(m.toLowerCase())],m=["toString","toUpperCase"]["eEfFgG".indexOf(m)%2],g=f+Math.abs(q)[r](p),b(g,f,n,k,l)[m]();default:return f}})}function ya(a){a.Dd=3621377730;a.ke=null;a.V=null;a.name=null;a.eb=null;a.dir=za;a.ha=0;a.hb=100;a.K=200;a.g=a.i=0;a.L=0;a.n=Array(1+a.hb);a.f=Array(1+a.K);a.fc={};a.Lc={};a.valid=0;a.head=new Int32Array(1+a.hb);a.Qd=null;a.U=null;a.na=a.sa=Aa;a.aa=0;a.$=0;a.some=0;a.df=Aa;a.ae=0;a.za=Aa;a.ta=0}
var Ba=exports.glp_create_prob=function(){var a={};ya(a);return a},Ca=exports.glp_set_prob_name=function(a,b){var c=a.V;null!=c&&0!=c.reason&&w("glp_set_prob_name: operation not allowed");a.name=b},Da=exports.glp_set_obj_name=function(a,b){var c=a.V;null!=c&&0!=c.reason&&w("glp_set_obj_name: operation not allowed");a.eb=b},Fa=exports.glp_set_obj_dir=function(a,b){var c=a.V;null!=c&&0!=c.reason&&w("glp_set_obj_dir: operation not allowed");b!=za&&b!=Ea&&w("glp_set_obj_dir: dir = "+b+"; invalid direction flag");
a.dir=b},La=exports.glp_add_rows=function(a,b){var c=a.V,d;1>b&&w("glp_add_rows: nrs = "+b+"; invalid number of rows");b>1E8-a.g&&w("glp_add_rows: nrs = "+b+"; too many rows");var e=a.g+b;if(a.hb<e){for(;a.hb<e;)a.hb+=a.hb;a.n.length=1+a.hb;a.head=new Int32Array(1+a.hb)}for(var f=a.g+1;f<=e;f++){a.n[f]=d={};d.ea=f;d.name=null;d.rb=null;d.La=0;d.origin=0;d.qc=0;if(null!=c)switch(c.reason){case Ga:d.La=c.N.La;d.origin=Ha;break;case Ia:d.La=c.N.La,d.origin=Ja}d.type=Ka;d.c=d.d=0;d.k=null;d.ma=1;d.m=
A;d.bind=0;d.r=d.J=0;d.dc=d.mc=0;d.Sa=0}a.g=e;a.valid=0;null!=c&&0!=c.reason&&(c.pe=1);return e-b+1},Oa=exports.glp_add_cols=function(a,b){var c=a.V;null!=c&&0!=c.reason&&w("glp_add_cols: operation not allowed");1>b&&w("glp_add_cols: ncs = "+b+"; invalid number of columns");b>1E8-a.i&&w("glp_add_cols: ncs = "+b+"; too many columns");var d=a.i+b;if(a.K<d){for(;a.K<d;)a.K+=a.K;a.f.length=1+a.K}for(var e=a.i+1;e<=d;e++)a.f[e]=c={},c.C=e,c.name=null,c.rb=null,c.kind=Ma,c.type=B,c.c=c.d=0,c.u=0,c.k=null,
c.va=1,c.m=Na,c.bind=0,c.r=c.J=0,c.dc=c.mc=0,c.Sa=0;a.i=d;return d-b+1},Pa=exports.glp_set_row_name=function(a,b,c){1<=b&&b<=a.g||w("glp_set_row_name: i = "+b+"; row number out of range");b=a.n[b];null!=b.name&&(delete a.fc[b.name],b.name=null);null!=c&&(b.name=c,a.fc[b.name]=b)},Qa=exports.glp_set_col_name=function(a,b,c){var d=a.V;null!=d&&0!=d.reason&&w("glp_set_col_name: operation not allowed");1<=b&&b<=a.i||w("glp_set_col_name: j = "+b+"; column number out of range");b=a.f[b];null!=b.name&&(delete a.Lc[b.name],
b.name=null);null!=c&&(b.name=c,a.Lc[b.name]=b)},Va=exports.glp_set_row_bnds=function(a,b,c,d,e){1<=b&&b<=a.g||w("glp_set_row_bnds: i = "+b+"; row number out of range");a=a.n[b];a.type=c;switch(c){case Ka:a.c=a.d=0;a.m!=A&&(a.m=Ra);break;case Sa:a.c=d;a.d=0;a.m!=A&&(a.m=G);break;case Ta:a.c=0;a.d=e;a.m!=A&&(a.m=Ua);break;case I:a.c=d;a.d=e;a.m!=A&&a.m!=G&&a.m!=Ua&&(a.m=Math.abs(d)<=Math.abs(e)?G:Ua);break;case B:a.c=a.d=d;a.m!=A&&(a.m=Na);break;default:w("glp_set_row_bnds: i = "+b+"; type = "+c+"; invalid row type")}},
Wa=exports.glp_set_col_bnds=function(a,b,c,d,e){1<=b&&b<=a.i||w("glp_set_col_bnds: j = "+b+"; column number out of range");a=a.f[b];a.type=c;switch(c){case Ka:a.c=a.d=0;a.m!=A&&(a.m=Ra);break;case Sa:a.c=d;a.d=0;a.m!=A&&(a.m=G);break;case Ta:a.c=0;a.d=e;a.m!=A&&(a.m=Ua);break;case I:a.c=d;a.d=e;a.m!=A&&a.m!=G&&a.m!=Ua&&(a.m=Math.abs(d)<=Math.abs(e)?G:Ua);break;case B:a.c=a.d=d;a.m!=A&&(a.m=Na);break;default:w("glp_set_col_bnds: j = "+b+"; type = "+c+"; invalid column type")}},Xa=exports.glp_set_obj_coef=
function(a,b,c){var d=a.V;null!=d&&0!=d.reason&&w("glp_set_obj_coef: operation not allowed");0<=b&&b<=a.i||w("glp_set_obj_coef: j = "+b+"; column number out of range");0==b?a.ha=c:a.f[b].u=c},Ya=exports.glp_set_mat_row=function(a,b,c,d,e){var f,g,h;1<=b&&b<=a.g||w("glp_set_mat_row: i = "+b+"; row number out of range");for(var k=a.n[b];null!=k.k;)g=k.k,k.k=g.B,f=g.f,null==g.ra?f.k=g.I:g.ra.I=g.I,null!=g.I&&(g.I.ra=g.ra),a.L--,f.m==A&&(a.valid=0);0<=c&&c<=a.i||w("glp_set_mat_row: i = "+b+"; len = "+
c+"; invalid row length ");c>5E8-a.L&&w("glp_set_mat_row: i = "+b+"; len = "+c+"; too many constraint coefficients");for(h=1;h<=c;h++)g=d[h],1<=g&&g<=a.i||w("glp_set_mat_row: i = "+b+"; ind["+h+"] = "+g+"; column index out of range"),f=a.f[g],null!=f.k&&f.k.n.ea==b&&w("glp_set_mat_row: i = "+b+"; ind["+h+"] = "+g+"; duplicate column indices not allowed"),g={},a.L++,g.n=k,g.f=f,g.j=e[h],g.ua=null,g.B=k.k,g.ra=null,g.I=f.k,null!=g.B&&(g.B.ua=g),null!=g.I&&(g.I.ra=g),k.k=f.k=g,f.m==A&&0!=g.j&&(a.valid=
0);for(g=k.k;null!=g;g=b)b=g.B,0==g.j&&(null==g.ua?k.k=b:g.ua.B=b,null!=b&&(b.ua=g.ua),g.f.k=g.I,null!=g.I&&(g.I.ra=null),a.L--)},Za=exports.glp_set_mat_col=function(a,b,c,d,e){var f=a.V,g,h,k;null!=f&&0!=f.reason&&w("glp_set_mat_col: operation not allowed");1<=b&&b<=a.i||w("glp_set_mat_col: j = "+b+"; column number out of range");for(f=a.f[b];null!=f.k;)h=f.k,f.k=h.I,g=h.n,null==h.ua?g.k=h.B:h.ua.B=h.B,null!=h.B&&(h.B.ua=h.ua),a.L--;0<=c&&c<=a.g||w("glp_set_mat_col: j = "+b+"; len = "+c+"; invalid column length");
c>5E8-a.L&&w("glp_set_mat_col: j = "+b+"; len = "+c+"; too many constraint coefficients");for(k=1;k<=c;k++)h=d[k],1<=h&&h<=a.g||w("glp_set_mat_col: j = "+b+"; ind["+k+"] = "+h+"; row index out of range"),g=a.n[h],null!=g.k&&g.k.f.C==b&&w("glp_set_mat_col: j = "+b+"; ind["+k+"] = "+h+"; duplicate row indices not allowed"),h={},a.L++,h.n=g,h.f=f,h.j=e[k],h.ua=null,h.B=g.k,h.ra=null,h.I=f.k,null!=h.B&&(h.B.ua=h),null!=h.I&&(h.I.ra=h),g.k=f.k=h;for(h=f.k;null!=h;h=b)b=h.I,0==h.j&&(h.n.k=h.B,null!=h.B&&
(h.B.ua=null),null==h.ra?f.k=b:h.ra.I=b,null!=b&&(b.ra=h.ra),a.L--);f.m==A&&(a.valid=0)};
exports.glp_load_matrix=function(a,b,c,d,e){var f=a.V,g,h,k,l;null!=f&&0!=f.reason&&w("glp_load_matrix: operation not allowed");for(k=1;k<=a.g;k++)for(f=a.n[k];null!=f.k;)h=f.k,f.k=h.B,a.L--;for(h=1;h<=a.i;h++)a.f[h].k=null;0>b&&w("glp_load_matrix: ne = "+b+"; invalid number of constraint coefficients");5E8<b&&w("glp_load_matrix: ne = "+b+"; too many constraint coefficients");for(l=1;l<=b;l++)k=c[l],h=d[l],1<=k&&k<=a.g||w("glp_load_matrix: ia["+l+"] = "+k+"; row index out of range"),f=a.n[k],1<=h&&
h<=a.i||w("glp_load_matrix: ja["+l+"] = "+h+"; column index out of range"),g=a.f[h],h={},a.L++,h.n=f,h.f=g,h.j=e[l],h.ua=null,h.B=f.k,null!=h.B&&(h.B.ua=h),f.k=h;for(k=1;k<=a.g;k++)for(h=a.n[k].k;null!=h;h=h.B){g=h.f;if(null!=g.k&&g.k.n.ea==k){for(l=1;l<=b&&(c[l]!=k||d[l]!=g.C);l++);w("glp_load_mat: ia["+l+"] = "+k+"; ja["+l+"] = "+g.C+"; duplicate indices not allowed")}h.ra=null;h.I=g.k;null!=h.I&&(h.I.ra=h);g.k=h}for(k=1;k<=a.g;k++)for(f=a.n[k],h=f.k;null!=h;h=b)b=h.B,0==h.j&&(null==h.ua?f.k=b:
h.ua.B=b,null!=b&&(b.ua=h.ua),null==h.ra?h.f.k=h.I:h.ra.I=h.I,null!=h.I&&(h.I.ra=h.ra),a.L--);a.valid=0};
exports.glp_check_dup=function(a,b,c,d,e){var f,g,h,k,l;0>a&&w("glp_check_dup: m = %d; invalid parameter");0>b&&w("glp_check_dup: n = %d; invalid parameter");0>c&&w("glp_check_dup: ne = %d; invalid parameter");0<c&&null==d&&w("glp_check_dup: ia = "+d+"; invalid parameter");0<c&&null==e&&w("glp_check_dup: ja = "+e+"; invalid parameter");for(h=1;h<=c;h++)if(f=d[h],g=e[h],!(1<=f&&f<=a&&1<=g&&g<=b))return a=-h;if(0==a||0==b)return 0;k=new Int32Array(1+a);l=new Int32Array(1+c);b=new Int8Array(1+b);for(h=
1;h<=c;h++)f=d[h],l[h]=k[f],k[f]=h;for(f=1;f<=a;f++){for(h=k[f];0!=h;h=l[h]){g=e[h];if(b[g]){for(h=1;h<=c&&(d[h]!=f||e[h]!=g);h++);for(h++;h<=c&&(d[h]!=f||e[h]!=g);h++);return a=+h}b[g]=1}for(h=k[f];0!=h;h=l[h])b[e[h]]=0}return 0};
var $a=exports.glp_sort_matrix=function(a){var b,c,d;null!=a&&3621377730==a.Dd||w("glp_sort_matrix: P = "+a+"; invalid problem object");for(c=a.g;1<=c;c--)a.n[c].k=null;for(d=a.i;1<=d;d--)for(b=a.f[d].k;null!=b;b=b.I)c=b.n.ea,b.ua=null,b.B=a.n[c].k,null!=b.B&&(b.B.ua=b),a.n[c].k=b;for(d=a.i;1<=d;d--)a.f[d].k=null;for(c=a.g;1<=c;c--)for(b=a.n[c].k;null!=b;b=b.B)d=b.f.C,b.ra=null,b.I=a.f[d].k,null!=b.I&&(b.I.ra=b),a.f[d].k=b},ab=exports.glp_del_rows=function(a,b,c){var d=a.V,e,f,g;1<=b&&b<=a.g||w("glp_del_rows: nrs = "+
b+"; invalid number of rows");for(g=1;g<=b;g++)f=c[g],1<=f&&f<=a.g||w("glp_del_rows: num["+g+"] = "+f+"; row number out of range"),e=a.n[f],null!=d&&0!=d.reason&&(d.reason!=Ga&&d.reason!=Ia&&w("glp_del_rows: operation not allowed"),e.La!=d.N.La&&w("glp_del_rows: num["+g+"] = "+f+"; invalid attempt to delete row created not in current subproblem"),e.m!=A&&w("glp_del_rows: num["+g+"] = "+f+"; invalid attempt to delete active row (constraint)"),d.tf=1),0==e.ea&&w("glp_del_rows: num["+g+"] = "+f+"; duplicate row numbers not allowed"),
Pa(a,f,null),Ya(a,f,0,null,null),e.ea=0;b=0;for(f=1;f<=a.g;f++)e=a.n[f],0!=e.ea&&(e.ea=++b,a.n[e.ea]=e);a.g=b;a.valid=0};
exports.glp_del_cols=function(a,b,c){var d=a.V,e,f;null!=d&&0!=d.reason&&w("glp_del_cols: operation not allowed");1<=b&&b<=a.i||w("glp_del_cols: ncs = "+b+"; invalid number of columns");for(f=1;f<=b;f++)d=c[f],1<=d&&d<=a.i||w("glp_del_cols: num["+f+"] = "+d+"; column number out of range"),e=a.f[d],0==e.C&&w("glp_del_cols: num["+f+"] = "+d+"; duplicate column numbers not allowed"),Qa(a,d,null),Za(a,d,0,null,null),e.C=0,e.m==A&&(a.valid=0);b=0;for(d=1;d<=a.i;d++)e=a.f[d],0!=e.C&&(e.C=++b,a.f[e.C]=e);
a.i=b;if(a.valid)for(c=a.g,e=a.head,d=1;d<=b;d++)f=a.f[d].bind,0!=f&&(e[f]=c+d)};
var hb=exports.glp_copy_prob=function(a,b,c){var d=a.V,e={},f,g,h,k;null!=d&&0!=d.reason&&w("glp_copy_prob: operation not allowed");a==b&&w("glp_copy_prob: copying problem object to itself not allowed");c!=bb&&c!=cb&&w("glp_copy_prob: names = "+c+"; invalid parameter");db(a);c&&null!=b.name&&Ca(a,b.name);c&&null!=b.eb&&Da(a,b.eb);a.dir=b.dir;a.ha=b.ha;0<b.g&&La(a,b.g);0<b.i&&Oa(a,b.i);eb(b,e);fb(a,e);a.na=b.na;a.sa=b.sa;a.aa=b.aa;a.some=b.some;a.df=b.df;a.ae=b.ae;a.za=b.za;a.ta=b.ta;for(f=1;f<=b.g;f++)d=
a.n[f],e=b.n[f],c&&null!=e.name&&Pa(a,f,e.name),d.type=e.type,d.c=e.c,d.d=e.d,d.ma=e.ma,d.m=e.m,d.r=e.r,d.J=e.J,d.dc=e.dc,d.mc=e.mc,d.Sa=e.Sa;h=new Int32Array(1+b.g);k=new Float64Array(1+b.g);for(f=1;f<=b.i;f++)d=a.f[f],e=b.f[f],c&&null!=e.name&&Qa(a,f,e.name),d.kind=e.kind,d.type=e.type,d.c=e.c,d.d=e.d,d.u=e.u,g=gb(b,f,h,k),Za(a,f,g,h,k),d.va=e.va,d.m=e.m,d.r=e.r,d.J=e.J,d.dc=e.dc,d.mc=e.mc,d.Sa=e.Sa},db=exports.glp_erase_prob=function(a){var b=a.V;null!=b&&0!=b.reason&&w("glp_erase_prob: operation not allowed");
a.Dd=1061109567;a.ke=null;a.n=null;a.f=null;a.fc=null;a.Lc=null;a.head=null;a.Qd=null;a.U=null;ya(a)};exports.glp_get_prob_name=function(a){return a.name};
var ib=exports.glp_get_obj_name=function(a){return a.eb},jb=exports.glp_get_obj_dir=function(a){return a.dir},kb=exports.glp_get_num_rows=function(a){return a.g},lb=exports.glp_get_num_cols=function(a){return a.i},mb=exports.glp_get_row_name=function(a,b){1<=b&&b<=a.g||w("glp_get_row_name: i = "+b+"; row number out of range");return a.n[b].name},nb=exports.glp_get_col_name=function(a,b){1<=b&&b<=a.i||w("glp_get_col_name: j = "+b+"; column number out of range");return a.f[b].name},ob=exports.glp_get_row_type=
function(a,b){1<=b&&b<=a.g||w("glp_get_row_type: i = "+b+"; row number out of range");return a.n[b].type},pb=exports.glp_get_row_lb=function(a,b){var c;1<=b&&b<=a.g||w("glp_get_row_lb: i = "+b+"; row number out of range");switch(a.n[b].type){case Ka:case Ta:c=-s;break;case Sa:case I:case B:c=a.n[b].c}return c},qb=exports.glp_get_row_ub=function(a,b){var c;1<=b&&b<=a.g||w("glp_get_row_ub: i = "+b+"; row number out of range");switch(a.n[b].type){case Ka:case Sa:c=+s;break;case Ta:case I:case B:c=a.n[b].d}return c},
rb=exports.glp_get_col_type=function(a,b){1<=b&&b<=a.i||w("glp_get_col_type: j = "+b+"; column number out of range");return a.f[b].type},sb=exports.glp_get_col_lb=function(a,b){var c;1<=b&&b<=a.i||w("glp_get_col_lb: j = "+b+"; column number out of range");switch(a.f[b].type){case Ka:case Ta:c=-s;break;case Sa:case I:case B:c=a.f[b].c}return c},tb=exports.glp_get_col_ub=function(a,b){var c;1<=b&&b<=a.i||w("glp_get_col_ub: j = "+b+"; column number out of range");switch(a.f[b].type){case Ka:case Sa:c=
+s;break;case Ta:case I:case B:c=a.f[b].d}return c};exports.glp_get_obj_coef=function(a,b){0<=b&&b<=a.i||w("glp_get_obj_coef: j = "+b+"; column number out of range");return 0==b?a.ha:a.f[b].u};exports.glp_get_num_nz=function(a){return a.L};
var ub=exports.glp_get_mat_row=function(a,b,c,d){var e;1<=b&&b<=a.g||w("glp_get_mat_row: i = "+b+"; row number out of range");e=0;for(a=a.n[b].k;null!=a;a=a.B)e++,null!=c&&(c[e]=a.f.C),null!=d&&(d[e]=a.j);return e},gb=exports.glp_get_mat_col=function(a,b,c,d){var e;1<=b&&b<=a.i||w("glp_get_mat_col: j = "+b+"; column number out of range");e=0;for(a=a.f[b].k;null!=a;a=a.I)e++,null!=c&&(c[e]=a.n.ea),null!=d&&(d[e]=a.j);return e},vb=exports.glp_create_index=function(a){var b,c;if(null==a.fc)for(a.fc=
{},c=1;c<=a.g;c++)b=a.n[c],null!=b.name&&(a.fc[b.name]=b);if(null==a.Lc)for(a.Lc={},c=1;c<=a.i;c++)b=a.f[c],null!=b.name&&(a.Lc[b.name]=b)},wb=exports.glp_find_row=function(a,b){var c=0;null==a.fc&&w("glp_find_row: row name index does not exist");var d=a.fc[b];d&&(c=d.ea);return c},xb=exports.glp_find_col=function(a,b){var c=0;null==a.Lc&&w("glp_find_col: column name index does not exist");var d=a.Lc[b];d&&(c=d.C);return c},yb=exports.glp_delete_index=function(a){a.fc=null;a.fc=null},zb=exports.glp_set_rii=
function(a,b,c){1<=b&&b<=a.g||w("glp_set_rii: i = "+b+"; row number out of range");0>=c&&w("glp_set_rii: i = "+b+"; rii = "+c+"; invalid scale factor");if(a.valid&&a.n[b].ma!=c)for(var d=a.n[b].k;null!=d;d=d.B)if(d.f.m==A){a.valid=0;break}a.n[b].ma=c},Ab=exports.glp_set_sjj=function(a,b,c){1<=b&&b<=a.i||w("glp_set_sjj: j = "+b+"; column number out of range");0>=c&&w("glp_set_sjj: j = "+b+"; sjj = "+c+"; invalid scale factor");a.valid&&a.f[b].va!=c&&a.f[b].m==A&&(a.valid=0);a.f[b].va=c},Cb=exports.glp_get_rii=
function(a,b){1<=b&&b<=a.g||w("glp_get_rii: i = "+b+"; row number out of range");return a.n[b].ma},Db=exports.glp_get_sjj=function(a,b){1<=b&&b<=a.i||w("glp_get_sjj: j = "+b+"; column number out of range");return a.f[b].va},Eb=exports.glp_unscale_prob=function(a){var b=kb(a),c=lb(a),d;for(d=1;d<=b;d++)zb(a,d,1);for(b=1;b<=c;b++)Ab(a,b,1)},Fb=exports.glp_set_row_stat=function(a,b,c){1<=b&&b<=a.g||w("glp_set_row_stat: i = "+b+"; row number out of range");c!=A&&c!=G&&c!=Ua&&c!=Ra&&c!=Na&&w("glp_set_row_stat: i = "+
b+"; stat = "+c+"; invalid status");b=a.n[b];if(c!=A)switch(b.type){case Ka:c=Ra;break;case Sa:c=G;break;case Ta:c=Ua;break;case I:c!=Ua&&(c=G);break;case B:c=Na}if(b.m==A&&c!=A||b.m!=A&&c==A)a.valid=0;b.m=c},Gb=exports.glp_set_col_stat=function(a,b,c){1<=b&&b<=a.i||w("glp_set_col_stat: j = "+b+"; column number out of range");c!=A&&c!=G&&c!=Ua&&c!=Ra&&c!=Na&&w("glp_set_col_stat: j = "+b+"; stat = "+c+"; invalid status");b=a.f[b];if(c!=A)switch(b.type){case Ka:c=Ra;break;case Sa:c=G;break;case Ta:c=
Ua;break;case I:c!=Ua&&(c=G);break;case B:c=Na}if(b.m==A&&c!=A||b.m!=A&&c==A)a.valid=0;b.m=c},Hb=exports.glp_std_basis=function(a){var b;for(b=1;b<=a.g;b++)Fb(a,b,A);for(b=1;b<=a.i;b++){var c=a.f[b];c.type==I&&Math.abs(c.c)>Math.abs(c.d)?Gb(a,b,Ua):Gb(a,b,G)}},sc=exports.glp_simplex=function(a,b){function c(a,b){var c;if(!Ib(a)&&(c=Jb(a),0!=c&&(c==Kb?b.o>=Lb&&x("glp_simplex: initial basis is invalid"):c==Mb?b.o>=Lb&&x("glp_simplex: initial basis is singular"):c==Nb&&b.o>=Lb&&x("glp_simplex: initial basis is ill-conditioned")),
0!=c))return c;b.cb==Ob?c=Pb(a,b):b.cb==Qb?(c=Rb(a,b),c==Sb&&a.valid&&(c=Pb(a,b))):b.cb==Tb&&(c=Rb(a,b));return c}function d(a,b){function d(){Ub(e,f);f=null;Vb(e,a);return r=0}var e,f=null,g={},r;b.o>=Wb&&x("Preprocessing...");e=Xb();Yb(e,a,Zb);r=$b(e,0);0!=r&&(r==ac?b.o>=Wb&&x("PROBLEM HAS NO PRIMAL FEASIBLE SOLUTION"):r==bc&&b.o>=Wb&&x("PROBLEM HAS NO DUAL FEASIBLE SOLUTION"));if(0!=r)return r;f=Ba();cc(e,f);if(0==f.g&&0==f.i)return f.na=f.sa=dc,f.aa=f.ha,b.o>=fc&&0==b.fb&&x(a.$+": obj = "+f.aa+
" infeas = 0.0"),b.o>=Wb&&x("OPTIMAL SOLUTION FOUND BY LP PREPROCESSOR"),d();b.o>=Wb&&x(f.g+" row"+(1==f.g?"":"s")+", "+f.i+" column"+(1==f.i?"":"s")+", "+f.L+" non-zero"+(1==f.L?"":"s")+"");eb(a,g);fb(f,g);var g=na,n=g.Fb;g.Fb=!n||b.o<Wb?cb:bb;gc(f,hc);g.Fb=n;g=na;n=g.Fb;g.Fb=!n||b.o<Wb?cb:bb;ic(f);g.Fb=n;f.$=a.$;r=c(f,b);a.$=f.$;return 0!=r||f.na!=dc||f.sa!=dc?(b.o>=Lb&&x("glp_simplex: unable to recover undefined or non-optimal solution"),0==r&&(f.na==jc?r=ac:f.sa==jc&&(r=bc)),r):d()}function e(a,
b){function c(){f.m=G;f.r=f.c}function d(){f.m=Ua;f.r=f.d}var e,f,g,n,t;a.valid=0;a.na=a.sa=dc;a.aa=a.ha;n=t=a.some=0;for(g=1;g<=a.g;g++){e=a.n[g];e.m=A;e.r=e.J=0;if(e.type==Sa||e.type==I||e.type==B)e.c>+b.Gb&&(a.na=jc,0==a.some&&b.cb!=Ob&&(a.some=g)),n<+e.c&&(n=+e.c);if(e.type==Ta||e.type==I||e.type==B)e.d<-b.Gb&&(a.na=jc,0==a.some&&b.cb!=Ob&&(a.some=g)),n<-e.d&&(n=-e.d)}for(e=g=1;e<=a.i;e++)f=a.f[e],g<Math.abs(f.u)&&(g=Math.abs(f.u));g=(a.dir==za?1:-1)/g;for(e=1;e<=a.i;e++){f=a.f[e];f.type==Ka?
(f.m=Ra,f.r=0):f.type==Sa?c():f.type==Ta?d():f.type==I?0<g*f.u?c():0>g*f.u?d():Math.abs(f.c)<=Math.abs(f.d)?c():d():f.type==B&&(f.m=Na,f.r=f.c);f.J=f.u;a.aa+=f.u*f.r;if(f.type==Ka||f.type==Sa)g*f.J<-b.tb&&(a.sa=jc,0==a.some&&b.cb==Ob&&(a.some=a.g+e)),t<-g*f.J&&(t=-g*f.J);if(f.type==Ka||f.type==Ta)g*f.J>+b.tb&&(a.sa=jc,0==a.some&&b.cb==Ob&&(a.some=a.g+e)),t<+g*f.J&&(t=+g*f.J)}b.o>=fc&&0==b.fb&&x("~"+a.$+": obj = "+a.aa+" infeas = "+(b.cb==Ob?n:t)+"");b.o>=Wb&&0==b.fb&&(a.na==dc&&a.sa==dc?x("OPTIMAL SOLUTION FOUND"):
a.na==jc?x("PROBLEM HAS NO FEASIBLE SOLUTION"):b.cb==Ob?x("PROBLEM HAS UNBOUNDED SOLUTION"):x("PROBLEM HAS NO DUAL FEASIBLE SOLUTION"))}var f;null!=a&&3621377730==a.Dd||w("glp_simplex: P = "+a+"; invalid problem object");null!=a.V&&0!=a.V.reason&&w("glp_simplex: operation not allowed");null==b&&(b=new kc);b.o!=lc&&b.o!=Lb&&b.o!=fc&&b.o!=Wb&&b.o!=mc&&w("glp_simplex: msg_lev = "+b.o+"; invalid parameter");b.cb!=Ob&&b.cb!=Qb&&b.cb!=Tb&&w("glp_simplex: meth = "+b.cb+"; invalid parameter");b.fd!=nc&&b.fd!=
oc&&w("glp_simplex: pricing = "+b.fd+"; invalid parameter");b.ne!=pc&&b.ne!=qc&&w("glp_simplex: r_test = "+b.ne+"; invalid parameter");0<b.Gb&&1>b.Gb||w("glp_simplex: tol_bnd = "+b.Gb+"; invalid parameter");0<b.tb&&1>b.tb||w("glp_simplex: tol_dj = "+b.tb+"; invalid parameter");0<b.xe&&1>b.xe||w("glp_simplex: tol_piv = "+b.xe+"; invalid parameter");0>b.oc&&w("glp_simplex: it_lim = "+b.oc+"; invalid parameter");0>b.sb&&w("glp_simplex: tm_lim = "+b.sb+"; invalid parameter");1>b.bc&&w("glp_simplex: out_frq = "+
b.bc+"; invalid parameter");0>b.fb&&w("glp_simplex: out_dly = "+b.fb+"; invalid parameter");b.yc!=bb&&b.yc!=cb&&w("glp_simplex: presolve = "+b.yc+"; invalid parameter");a.na=a.sa=Aa;a.aa=0;a.some=0;for(f=1;f<=a.g;f++){var g=a.n[f];if(g.type==I&&g.c>=g.d)return b.o>=Lb&&x("glp_simplex: row "+f+": lb = "+g.c+", ub = "+g.d+"; incorrect bounds"),f=rc}for(f=1;f<=a.i;f++)if(g=a.f[f],g.type==I&&g.c>=g.d)return b.o>=Lb&&x("glp_simplex: column "+f+": lb = "+g.c+", ub = "+g.d+"; incorrect bounds"),f=rc;b.o>=
Wb&&(x("GLPK Simplex Optimizer, v"+ra()+""),x(a.g+" row"+(1==a.g?"":"s")+", "+a.i+" column"+(1==a.i?"":"s")+", "+a.L+" non-zero"+(1==a.L?"":"s")+""));0==a.L?(e(a,b),f=0):f=b.yc?d(a,b):c(a,b);return f},kc=exports.SMCP=function(a){a=a||{};this.o=a.msg_lev||Wb;this.cb=a.meth||Ob;this.fd=a.pricing||oc;this.ne=a.r_test||qc;this.Gb=a.tol_bnd||1E-7;this.tb=a.tol_dj||1E-7;this.xe=a.tol_piv||1E-10;this.hf=a.obj_ll||-s;this.jf=a.obj_ul||+s;this.oc=a.it_lim||2147483647;this.sb=a.tm_lim||2147483647;this.bc=a.out_frq||
500;this.fb=a.out_dly||0;this.yc=a.presolve||cb},xc=exports.glp_get_status=function(a){var b;b=tc(a);switch(b){case dc:switch(uc(a)){case dc:b=vc;break;case jc:b=wc}}return b},tc=exports.glp_get_prim_stat=function(a){return a.na},uc=exports.glp_get_dual_stat=function(a){return a.sa},yc=exports.glp_get_obj_val=function(a){return a.aa},zc=exports.glp_get_row_stat=function(a,b){1<=b&&b<=a.g||w("glp_get_row_stat: i = "+b+"; row number out of range");return a.n[b].m},Ac=exports.glp_get_row_prim=function(a,
b){1<=b&&b<=a.g||w("glp_get_row_prim: i = "+b+"; row number out of range");return a.n[b].r},Bc=exports.glp_get_row_dual=function(a,b){1<=b&&b<=a.g||w("glp_get_row_dual: i = "+b+"; row number out of range");return a.n[b].J},Cc=exports.glp_get_col_stat=function(a,b){1<=b&&b<=a.i||w("glp_get_col_stat: j = "+b+"; column number out of range");return a.f[b].m},Dc=exports.glp_get_col_prim=function(a,b){1<=b&&b<=a.i||w("glp_get_col_prim: j = "+b+"; column number out of range");return a.f[b].r},Ec=exports.glp_get_col_dual=
function(a,b){1<=b&&b<=a.i||w("glp_get_col_dual: j = "+b+"; column number out of range");return a.f[b].J};exports.glp_get_unbnd_ray=function(a){var b=a.some;b>a.g+a.i&&(b=0);return b};
var Hc=exports.glp_set_col_kind=function(a,b,c){1<=b&&b<=a.i||w("glp_set_col_kind: j = "+b+"; column number out of range");var d=a.f[b];switch(c){case Ma:d.kind=Ma;break;case Fc:d.kind=Fc;break;case Gc:d.kind=Fc;d.type==I&&0==d.c&&1==d.d||Wa(a,b,I,0,1);break;default:w("glp_set_col_kind: j = "+b+"; kind = "+c+"; invalid column kind")}},Ic=exports.glp_get_col_kind=function(a,b){1<=b&&b<=a.i||w("glp_get_col_kind: j = "+b+"; column number out of range");var c=a.f[b],d=c.kind;switch(d){case Fc:c.type==
I&&0==c.c&&1==c.d&&(d=Gc)}return d},Jc=exports.glp_get_num_int=function(a){for(var b,c=0,d=1;d<=a.i;d++)b=a.f[d],b.kind==Fc&&c++;return c},Kc=exports.glp_get_num_bin=function(a){for(var b,c=0,d=1;d<=a.i;d++)b=a.f[d],b.kind==Fc&&b.type==I&&0==b.c&&1==b.d&&c++;return c};
exports.glp_intopt=function(a,b){function c(a,b){var c;if(xc(a)!=vc)return b.o>=Lb&&x("glp_intopt: optimal basis to initial LP relaxation not provided"),c=Lc;b.o>=Wb&&x("Integer optimization begins...");var d=a.g;c=a.i;var e,f;a.V=e={};e.i=c;e.wc=d;e.ac=new Int8Array(1+d+c);e.bd=new Float64Array(1+d+c);e.cd=new Float64Array(1+d+c);e.mf=new Int8Array(1+d+c);e.lf=new Float64Array(1+d+c);e.kf=new Float64Array(1+d+c);for(f=1;f<=d;f++){var q=a.n[f];e.ac[f]=q.type;e.bd[f]=q.c;e.cd[f]=q.d;e.mf[f]=q.m;e.lf[f]=
q.r;e.kf[f]=q.J}for(f=1;f<=c;f++)q=a.f[f],e.ac[d+f]=q.type,e.bd[d+f]=q.c,e.cd[d+f]=q.d,e.mf[d+f]=q.m,e.lf[d+f]=q.r,e.kf[d+f]=q.J;e.ih=a.aa;e.fe=0;e.Sc=0;e.ya=null;e.head=e.Xa=null;e.Pd=e.Zf=e.Jg=0;e.Ig=0;e.se=null;e.qe=e.te=null;e.re=null;e.N=null;e.A=a;e.ad=new Int8Array(1+c);e.Fg=e.Gg=0;e.qf=null;e.of=e.rf=null;e.pf=null;d={size:0};d.head=d.Xa=null;d.fh=0;d.N=null;e.Bd=d;e.Xf=null;e.Ne=null;e.Fd=null;e.Bg=new Int32Array(1+c);e.Tg=new Float64Array(1+c);e.p=b;e.hc=ja();e.Lg=0;e.qh=0;e.reason=0;e.pe=
0;e.tf=0;e.Tc=0;e.Jf=0;e.ud=0;e.gf=0;e.stop=0;Mc(e,null);c=Nc(e);var d=e.A,r=d.g;f=d.i;if(r!=e.wc){var n,r=r-e.wc;n=new Int32Array(1+r);for(q=1;q<=r;q++)n[q]=e.wc+q;ab(d,r,n)}r=e.wc;for(q=1;q<=r;q++)Va(d,q,e.ac[q],e.bd[q],e.cd[q]),Fb(d,q,e.mf[q]),d.n[q].r=e.lf[q],d.n[q].J=e.kf[q];for(q=1;q<=f;q++)Wa(d,q,e.ac[r+q],e.bd[r+q],e.cd[r+q]),Gb(d,q,e.mf[r+q]),d.f[q].r=e.lf[r+q],d.f[q].J=e.kf[r+q];d.na=d.sa=dc;d.aa=e.ih;Oc(e.Bd);d.V=null;0==c?a.za==dc?(b.o>=Wb&&x("INTEGER OPTIMAL SOLUTION FOUND"),a.za=vc):
(b.o>=Wb&&x("PROBLEM HAS NO INTEGER FEASIBLE SOLUTION"),a.za=jc):c==Pc?b.o>=Wb&&x("RELATIVE MIP GAP TOLERANCE REACHED; SEARCH TERMINATED"):c==Qc?b.o>=Wb&&x("TIME LIMIT EXCEEDED; SEARCH TERMINATED"):c==Sb?b.o>=Lb&&x("glp_intopt: cannot solve current LP relaxation"):c==Rc&&b.o>=Wb&&x("SEARCH TERMINATED BY APPLICATION");return c}function d(a,b){function d(){Ub(m,q);q=null;Vb(m,a);return n}var e=na,f=e.Fb,m,q=null,r={},n;b.o>=Wb&&x("Preprocessing...");m=Xb();Yb(m,a,Sc);e.Fb=!f||b.o<Wb?cb:bb;n=Tc(m,b);
e.Fb=f;0!=n&&(n==ac?b.o>=Wb&&x("PROBLEM HAS NO PRIMAL FEASIBLE SOLUTION"):n==bc&&b.o>=Wb&&x("LP RELAXATION HAS NO DUAL FEASIBLE SOLUTION"));if(0!=n)return n;q=Ba();cc(m,q);if(0==q.g&&0==q.i)return q.za=vc,q.ta=q.ha,b.o>=Wb&&(x("Objective value = "+q.ta+""),x("INTEGER OPTIMAL SOLUTION FOUND BY MIP PREPROCESSOR")),d();if(b.o>=Wb){var t=Jc(q),y=Kc(q);x(q.g+" row"+(1==q.g?"":"s")+", "+q.i+" column"+(1==q.i?"":"s")+", "+q.L+" non-zero"+(1==q.L?"":"s")+"");x(t+" integer variable"+(1==t?"":"s")+", "+(0==
y?"none of":1==t&&1==y?"":1==y?"one of":y==t?"all of":y+" of")+" which "+(1==y?"is":"are")+" binary")}eb(a,r);fb(q,r);e.Fb=!f||b.o<Wb?cb:bb;gc(q,Uc|Vc|Wc|Xc);e.Fb=f;e.Fb=!f||b.o<Wb?cb:bb;ic(q);e.Fb=f;b.o>=Wb&&x("Solving LP relaxation...");e=new kc;e.o=b.o;q.$=a.$;n=sc(q,e);a.$=q.$;if(0!=n)return b.o>=Lb&&x("glp_intopt: cannot solve LP relaxation"),n=Sb;n=xc(q);n==vc?n=0:n==jc?n=ac:n==wc&&(n=bc);if(0!=n)return n;q.$=a.$;n=c(q,b);a.$=q.$;return q.za!=vc&&q.za!=dc?(a.za=q.za,n):d()}var e,f;null!=a&&
3621377730==a.Dd||w("glp_intopt: P = "+a+"; invalid problem object");null!=a.V&&w("glp_intopt: operation not allowed");null==b&&(b=new Yc);b.o!=lc&&b.o!=Lb&&b.o!=fc&&b.o!=Wb&&b.o!=mc&&w("glp_intopt: msg_lev = "+b.o+"; invalid parameter");b.Jb!=Zc&&b.Jb!=$c&&b.Jb!=ad&&b.Jb!=bd&&b.Jb!=cd&&w("glp_intopt: br_tech = "+b.Jb+"; invalid parameter");b.kc!=dd&&b.kc!=ed&&b.kc!=fd&&b.kc!=gd&&w("glp_intopt: bt_tech = "+b.kc+"; invalid parameter");0<b.Ub&&1>b.Ub||w("glp_intopt: tol_int = "+b.Ub+"; invalid parameter");
0<b.we&&1>b.we||w("glp_intopt: tol_obj = "+b.we+"; invalid parameter");0>b.sb&&w("glp_intopt: tm_lim = "+b.sb+"; invalid parameter");0>b.bc&&w("glp_intopt: out_frq = "+b.bc+"; invalid parameter");0>b.fb&&w("glp_intopt: out_dly = "+b.fb+"; invalid parameter");0<=b.Me&&256>=b.Me||w("glp_intopt: cb_size = "+b.Me+"; invalid parameter");b.ed!=hd&&b.ed!=id&&b.ed!=jd&&w("glp_intopt: pp_tech = "+b.ed+"; invalid parameter");0>b.ce&&w("glp_intopt: mip_gap = "+b.ce+"; invalid parameter");b.Ed!=bb&&b.Ed!=cb&&
w("glp_intopt: mir_cuts = "+b.Ed+"; invalid parameter");b.Ad!=bb&&b.Ad!=cb&&w("glp_intopt: gmi_cuts = "+b.Ad+"; invalid parameter");b.xd!=bb&&b.xd!=cb&&w("glp_intopt: cov_cuts = "+b.xd+"; invalid parameter");b.vd!=bb&&b.vd!=cb&&w("glp_intopt: clq_cuts = "+b.vd+"; invalid parameter");b.yc!=bb&&b.yc!=cb&&w("glp_intopt: presolve = "+b.yc+"; invalid parameter");b.sd!=bb&&b.sd!=cb&&w("glp_intopt: binarize = "+b.sd+"; invalid parameter");b.Xe!=bb&&b.Xe!=cb&&w("glp_intopt: fp_heur = "+b.Xe+"; invalid parameter");
a.za=Aa;a.ta=0;for(e=1;e<=a.g;e++)if(f=a.n[e],f.type==I&&f.c>=f.d)return b.o>=Lb&&x("glp_intopt: row "+e+": lb = "+f.c+", ub = "+f.d+"; incorrect bounds"),e=rc;for(e=1;e<=a.i;e++)if(f=a.f[e],f.type==I&&f.c>=f.d)return b.o>=Lb&&x("glp_intopt: column "+e+": lb = "+f.c+", ub = "+f.d+"; incorrect bounds"),e=rc;for(e=1;e<=a.i;e++)if(f=a.f[e],f.kind==Fc){if((f.type==Sa||f.type==I)&&f.c!=Math.floor(f.c))return b.o>=Lb&&x("glp_intopt: integer column "+e+" has non-integer lower bound "+f.c+""),e=rc;if((f.type==
Ta||f.type==I)&&f.d!=Math.floor(f.d))return b.o>=Lb&&x("glp_intopt: integer column "+e+" has non-integer upper bound "+f.d+""),e=rc;if(f.type==B&&f.c!=Math.floor(f.c))return b.o>=Lb&&x("glp_intopt: integer column "+e+" has non-integer fixed value "+f.c+""),e=rc}b.o>=Wb&&(e=Jc(a),f=Kc(a),x("GLPK Integer Optimizer, v"+ra()+""),x(a.g+" row"+(1==a.g?"":"s")+", "+a.i+" column"+(1==a.i?"":"s")+", "+a.L+" non-zero"+(1==a.L?"":"s")+""),x(e+" integer variable"+(1==e?"":"s")+", "+(0==f?"none of":1==e&&1==f?
"":1==f?"one of":f==e?"all of":f+" of")+" which "+(1==f?"is":"are")+" binary"));return e=b.yc?d(a,b):c(a,b)};
var Yc=exports.IOCP=function(a){a=a||{};this.o=a.msg_lev||Wb;this.Jb=a.br_tech||bd;this.kc=a.bt_tech||fd;this.Ub=a.tol_int||1E-5;this.we=a.tol_obj||1E-7;this.sb=a.tm_lim||2147483647;this.bc=a.out_frq||5E3;this.fb=a.out_dly||1E4;this.ob=a.cb_func||null;this.Uc=a.cb_info||null;this.Me=a.cb_size||0;this.ed=a.pp_tech||jd;this.ce=a.mip_gap||0;this.Ed=a.mir_cuts||cb;this.Ad=a.gmi_cuts||cb;this.xd=a.cov_cuts||cb;this.vd=a.clq_cuts||cb;this.yc=a.presolve||cb;this.sd=a.binarize||cb;this.Xe=a.fp_heur||cb};
exports.glp_mip_status=function(a){return a.za};exports.glp_mip_obj_val=function(a){return a.ta};
var kd=exports.glp_mip_row_val=function(a,b){1<=b&&b<=a.g||w("glp_mip_row_val: i = "+b+"; row number out of range");return a.n[b].Sa},ld=exports.glp_mip_col_val=function(a,b){1<=b&&b<=a.i||w("glp_mip_col_val: j = "+b+"; column number out of range");return a.f[b].Sa},Ib=exports.glp_bf_exists=function(a){return 0==a.g||a.valid},Jb=exports.glp_factorize=function(a){function b(a,b,c,d){var e=a.g,f;f=a.head[b];if(f<=e)b=1,c[1]=f,d[1]=1;else for(b=0,a=a.f[f-e].k;null!=a;a=a.I)b++,c[b]=a.n.ea,d[b]=-a.n.ma*
a.j*a.f.va;return b}var c=a.g,d=a.i,e=a.n,f=a.f,g=a.head,h,k,l;h=a.valid=0;for(k=1;k<=c+d;k++)if(k<=c?(l=e[k].m,e[k].bind=0):(l=f[k-c].m,f[k-c].bind=0),l==A){h++;if(h>c)return a=Kb;g[h]=k;k<=c?e[k].bind=h:f[k-c].bind=h}if(h<c)return a=Kb;if(0<c){null==a.U&&(a.U={valid:0,type:md,gb:null,Za:null,Cd:0,cc:0.1,xc:4,gc:1,Mb:1E-15,sc:1E10,$c:100,ic:1E-6,vc:100,kd:1E3,Ch:-1,hg:0},nd(a));switch(od(a.U,c,b,a)){case pd:return a=Mb;case qd:return a=Nb}a.valid=1}return 0};
exports.glp_bf_updated=function(a){0==a.g||a.valid||w("glp_bf_update: basis factorization does not exist");return 0==a.g?0:a.U.hg};var eb=exports.glp_get_bfcp=function(a,b){var c=a.Qd;null==c?(b.type=md,b.Cd=0,b.cc=0.1,b.xc=4,b.gc=bb,b.Mb=1E-15,b.sc=1E10,b.$c=100,b.ic=1E-6,b.vc=100,b.kd=0):da(b,c)};function nd(a){var b={};eb(a,b);a=a.U;a.type=b.type;a.Cd=b.Cd;a.cc=b.cc;a.xc=b.xc;a.gc=b.gc;a.Mb=b.Mb;a.sc=b.sc;a.$c=b.$c;a.ic=b.ic;a.vc=b.vc;a.kd=b.kd}
var fb=exports.glp_set_bfcp=function(a,b){var c=a.Qd;null==b?null!=c&&(a.Qd=null):(null==c&&(c=a.Qd={}),da(c,b),c.type!=md&&c.type!=rd&&c.type!=sd&&w("glp_set_bfcp: type = "+c.type+"; invalid parameter"),0>c.Cd&&w("glp_set_bfcp: lu_size = "+c.Cd+"; invalid parameter"),0<c.cc&&1>c.cc||w("glp_set_bfcp: piv_tol = "+c.cc+"; invalid parameter"),1>c.xc&&w("glp_set_bfcp: piv_lim = "+c.xc+"; invalid parameter"),c.gc!=bb&&c.gc!=cb&&w("glp_set_bfcp: suhl = "+c.gc+"; invalid parameter"),0<=c.Mb&&1E-6>=c.Mb||
w("glp_set_bfcp: eps_tol = "+c.Mb+"; invalid parameter"),1>c.sc&&w("glp_set_bfcp: max_gro = "+c.sc+"; invalid parameter"),1<=c.$c&&32767>=c.$c||w("glp_set_bfcp: nfs_max = "+c.$c+"; invalid parameter"),0<c.ic&&1>c.ic||w("glp_set_bfcp: upd_tol = "+c.ic+"; invalid parameter"),1<=c.vc&&32767>=c.vc||w("glp_set_bfcp: nrs_max = "+c.vc+"; invalid parameter"),0>c.kd&&w("glp_set_bfcp: rs_size = "+c.vc+"; invalid parameter"),0==c.kd&&(c.kd=20*c.vc));null!=a.U&&nd(a)},td=exports.glp_get_bhead=function(a,b){0==
a.g||a.valid||w("glp_get_bhead: basis factorization does not exist");1<=b&&b<=a.g||w("glp_get_bhead: k = "+b+"; index out of range");return a.head[b]},ud=exports.glp_get_row_bind=function(a,b){0==a.g||a.valid||w("glp_get_row_bind: basis factorization does not exist");1<=b&&b<=a.g||w("glp_get_row_bind: i = "+b+"; row number out of range");return a.n[b].bind},vd=exports.glp_get_col_bind=function(a,b){0==a.g||a.valid||w("glp_get_col_bind: basis factorization does not exist");1<=b&&b<=a.i||w("glp_get_col_bind: j = "+
b+"; column number out of range");return a.f[b].bind},xd=exports.glp_ftran=function(a,b){var c=a.g,d=a.n,e=a.f,f,g;0==c||a.valid||w("glp_ftran: basis factorization does not exist");for(f=1;f<=c;f++)b[f]*=d[f].ma;0<c&&wd(a.U,b);for(f=1;f<=c;f++)g=a.head[f],b[f]=g<=c?b[f]/d[g].ma:b[f]*e[g-c].va},zd=exports.glp_btran=function(a,b){var c=a.g,d=a.n,e=a.f,f,g;0==c||a.valid||w("glp_btran: basis factorization does not exist");for(f=1;f<=c;f++)g=a.head[f],b[f]=g<=c?b[f]/d[g].ma:b[f]*e[g-c].va;0<c&&yd(a.U,
b);for(f=1;f<=c;f++)b[f]*=d[f].ma};
exports.glp_warm_up=function(a){var b,c,d,e,f;a.na=a.sa=Aa;a.aa=0;a.some=0;for(d=1;d<=a.g;d++)b=a.n[d],b.r=b.J=0;for(d=1;d<=a.i;d++)b=a.f[d],b.r=b.J=0;if(!Ib(a)&&(e=Jb(a),0!=e))return e;e=new Float64Array(1+a.g);for(d=1;d<=a.g;d++)b=a.n[d],b.m!=A&&(b.m==G?b.r=b.c:b.m==Ua?b.r=b.d:b.m==Ra?b.r=0:b.m==Na&&(b.r=b.c),e[d]-=b.r);for(d=1;d<=a.i;d++)if(b=a.f[d],b.m!=A&&(b.m==G?b.r=b.c:b.m==Ua?b.r=b.d:b.m==Ra?b.r=0:b.m==Na&&(b.r=b.c),0!=b.r))for(c=b.k;null!=c;c=c.I)e[c.n.ea]+=c.j*b.r;xd(a,e);a.na=dc;for(d=
1;d<=a.g;d++)if(b=a.n[d],b.m==A){b.r=e[b.bind];c=b.type;if(c==Sa||c==I||c==B)f=1E-6+1E-9*Math.abs(b.c),b.r<b.c-f&&(a.na=Ad);if(c==Ta||c==I||c==B)f=1E-6+1E-9*Math.abs(b.d),b.r>b.d+f&&(a.na=Ad)}for(d=1;d<=a.i;d++)if(b=a.f[d],b.m==A){b.r=e[b.bind];c=b.type;if(c==Sa||c==I||c==B)f=1E-6+1E-9*Math.abs(b.c),b.r<b.c-f&&(a.na=Ad);if(c==Ta||c==I||c==B)f=1E-6+1E-9*Math.abs(b.d),b.r>b.d+f&&(a.na=Ad)}a.aa=a.ha;for(d=1;d<=a.i;d++)b=a.f[d],a.aa+=b.u*b.r;for(d=1;d<=a.g;d++)e[d]=0;for(d=1;d<=a.i;d++)b=a.f[d],b.m==
A&&(e[b.bind]=b.u);zd(a,e);a.sa=dc;for(d=1;d<=a.g;d++)if(b=a.n[d],b.m==A)b.J=0;else if(b.J=-e[d],c=b.m,b=a.dir==za?+b.J:-b.J,(c==Ra||c==G)&&-1E-5>b||(c==Ra||c==Ua)&&1E-5<b)a.sa=Ad;for(d=1;d<=a.i;d++)if(b=a.f[d],b.m==A)b.J=0;else{b.J=b.u;for(c=b.k;null!=c;c=c.I)b.J+=c.j*e[c.n.ea];c=b.m;b=a.dir==za?+b.J:-b.J;if((c==Ra||c==G)&&-1E-5>b||(c==Ra||c==Ua)&&1E-5<b)a.sa=Ad}return 0};
var Bd=exports.glp_eval_tab_row=function(a,b,c,d){var e=a.g,f=a.i,g,h,k,l,p,m,q;0==e||a.valid||w("glp_eval_tab_row: basis factorization does not exist");1<=b&&b<=e+f||w("glp_eval_tab_row: k = "+b+"; variable number out of range");g=b<=e?ud(a,b):vd(a,b-e);0==g&&w("glp_eval_tab_row: k = "+b+"; variable must be basic");m=new Float64Array(1+e);l=new Int32Array(1+e);q=new Float64Array(1+e);m[g]=1;zd(a,m);h=0;for(b=1;b<=e+f;b++){if(b<=e){if(zc(a,b)==A)continue;p=-m[b]}else{if(Cc(a,b-e)==A)continue;k=gb(a,
b-e,l,q);p=0;for(g=1;g<=k;g++)p+=m[l[g]]*q[g]}0!=p&&(h++,c[h]=b,d[h]=p)}return h},Cd=exports.glp_eval_tab_col=function(a,b,c,d){var e=a.g,f=a.i,g;0==e||a.valid||w("glp_eval_tab_col: basis factorization does not exist");1<=b&&b<=e+f||w("glp_eval_tab_col: k = "+b+"; variable number out of range");(b<=e?zc(a,b):Cc(a,b-e))==A&&w("glp_eval_tab_col: k = "+b+"; variable must be non-basic");f=new Float64Array(1+e);if(b<=e)f[b]=-1;else for(g=gb(a,b-e,c,d),b=1;b<=g;b++)f[c[b]]=d[b];xd(a,f);g=0;for(b=1;b<=e;b++)0!=
f[b]&&(g++,c[g]=td(a,b),d[g]=f[b]);return g},Dd=exports.glp_transform_row=function(a,b,c,d){var e,f,g,h,k,l,p,m,q,r;Ib(a)||w("glp_transform_row: basis factorization does not exist ");f=kb(a);g=lb(a);m=new Float64Array(1+g);0<=b&&b<=g||w("glp_transform_row: len = "+b+"; invalid row length");for(h=1;h<=b;h++)e=c[h],1<=e&&e<=g||w("glp_transform_row: ind["+h+"] = "+e+"; column index out of range"),0==d[h]&&w("glp_transform_row: val["+h+"] = 0; zero coefficient not allowed"),0!=m[e]&&w("glp_transform_row: ind["+
h+"] = "+e+"; duplicate column indices not allowed"),m[e]=d[h];q=new Float64Array(1+f);for(e=1;e<=f;e++)b=td(a,e),q[e]=b<=f?0:m[b-f];zd(a,q);b=0;for(e=1;e<=f;e++)zc(a,e)!=A&&(p=-q[e],0!=p&&(b++,c[b]=e,d[b]=p));l=new Int32Array(1+f);r=new Float64Array(1+f);for(e=1;e<=g;e++)if(Cc(a,e)!=A){p=m[e];k=gb(a,e,l,r);for(h=1;h<=k;h++)p+=r[h]*q[l[h]];0!=p&&(b++,c[b]=f+e,d[b]=p)}return b};
exports.glp_transform_col=function(a,b,c,d){var e,f,g,h;Ib(a)||w("glp_transform_col: basis factorization does not exist ");f=kb(a);h=new Float64Array(1+f);0<=b&&b<=f||w("glp_transform_col: len = "+b+"; invalid column length");for(g=1;g<=b;g++)e=c[g],1<=e&&e<=f||w("glp_transform_col: ind["+g+"] = "+e+"; row index out of range"),0==d[g]&&w("glp_transform_col: val["+g+"] = 0; zero coefficient not allowed"),0!=h[e]&&w("glp_transform_col: ind["+g+"] = "+e+"; duplicate row indices not allowed"),h[e]=d[g];
xd(a,h);b=0;for(e=1;e<=f;e++)0!=h[e]&&(b++,c[b]=td(a,e),d[b]=h[e]);return b};
var Ed=exports.glp_prim_rtest=function(a,b,c,d,e,f){var g,h,k,l,p,m,q,r,n,t,y,E,C;tc(a)!=dc&&w("glp_prim_rtest: basic solution is not primal feasible ");1!=e&&-1!=e&&w("glp_prim_rtest: dir = "+e+"; invalid parameter");0<f&&1>f||w("glp_prim_rtest: eps = "+f+"; invalid parameter");h=kb(a);k=lb(a);l=0;C=s;r=0;for(p=1;p<=b;p++)if(g=c[p],1<=g&&g<=h+k||w("glp_prim_rtest: ind["+p+"] = "+g+"; variable number out of range"),g<=h?(m=ob(a,g),t=pb(a,g),y=qb(a,g),q=zc(a,g),n=Ac(a,g)):(m=rb(a,g-h),t=sb(a,g-h),
y=tb(a,g-h),q=Cc(a,g-h),n=Dc(a,g-h)),q!=A&&w("glp_prim_rtest: ind["+p+"] = "+g+"; non-basic variable not allowed"),g=0<e?+d[p]:-d[p],m!=Ka){if(m==Sa){if(g>-f)continue;E=(t-n)/g}else if(m==Ta){if(g<+f)continue;E=(y-n)/g}else if(m==I)if(0>g){if(g>-f)continue;E=(t-n)/g}else{if(g<+f)continue;E=(y-n)/g}else if(m==B){if(-f<g&&g<+f)continue;E=0}0>E&&(E=0);if(C>E||C==E&&r<Math.abs(g))l=p,C=E,r=Math.abs(g)}return l},Fd=exports.glp_dual_rtest=function(a,b,c,d,e,f){var g,h,k,l,p,m,q,r,n,t,y;uc(a)!=dc&&w("glp_dual_rtest: basic solution is not dual feasible");
1!=e&&-1!=e&&w("glp_dual_rtest: dir = "+e+"; invalid parameter");0<f&&1>f||w("glp_dual_rtest: eps = "+f+"; invalid parameter");h=kb(a);k=lb(a);n=jb(a)==za?1:-1;l=0;y=s;q=0;for(p=1;p<=b;p++){g=c[p];1<=g&&g<=h+k||w("glp_dual_rtest: ind["+p+"] = "+g+"; variable number out of range");g<=h?(m=zc(a,g),r=Bc(a,g)):(m=Cc(a,g-h),r=Ec(a,g-h));m==A&&w("glp_dual_rtest: ind["+p+"] = "+g+"; basic variable not allowed");g=0<e?+d[p]:-d[p];if(m==G){if(g<+f)continue;t=n*r/g}else if(m==Ua){if(g>-f)continue;t=n*r/g}else if(m==
Ra){if(-f<g&&g<+f)continue;t=0}else if(m==Na)continue;0>t&&(t=0);if(y>t||y==t&&q<Math.abs(g))l=p,y=t,q=Math.abs(g)}return l};
function Gd(a,b,c,d,e,f,g){var h,k,l,p=0,m,q;a.na==Aa&&w("glp_analyze_row: primal basic solution components are undefined");a.sa!=dc&&w("glp_analyze_row: basic solution is not dual feasible");0<=b&&b<=a.i||w("glp_analyze_row: len = "+b+"; invalid row length");q=0;for(h=1;h<=b;h++)k=c[h],1<=k&&k<=a.g+a.i||w("glp_analyze_row: ind["+h+"] = "+k+"; row/column index out of range"),k<=a.g?(a.n[k].m==A&&w("glp_analyze_row: ind["+h+"] = "+k+"; basic auxiliary variable is not allowed"),m=a.n[k].r):(a.f[k-a.g].m==
A&&w("glp_analyze_row: ind["+h+"] = "+k+"; basic structural variable is not allowed"),m=a.f[k-a.g].r),q+=d[h]*m;if(e==Sa){if(q>=f)return 1;l=1}else if(e==Ta){if(q<=f)return 1;l=-1}else w("glp_analyze_row: type = "+e+"; invalid parameter");e=f-q;b=Fd(a,b,c,d,l,1E-9);if(0==b)return 2;k=c[b];m=k<=a.g?a.n[k].r:a.f[k-a.g].r;c=e/d[b];g(b,m,c,q,e,k<=a.g?a.n[k].J*c:a.f[k-a.g].J*c);return p}
exports.glp_analyze_bound=function(a,b,c){var d,e,f,g,h,k,l,p,m,q,r,n,t,y;r=n=t=y=null;null!=a&&3621377730==a.Dd||w("glp_analyze_bound: P = "+a+"; invalid problem object");e=a.g;f=a.i;a.na==dc&&a.sa==dc||w("glp_analyze_bound: optimal basic solution required");0==e||a.valid||w("glp_analyze_bound: basis factorization required");1<=b&&b<=e+f||w("glp_analyze_bound: k = "+b+"; variable number out of range");d=b<=e?a.n[b]:a.f[b-e];g=d.m;f=d.r;g==A&&w("glp_analyze_bound: k = "+b+"; basic variable not allowed ");
g=new Int32Array(1+e);q=new Float64Array(1+e);k=Cd(a,b,g,q);for(b=-1;1>=b;b+=2)l=Ed(a,k,g,q,b,1E-9),0==l?(h=0,l=0>b?-s:+s):(h=g[l],h<=e?(d=a.n[h],p=pb(a,d.ea),m=qb(a,d.ea)):(d=a.f[h-e],p=sb(a,d.C),m=tb(a,d.C)),d=d.r,d=0>b&&0<q[l]||0<b&&0>q[l]?p-d:m-d,l=f+d/q[l]),0>b?(r=l,n=h):(t=l,y=h);c(r,n,t,y)};
exports.glp_analyze_coef=function(a,b,c){var d,e,f,g,h,k,l,p,m,q,r,n,t,y,E,C,D,H,R,V,O=null,Q=null,F=null,W=null,X=null,ca=null;null!=a&&3621377730==a.Dd||w("glp_analyze_coef: P = "+a+"; invalid problem object");e=a.g;f=a.i;a.na==dc&&a.sa==dc||w("glp_analyze_coef: optimal basic solution required");0==e||a.valid||w("glp_analyze_coef: basis factorization required");1<=b&&b<=e+f||w("glp_analyze_coef: k = "+b+"; variable number out of range");b<=e?(d=a.n[b],g=d.type,n=d.c,t=d.d,y=0):(d=a.f[b-e],g=d.type,
n=d.c,t=d.d,y=d.u);h=d.m;E=d.r;h!=A&&w("glp_analyze_coef: k = "+b+"; non-basic variable not allowed");h=new Int32Array(1+e);V=new Float64Array(1+e);r=new Int32Array(1+f);R=new Float64Array(1+f);m=Bd(a,b,r,R);for(f=-1;1>=f;f+=2)a.dir==za?l=-f:a.dir==Ea&&(l=+f),q=Fd(a,m,r,R,l,1E-9),0==q?(C=0>f?-s:+s,k=0,q=E):(k=r[q],d=k<=e?a.n[k]:a.f[k-e],l=d.J,d=-l/R[q],C=y+d,l=0>f&&0<R[q]||0<f&&0>R[q]?1:-1,a.dir==Ea&&(l=-l),p=Cd(a,k,h,V),d=b<=e?a.n[b]:a.f[b-e],d.type=Ka,d.c=d.d=0,p=Ed(a,p,h,V,l,1E-9),d=b<=e?a.n[b]:
a.f[b-e],d.type=g,d.c=n,d.d=t,0==p?q=0>l&&0<R[q]||0<l&&0>R[q]?-s:+s:(d=h[p],d<=e?(d=a.n[d],D=pb(a,d.ea),H=qb(a,d.ea)):(d=a.f[d-e],D=sb(a,d.C),H=tb(a,d.C)),d=d.r,d=0>l&&0<V[p]||0<l&&0>V[p]?D-d:H-d,q=E+R[q]/V[p]*d)),0>f?(O=C,Q=k,F=q):(W=C,X=k,ca=q);c(O,Q,F,W,X,ca)};exports.glp_ios_reason=function(a){return a.reason};exports.glp_ios_get_prob=function(a){return a.A};function Hd(a){a.reason!=Ia&&w("glp_ios_pool_size: operation not allowed");return a.Bd.size}
function Id(a,b,c,d,e,f,g){a.reason!=Ia&&w("glp_ios_add_row: operation not allowed");var h=a.Bd,k,l;k={name:null};0<=b&&255>=b||w("glp_ios_add_row: klass = "+b+"; invalid cut class");k.qc=b;k.k=null;0<=c&&c<=a.i||w("glp_ios_add_row: len = "+c+"; invalid cut length");for(l=1;l<=c;l++)b={},1<=d[l]&&d[l]<=a.i||w("glp_ios_add_row: ind["+l+"] = "+d[l]+"; column index out of range"),b.C=d[l],b.j=e[l],b.e=k.k,k.k=b;f!=Sa&&f!=Ta&&f!=B&&w("glp_ios_add_row: type = "+f+"; invalid cut type");k.type=f;k.cg=g;
k.ca=h.Xa;k.e=null;null==k.ca?h.head=k:k.ca.e=k;h.Xa=k;h.size++}function Jd(a,b){1<=b&&b<=a.A.i||w("glp_ios_can_branch: j = "+b+"; column number out of range");return a.ad[b]}
function Kd(a,b){var c=a.A,d=a.wc,e=a.i,f,g;g=c.ha;for(f=1;f<=e;f++){var h=c.f[f];if(h.kind==Fc&&b[f]!=Math.floor(b[f]))return 1;g+=h.u*b[f]}if(c.za==dc)switch(c.dir){case za:if(g>=a.A.ta)return 1;break;case Ea:if(g<=a.A.ta)return 1}a.p.o>=fc&&x("Solution found by heuristic: "+g+"");c.za=dc;c.ta=g;for(f=1;f<=e;f++)c.f[f].Sa=b[f];for(e=1;e<=d;e++)for(f=c.n[e],f.Sa=0,g=f.k;null!=g;g=g.B)f.Sa+=g.j*g.f.Sa;return 0}exports.glp_mpl_alloc_wksp=function(){return Ld()};
exports._glp_mpl_init_rand=function(a,b){0!=a.D&&w("glp_mpl_init_rand: invalid call sequence\n");Md(a.Gd,b)};var Od=exports.glp_mpl_read_model=function(a,b,c,d){0!=a.D&&w("glp_mpl_read_model: invalid call sequence");a=Nd(a,b,c,d);1==a||2==a?a=0:4==a&&(a=1);return a};exports.glp_mpl_read_model_from_string=function(a,b,c,d){var e=0;return Od(a,b,function(){return e<c.length?c[e++]:-1},d)};
var Qd=exports.glp_mpl_read_data=function(a,b,c){1!=a.D&&2!=a.D&&w("glp_mpl_read_data: invalid call sequence");a=Pd(a,b,c);2==a?a=0:4==a&&(a=1);return a};exports.glp_mpl_read_data_from_string=function(a,b,c){var d=0;return Qd(a,b,function(){return d<c.length?c[d++]:-1})};exports.glp_mpl_generate=function(a,b,c,d){1!=a.D&&2!=a.D&&w("glp_mpl_generate: invalid call sequence\n");a=Rd(a,b,c,d);3==a?a=0:4==a&&(a=1);return a};
exports.glp_mpl_build_prob=function(a,b){var c,d,e,f,g,h,k;3!=a.D&&w("glp_mpl_build_prob: invalid call sequence\n");db(b);Ca(b,Sd(a));c=Td(a);0<c&&La(b,c);for(d=1;d<=c;d++){Pa(b,d,Ud(a,d));g=Vd(a,d,function(a,b){h=a;k=b});switch(g){case Wd:g=Ka;break;case Xd:g=Sa;break;case Yd:g=Ta;break;case Zd:g=I;break;case $d:g=B}g==I&&Math.abs(h-k)<1E-9*(1+Math.abs(h))&&(g=B,Math.abs(h)<=Math.abs(k)?k=h:h=k);Va(b,d,g,h,k);0!=ae(a,d)&&x("glp_mpl_build_prob: row "+Ud(a,d)+"; constant term "+ae(a,d)+" ignored")}d=
be(a);0<d&&Oa(b,d);for(e=1;e<=d;e++){Qa(b,e,ce(a,e));f=de(a,e);switch(f){case ee:case fe:Hc(b,e,Fc)}g=ge(a,e,function(a,b){h=a;k=b});switch(g){case Wd:g=Ka;break;case Xd:g=Sa;break;case Yd:g=Ta;break;case Zd:g=I;break;case $d:g=B}if(f==fe){if(g==Ka||g==Ta||0>h)h=0;if(g==Ka||g==Sa||1<k)k=1;g=I}g==I&&Math.abs(h-k)<1E-9*(1+Math.abs(h))&&(g=B,Math.abs(h)<=Math.abs(k)?k=h:h=k);Wa(b,e,g,h,k)}g=new Int32Array(1+d);e=new Float64Array(1+d);for(d=1;d<=c;d++)f=he(a,d,g,e),Ya(b,d,f,g,e);for(d=1;d<=c;d++)if(f=
ie(a,d),f==je||f==ke){Da(b,Ud(a,d));Fa(b,f==je?za:Ea);Xa(b,0,ae(a,d));f=he(a,d,g,e);for(c=1;c<=f;c++)Xa(b,g[c],e[c]);break}};
exports.glp_mpl_postsolve=function(a,b,c){var d,e,f,g,h,k;(3!=a.D||a.Of)&&w("glp_mpl_postsolve: invalid call sequence");c!=Zb&&c!=le&&c!=Sc&&w("glp_mpl_postsolve: sol = "+c+"; invalid parameter");e=Td(a);f=be(a);e==kb(b)&&f==lb(b)||w("glp_mpl_postsolve: wrong problem object\n");if(!me(a))return 0;for(d=1;d<=e;d++)c==Zb?(g=zc(b,d),h=Ac(b,d),k=Bc(b,d)):c==le?(g=0,h=glp_ipt_row_prim(b,d),k=glp_ipt_row_dual(b,d)):c==Sc&&(g=0,h=kd(b,d),k=0),1E-9>Math.abs(h)&&(h=0),1E-9>Math.abs(k)&&(k=0),ne(a,d,g,h,k);
for(d=1;d<=f;d++)c==Zb?(g=Cc(b,d),h=Dc(b,d),k=Ec(b,d)):c==le?(g=0,h=glp_ipt_col_prim(b,d),k=glp_ipt_col_dual(b,d)):c==Sc&&(g=0,h=ld(b,d),k=0),1E-9>Math.abs(h)&&(h=0),1E-9>Math.abs(k)&&(k=0),oe(a,d,g,h,k);a=pe(a);3==a?a=0:4==a&&(a=1);return a};
function qe(a,b){var c,d,e;c=null;for(d=a.root;null!=d;)c=d,0>=a.yg(a.info,b,c.key)?(e=0,d=c.left,c.pa++):(e=1,d=c.right);d={};d.key=b;d.type=0;d.link=null;d.pa=1;d.R=c;d.ba=null==c?0:e;d.wa=0;d.left=null;d.right=null;a.size++;for(null==c?a.root=d:0==e?c.left=d:c.right=d;null!=c;){if(0==e){if(0<c.wa){c.wa=0;break}if(0>c.wa){re(a,c);break}c.wa=-1}else{if(0>c.wa){c.wa=0;break}if(0<c.wa){re(a,c);break}c.wa=1}e=c.ba;c=c.R}null==c&&a.height++;return d}
function re(a,b){var c,d,e,f,g;0>b.wa?(c=b.R,d=b.left,e=d.right,0>=d.wa?(null==c?a.root=d:0==b.ba?c.left=d:c.right=d,b.pa-=d.pa,d.R=c,d.ba=b.ba,d.wa++,d.right=b,b.R=d,b.ba=1,b.wa=-d.wa,b.left=e,null!=e&&(e.R=b,e.ba=0)):(f=e.left,g=e.right,null==c?a.root=e:0==b.ba?c.left=e:c.right=e,b.pa-=d.pa+e.pa,e.pa+=d.pa,b.wa=0<=e.wa?0:1,d.wa=0>=e.wa?0:-1,e.R=c,e.ba=b.ba,e.wa=0,e.left=d,e.right=b,b.R=e,b.ba=1,b.left=g,d.R=e,d.ba=0,d.right=f,null!=f&&(f.R=d,f.ba=1),null!=g&&(g.R=b,g.ba=0))):(c=b.R,d=b.right,e=
d.left,0<=d.wa?(null==c?a.root=d:0==b.ba?c.left=d:c.right=d,d.pa+=b.pa,d.R=c,d.ba=b.ba,d.wa--,d.left=b,b.R=d,b.ba=0,b.wa=-d.wa,b.right=e,null!=e&&(e.R=b,e.ba=1)):(f=e.left,g=e.right,null==c?a.root=e:0==b.ba?c.left=e:c.right=e,d.pa-=e.pa,e.pa+=b.pa,b.wa=0>=e.wa?0:-1,d.wa=0<=e.wa?0:1,e.R=c,e.ba=b.ba,e.wa=0,e.left=b,e.right=d,b.R=e,b.ba=0,b.right=f,d.R=e,d.ba=1,d.left=g,null!=f&&(f.R=b,f.ba=1),null!=g&&(g.R=d,g.ba=0)))}var pd=1,qd=2,se=3,te=4,ue=5;
function od(a,b,c,d){var e,f;f=a.valid=0;switch(a.type){case md:a.Za=null;null==a.gb&&(f={},f.hb=f.g=0,f.valid=0,f.ia=ve(),f.$d=50,f.Pb=0,f.Ze=f.af=f.$e=null,f.je=f.ie=null,f.ug=null,f.vg=null,f.ic=1E-6,f.ag=0,a.gb=f,f=1);break;case rd:case sd:a.gb=null,null==a.Za&&(we&&x("lpf_create_it: warning: debug mode enabled"),f={valid:0},f.Nc=f.ef=0,f.ia=ve(),f.g=0,f.Cf=null,f.K=50,f.i=0,f.Md=f.Ld=null,f.Od=f.Nd=null,f.Qc=null,f.Ge=f.Fe=null,f.Ie=f.He=null,f.Jd=1E3,f.od=0,f.Wb=null,f.Xb=null,f.jb=f.Gc=null,
a.Za=f,f=1)}null!=a.gb?e=a.gb.ia:null!=a.Za&&(e=a.Za.ia);f&&(e.Va=a.Cd);e.cc=a.cc;e.xc=a.xc;e.gc=a.gc;e.Mb=a.Mb;e.sc=a.sc;null!=a.gb&&(f&&(a.gb.$d=a.$c),a.gb.ic=a.ic);null!=a.Za&&(f&&(a.Za.K=a.vc),f&&(a.Za.Jd=a.kd));if(null!=a.gb){a:{e=a.gb;1>b&&w("fhv_factorize: m = "+b+"; invalid parameter");1E8<b&&w("fhv_factorize: m = "+b+"; matrix too big");e.g=b;e.valid=0;null==e.Ze&&(e.Ze=new Int32Array(1+e.$d));null==e.af&&(e.af=new Int32Array(1+e.$d));null==e.$e&&(e.$e=new Int32Array(1+e.$d));e.hb<b&&(e.hb=
b+100,e.je=new Int32Array(1+e.hb),e.ie=new Int32Array(1+e.hb),e.ug=new Int32Array(1+e.hb),e.vg=new Float64Array(1+e.hb));switch(xe(e.ia,b,c,d)){case ye:b=ze;break a;case Ae:b=Be;break a}e.valid=1;e.Pb=0;ga(e.je,1,e.ia.kb,1,b);ga(e.ie,1,e.ia.vb,1,b);b=e.ag=0}switch(b){case ze:return a=pd;case Be:return a=qd}}else if(null!=a.Za){a:{e=a.Za;if(we)var g,h,k,l,p,m;1>b&&w("lpf_factorize: m = "+b+"; invalid parameter");1E8<b&&w("lpf_factorize: m = "+b+"; matrix too big");e.ef=e.g=b;e.valid=0;null==e.Md&&
(e.Md=new Int32Array(1+e.K));null==e.Ld&&(e.Ld=new Int32Array(1+e.K));null==e.Od&&(e.Od=new Int32Array(1+e.K));null==e.Nd&&(e.Nd=new Int32Array(1+e.K));null==e.Qc&&(f=e.K,Ce&&x("scf_create_it: warning: debug mode enabled"),1<=f&&32767>=f||w("scf_create_it: n_max = "+f+"; invalid parameter"),g={},g.K=f,g.i=0,g.Nb=new Float64Array(1+f*f),g.v=new Float64Array(1+f*(f+1)/2),g.s=new Int32Array(1+f),g.fg=De,g.pa=0,g.l=Ce?new Float64Array(1+f*f):null,g.ig=new Float64Array(1+f),e.Qc=g);null==e.Wb&&(e.Wb=new Int32Array(1+
e.Jd));null==e.Xb&&(e.Xb=new Float64Array(1+e.Jd));e.Nc<b&&(e.Nc=b+100,e.Ge=new Int32Array(1+e.Nc+e.K),e.Fe=new Int32Array(1+e.Nc+e.K),e.Ie=new Int32Array(1+e.Nc+e.K),e.He=new Int32Array(1+e.Nc+e.K),e.jb=new Float64Array(1+e.Nc+e.K),e.Gc=new Float64Array(1+e.Nc+e.K));switch(xe(e.ia,b,c,d)){case ye:b=Ee;break a;case Ae:b=LPF_ECOND;break a}e.valid=1;if(we){e.Cf=p=new Float64Array(1+b*b);l=new Int32Array(1+b);m=new Float64Array(1+b);for(f=1;f<=b*b;f++)p[f]=0;for(h=1;h<=b;h++)for(k=c(d,h,l,m),f=1;f<=
k;f++)g=l[f],p[(g-1)*b+h]=m[f]}e.i=0;c=e.Qc;c.i=c.pa=0;for(f=1;f<=b;f++)e.Ge[f]=e.Fe[f]=f,e.Ie[f]=e.He[f]=f;e.od=1;b=0}switch(b){case 0:switch(a.type){case rd:a.Za.Qc.fg=De;break;case sd:a.Za.Qc.fg=Fe}break;case Ee:return a=pd;case LPF_ECOND:return a=qd}}a.valid=1;return a.hg=0}
function wd(a,b){if(null!=a.gb){var c=a.gb,d=c.ia.kb,e=c.ia.vb,f=c.je,g=c.ie;c.valid||w("fhv_ftran: the factorization is not valid");c.ia.kb=f;c.ia.vb=g;Ge(c.ia,0,b);c.ia.kb=d;c.ia.vb=e;He(c,0,b);Ie(c.ia,0,b)}else if(null!=a.Za){var c=a.Za,d=c.ef,e=c.g,h=c.i,k=c.Fe,f=c.He,g=c.jb,l,p;if(we)var m;c.valid||w("lpf_ftran: the factorization is not valid");if(we)for(m=new Float64Array(1+e),l=1;l<=e;l++)m[l]=b[l];for(l=1;l<=d+h;l++)g[l]=(p=k[l])<=e?b[p]:0;Ge(c.ia,0,g);Je(c,g,d,g);Ke(c.Qc,0,g,d);h=c.i;k=c.Md;
l=c.Ld;p=c.Wb;var q=c.Xb,r,n,t,y;for(r=1;r<=h;r++)if(0!=g[r+d])for(y=-1*g[r+d],n=k[r],t=n+l[r];n<t;n++)g[p[n]]+=y*q[n];Ie(c.ia,0,g);for(l=1;l<=e;l++)b[l]=g[f[l]];we&&Le(c,0,b,m)}}
function yd(a,b){if(null!=a.gb){var c=a.gb,d=c.ia.kb,e=c.ia.vb,f=c.je,g=c.ie;c.valid||w("fhv_btran: the factorization is not valid");Ie(c.ia,1,b);He(c,1,b);c.ia.kb=f;c.ia.vb=g;Ge(c.ia,1,b);c.ia.kb=d;c.ia.vb=e}else if(null!=a.Za){var c=a.Za,d=c.ef,e=c.g,h=c.i,f=c.Ge,k=c.Ie,g=c.jb,l,p;if(we)var m;c.valid||w("lpf_btran: the factorization is not valid");if(we)for(m=new Float64Array(1+e),l=1;l<=e;l++)m[l]=b[l];for(l=1;l<=d+h;l++)g[l]=(p=k[l])<=e?b[p]:0;Ie(c.ia,1,g);Me(c,g,d,g);Ke(c.Qc,1,g,d);h=c.i;k=c.Od;
l=c.Nd;p=c.Wb;var q=c.Xb,r,n,t,y;for(r=1;r<=h;r++)if(0!=g[r+d])for(y=-1*g[r+d],n=k[r],t=n+l[r];n<t;n++)g[p[n]]+=y*q[n];Ge(c.ia,1,g);for(l=1;l<=e;l++)b[l]=g[f[l]];we&&Le(c,1,b,m)}}
function Ne(a,b,c,d,e,f){if(null!=a.gb)switch(Oe(a.gb,b,c,d,e,f)){case ze:return a.valid=0,a=pd;case Pe:return a.valid=0,a=se;case Qe:return a.valid=0,a=te;case Re:return a.valid=0,a=ue}else if(null!=a.Za){a:{var g=a.Za,h=g.ef,k=g.g;if(we)var l=g.Cf;var p=g.i,m=g.Md,q=g.Ld,r=g.Od,n=g.Nd,t=g.Ge,y=g.Fe,E=g.Ie,C=g.He,D=g.od,H=g.Wb,R=g.Xb,V=g.Gc,O=g.jb,Q=g.Gc,F,W,X;g.valid||w("lpf_update_it: the factorization is not valid");1<=b&&b<=k||w("lpf_update_it: j = "+b+"; column number out of range");if(p==g.K)g.valid=
0,b=LPF_ELIMIT;else{for(F=1;F<=k;F++)V[F]=0;for(X=1;X<=c;X++)F=d[e+X],1<=F&&F<=k||w("lpf_update_it: ind["+X+"] = "+F+"; row number out of range"),0!=V[F]&&w("lpf_update_it: ind["+X+"] = "+F+"; duplicate row index not allowed"),0==f[X]&&w("lpf_update_it: val["+X+"] = "+f[X]+"; zero element not allowed"),V[F]=f[X];if(we)for(F=1;F<=k;F++)l[(F-1)*k+b]=V[F];for(F=1;F<=h+p;F++)O[F]=(W=y[F])<=k?V[W]:0;for(F=1;F<=h+p;F++)Q[F]=0;Q[C[b]]=1;Ge(g.ia,0,O);Ie(g.ia,1,Q);if(g.Jd<D+h+h){F=g.Jd;c=g.od-1;d=g.Wb;for(e=
g.Xb;F<D+h+h;)F+=F;g.Jd=F;g.Wb=new Int32Array(1+F);g.Xb=new Float64Array(1+F);ga(g.Wb,1,d,1,c);ga(g.Xb,1,e,1,c);H=g.Wb;R=g.Xb}m[p+1]=D;for(F=1;F<=h;F++)0!=O[F]&&(H[D]=F,R[D]=O[F],D++);q[p+1]=D-g.od;g.od=D;r[p+1]=D;for(F=1;F<=h;F++)0!=Q[F]&&(H[D]=F,R[D]=Q[F],D++);n[p+1]=D-g.od;g.od=D;Je(g,O,0,O);Me(g,Q,0,Q);q=0;for(F=1;F<=h;F++)q-=Q[F]*O[F];m=g.Qc;D=q;F=m.K;q=m.i;c=m.Nb;d=m.v;e=m.s;if(Ce)var ca=m.l;n=m.ig;r=0;if(q==F)r=Se;else{m.i=++q;f=1;for(k=(f-1)*m.K+q;f<q;f++,k+=F)c[k]=0;k=1;for(f=(q-1)*m.K+k;k<
q;k++,f++)c[f]=0;for(f=c[(q-1)*m.K+q]=1;f<q;f++){H=0;k=1;for(l=(f-1)*m.K+1;k<q;k++,l++)H+=c[l]*O[k+h];d[Te(m,f,q)]=H}for(k=1;k<q;k++)n[k]=Q[e[k]+h];n[q]=D;e[q]=q;if(Ce){f=1;for(k=(f-1)*m.K+q;f<q;f++,k+=F)ca[k]=O[f+h];k=1;for(f=(q-1)*m.K+k;k<q;k++,f++)ca[f]=Q[k+h];ca[(q-1)*m.K+q]=D}for(O=1;O<q&&0==n[O];O++);switch(m.fg){case De:Q=m.i;ca=m.Nb;for(D=m.v;O<Q;O++){e=Te(m,O,O);c=(O-1)*m.K+1;f=(Q-1)*m.K+1;if(Math.abs(D[e])<Math.abs(n[O])){F=O;for(d=e;F<=Q;F++,d++)l=D[d],D[d]=n[F],n[F]=l;F=1;d=c;for(k=f;F<=
Q;F++,d++,k++)l=ca[d],ca[d]=ca[k],ca[k]=l}Math.abs(D[e])<Ue&&(D[e]=n[O]=0);if(0!=n[O]){l=n[O]/D[e];F=O+1;for(d=e+1;F<=Q;F++,d++)n[F]-=l*D[d];F=1;d=c;for(k=f;F<=Q;F++,d++,k++)ca[k]-=l*ca[d]}}Math.abs(n[Q])<Ue&&(n[Q]=0);D[Te(m,Q,Q)]=n[Q];break;case Fe:Ve(m,O,n)}F=m.K;O=m.i;Q=m.v;D=0;ca=1;for(n=Te(m,ca,ca);ca<=O;ca++,n+=F,F--)0!=Q[n]&&D++;m.pa=D;m.pa!=q&&(r=We);Ce&&Le(m,"scf_update_exp")}switch(r){case We:g.valid=0;b=Ee;break a}t[h+p+1]=y[h+p+1]=h+p+1;E[h+p+1]=C[h+p+1]=h+p+1;F=C[b];W=C[h+p+1];E[F]=h+
p+1;C[h+p+1]=F;E[W]=b;C[b]=W;g.i++;b=0}}switch(b){case Ee:return a.valid=0,a=pd;case LPF_ELIMIT:return a.valid=0,a=te}}a.hg++;return 0}
var Xe="!\"#$%&()/,.;?@_`'{}|~",Ye=exports.glp_read_lp=function(a,b,c){function d(a,b){throw Error(a.count+": "+b);}function e(a,b){x(a.count+": warning: "+b)}function f(a){var b;"\n"==a.l&&a.count++;b=a.Qg();0>b?"\n"==a.l?(a.count--,b=-1):(e(a,"missing final end of line"),b="\n"):"\n"!=b&&(0<=" \t\n\v\f\r".indexOf(b)?b=" ":ta(b)&&d(a,"invalid control character "+b.charCodeAt(0)));a.l=b}function g(a){a.h+=a.l;f(a)}function h(a,b){return a.toLowerCase()==b.toLowerCase()?1:0}function k(a){function b(){for(a.b=
Q;va(a.l)||0<=Xe.indexOf(a.l);)g(a);c&&(h(a.h,"minimize")?a.b=y:h(a.h,"minimum")?a.b=y:h(a.h,"min")?a.b=y:h(a.h,"maximize")?a.b=E:h(a.h,"maximum")?a.b=E:h(a.h,"max")?a.b=E:h(a.h,"subject")?" "==a.l&&(f(a),"t"==a.l.toLowerCase()&&(a.b=C,a.h+=" ",g(a),"o"!=a.l.toLowerCase()&&d(a,"keyword `subject to' incomplete"),g(a),ua(a.l)&&d(a,"keyword `"+a.h+a.l+"...' not recognized"))):h(a.h,"such")?" "==a.l&&(f(a),"t"==a.l.toLowerCase()&&(a.b=C,a.h+=" ",g(a),"h"!=a.l.toLowerCase()&&d(a,"keyword `such that' incomplete"),
g(a),"a"!=a.l.toLowerCase()&&d(a,"keyword `such that' incomplete"),g(a),"t"!=a.l.toLowerCase()&&d(a,"keyword `such that' incomplete"),g(a),ua(a.l)&&d(a,"keyword `"+a.h+a.l+"...' not recognized"))):h(a.h,"st")?a.b=C:h(a.h,"s.t.")?a.b=C:h(a.h,"st.")?a.b=C:h(a.h,"bounds")?a.b=D:h(a.h,"bound")?a.b=D:h(a.h,"general")?a.b=H:h(a.h,"generals")?a.b=H:h(a.h,"gen")?a.b=H:h(a.h,"integer")?a.b=R:h(a.h,"integers")?a.b=R:h(a.h,"int")?a.b=R:h(a.h,"binary")?a.b=V:h(a.h,"binaries")?a.b=V:h(a.h,"bin")?a.b=V:h(a.h,"end")&&
(a.b=O))}var c;a.b=-1;a.h="";for(a.value=0;;){for(c=0;" "==a.l;)f(a);if(-1==a.l)a.b=t;else if("\n"==a.l)if(f(a),ua(a.l))c=1,b();else continue;else if("\\"==a.l){for(;"\n"!=a.l;)f(a);continue}else if(ua(a.l)||"."!=a.l&&0<=Xe.indexOf(a.l))b();else if(wa(a.l)||"."==a.l){for(a.b=F;wa(a.l);)g(a);if("."==a.l)for(g(a),1!=a.h.length||wa(a.l)||d(a,"invalid use of decimal point");wa(a.l);)g(a);if("e"==a.l||"E"==a.l)for(g(a),"+"!=a.l&&"-"!=a.l||g(a),wa(a.l)||d(a,"numeric constant `"+a.h+"' incomplete");wa(a.l);)g(a);
a.value=Number(a.h);a.value==Number.NaN&&d(a,"numeric constant `"+a.h+"' out of range")}else"+"==a.l?(a.b=W,g(a)):"-"==a.l?(a.b=X,g(a)):":"==a.l?(a.b=ca,g(a)):"<"==a.l?(a.b=ka,g(a),"="==a.l&&g(a)):">"==a.l?(a.b=P,g(a),"="==a.l&&g(a)):"="==a.l?(a.b=u,g(a),"<"==a.l?(a.b=ka,g(a)):">"==a.l&&(a.b=P,g(a))):d(a,"character `"+a.l+"' not recognized");break}for(;" "==a.l;)f(a)}function l(a,b){var c=xb(a.Ka,b);if(0==c){c=Oa(a.Ka,1);Qa(a.Ka,c,b);if(a.K<c){var d=a.K,e=a.Z,f=a.j,g=a.ba,h=a.c,k=a.d;a.K+=a.K;a.Z=
new Int32Array(1+a.K);ga(a.Z,1,e,1,d);a.j=new Float64Array(1+a.K);ga(a.j,1,f,1,d);a.ba=new Int8Array(1+a.K);ha(a.ba,1,0,a.K);ga(a.ba,1,g,1,d);a.c=new Float64Array(1+a.K);ga(a.c,1,h,1,d);a.d=new Float64Array(1+a.K);ga(a.d,1,k,1,d)}a.c[c]=+s;a.d[c]=-s}return c}function p(a){for(var b,c=0,e,f,g;;)if(a.b==W?(f=1,k(a)):a.b==X?(f=-1,k(a)):f=1,a.b==F?(g=a.value,k(a)):g=1,a.b!=Q&&d(a,"missing variable name"),b=l(a,a.h),a.ba[b]&&d(a,"multiple use of variable `"+a.h+"' not allowed"),c++,a.Z[c]=b,a.j[c]=f*g,
a.ba[b]=1,k(a),a.b!=W&&a.b!=X){for(b=1;b<=c;b++)a.ba[a.Z[b]]=0;e=0;for(b=1;b<=c;b++)0!=a.j[b]&&(e++,a.Z[e]=a.Z[b],a.j[e]=a.j[b]);break}return e}function m(a,b,c){a.c[b]!=+s&&e(a,"lower bound of variable `"+nb(a.Ka,b)+"' redefined");a.c[b]=c}function q(a,b,c){a.d[b]!=-s&&e(a,"upper bound of variable `"+nb(a.Ka,b)+"' redefined");a.d[b]=c}function r(a){var b,c,e,f;for(k(a);a.b==W||a.b==X||a.b==F||a.b==Q;)a.b==W||a.b==X?(c=1,f=a.b==W?1:-1,k(a),a.b==F?(e=f*a.value,k(a)):h(a.h,"infinity")||h(a.h,"inf")?
(0<f&&d(a,"invalid use of `+inf' as lower bound"),e=-s,k(a)):d(a,"missing lower bound")):a.b==F?(c=1,e=a.value,k(a)):c=0,c&&(a.b!=ka&&d(a,"missing `<', `<=', or `=<' after lower bound"),k(a)),a.b!=Q&&d(a,"missing variable name"),b=l(a,a.h),c&&m(a,b,e),k(a),a.b==ka?(k(a),a.b==W||a.b==X?(f=a.b==W?1:-1,k(a),a.b==F?(q(a,b,f*a.value),k(a)):h(a.h,"infinity")||h(a.h,"inf")?(0>f&&d(a,"invalid use of `-inf' as upper bound"),q(a,b,+s),k(a)):d(a,"missing upper bound")):a.b==F?(q(a,b,a.value),k(a)):d(a,"missing upper bound")):
a.b==P?(c&&d(a,"invalid bound definition"),k(a),a.b==W||a.b==X?(f=a.b==W?1:-1,k(a),a.b==F?(m(a,b,f*a.value),k(a)):h(a.h,"infinity")||0==h(a.h,"inf")?(0<f&&d(a,"invalid use of `+inf' as lower bound"),m(a,b,-s),k(a)):d(a,"missing lower bound")):a.b==F?(m(a,b,a.value),k(a)):d(a,"missing lower bound")):a.b==u?(c&&d(a,"invalid bound definition"),k(a),a.b==W||a.b==X?(f=a.b==W?1:-1,k(a),a.b==F?(m(a,b,f*a.value),q(a,b,f*a.value),k(a)):d(a,"missing fixed value")):a.b==F?(m(a,b,a.value),q(a,b,a.value),k(a)):
d(a,"missing fixed value")):h(a.h,"free")?(c&&d(a,"invalid bound definition"),m(a,b,-s),q(a,b,+s),k(a)):c||d(a,"invalid bound definition")}function n(a){var b,c;a.b==H?(c=0,k(a)):a.b==R?(c=0,k(a)):a.b==V&&(c=1,k(a));for(;a.b==Q;)b=l(a,a.h),Hc(a.Ka,b,Fc),c&&(m(a,b,0),q(a,b,1)),k(a)}var t=0,y=1,E=2,C=3,D=4,H=5,R=6,V=7,O=8,Q=9,F=10,W=11,X=12,ca=13,ka=14,P=15,u=16,z={};x("Reading problem data");null==b&&(b={});z.Ka=a;z.p=b;z.Qg=c;z.count=0;z.l="\n";z.b=t;z.h="";z.value=0;z.K=100;z.Z=new Int32Array(1+
z.K);z.j=new Float64Array(1+z.K);z.ba=new Int8Array(1+z.K);ha(z.ba,1,0,z.K);z.c=new Float64Array(1+z.K);z.d=new Float64Array(1+z.K);db(a);vb(a);k(z);z.b!=y&&z.b!=E&&d(z,"`minimize' or `maximize' keyword missing");(function(a){var b,c;a.b==y?Fa(a.Ka,za):a.b==E&&Fa(a.Ka,Ea);k(a);a.b==Q&&":"==a.l?(Da(a.Ka,a.h),k(a),k(a)):Da(a.Ka,"obj");c=p(a);for(b=1;b<=c;b++)Xa(a.Ka,a.Z[b],a.j[b])})(z);z.b!=C&&d(z,"constraints section missing");(function(a){var b,c,e;for(k(a);b=La(a.Ka,1),a.b==Q&&":"==a.l?(0!=wb(a.Ka,
a.h)&&d(a,"constraint `"+a.h+"' multiply defined"),Pa(a.Ka,b,a.h),k(a),k(a)):Pa(a.Ka,b,"r."+a.count),c=p(a),Ya(a.Ka,b,c,a.Z,a.j),a.b==ka?(e=Ta,k(a)):a.b==P?(e=Sa,k(a)):a.b==u?(e=B,k(a)):d(a,"missing constraint sense"),a.b==W?(c=1,k(a)):a.b==X?(c=-1,k(a)):c=1,a.b!=F&&d(a,"missing right-hand side"),Va(a.Ka,b,e,c*a.value,c*a.value),"\n"!=a.l&&-1!=a.l&&d(a,"invalid symbol(s) beyond right-hand side"),k(a),a.b==W||a.b==X||a.b==F||a.b==Q;);})(z);for(z.b==D&&r(z);z.b==H||z.b==R||z.b==V;)n(z);z.b==O?k(z):
z.b==t?e(z,"keyword `end' missing"):d(z,"symbol "+z.h+" in wrong position");z.b!=t&&d(z,"extra symbol(s) detected beyond `end'");var L,v;for(b=1;b<=a.i;b++)L=z.c[b],v=z.d[b],L==+s&&(L=0),v==-s&&(v=+s),c=L==-s&&v==+s?Ka:v==+s?Sa:L==-s?Ta:L!=v?I:B,Wa(z.Ka,b,c,L,v);x(a.g+" row"+(1==a.g?"":"s")+", "+a.i+" column"+(1==a.i?"":"s")+", "+a.L+" non-zero"+(1==a.L?"":"s"));0<Jc(a)&&(b=Jc(a),c=Kc(a),1==b?0==c?x("One variable is integer"):x("One variable is binary"):(L=b+" integer variables, ",x((0==c?L+"none":
1==c?L+"one":c==b?L+"all":L+c)+" of which "+(1==c?"is":"are")+" binary")));x(z.count+" lines were read");yb(a);$a(a);return 0};
exports.glp_write_lp=function(a,b,c){function d(a){if("."==a[0]||wa(a[0]))return 1;for(var b=0;b<a.length;b++)if(!va(a[b])&&0>Xe.indexOf(a[b]))return 1;return 0}function e(a){for(var b=0;b<a.length;b++)" "==a[b]?a[b]="_":"-"==a[b]?a[b]="~":"["==a[b]?a[b]="(":"]"==a[b]&&(a[b]=")")}function f(a,b){var c;c=0==b?ib(a.Ka):mb(a.Ka,b);if(null==c)return 0==b?"obj":"r_"+b;e(c);return d(c)?0==b?"obj":"r_"+b:c}function g(a,b){var c=nb(a.Ka,b);if(null==c)return"x_"+b;e(c);return d(c)?"x_"+b:c}function h(){c("End");
r++;x(r+" lines were written");return 0}var k={},l,p,m,q,r,n;x("Writing problem data");null==b&&(b={});k.Ka=a;k.p=b;r=0;c("\\* Problem: "+(null==a.name?"Unknown":a.name)+" *\\");r++;c("");r++;if(!(0<a.g&&0<a.i))return x("Warning: problem has no rows/columns"),c("\\* WARNING: PROBLEM HAS NO ROWS/COLUMNS *\\"),r++,c(""),r++,h();a.dir==za?(c("Minimize"),r++):a.dir==Ea&&(c("Maximize"),r++);b=f(k,0);n=" "+b+":";p=0;for(m=1;m<=a.i;m++)if(l=a.f[m],0!=l.u||null==l.k)p++,b=g(k,m),q=0==l.u?" + 0 "+b:1==l.u?
" + "+b:-1==l.u?" - "+b:0<l.u?" + "+l.u+" "+b:" - "+-l.u+" "+b,72<n.length+q.length&&(c(n),n="",r++),n+=q;0==p&&(q=" 0 "+g(k,1),n+=q);c(n);r++;0!=a.ha&&(c("\\* constant term = "+a.ha+" *\\"),r++);c("");r++;c("Subject To");r++;for(m=1;m<=a.g;m++)if(l=a.n[m],l.type!=Ka){b=f(k,m);n=" "+b+":";for(p=l.k;null!=p;p=p.B)b=g(k,p.f.C),q=1==p.j?" + "+b:-1==p.j?" - "+b:0<p.j?" + "+p.j+" "+b:" - "+-p.j+" "+b,72<n.length+q.length&&(c(n),n="",r++),n+=q;l.type==I?(q=" - ~r_"+m,72<n.length+q.length&&(c(n),n="",r++),
n+=q):null==l.k&&(q=" 0 "+g(k,1),n+=q);if(l.type==Sa)q=" >= "+l.c;else if(l.type==Ta)q=" <= "+l.d;else if(l.type==I||l.type==B)q=" = "+l.c;72<n.length+q.length&&(c(n),n="",r++);n+=q;c(n);r++}c("");r++;q=0;for(m=1;m<=a.g;m++)l=a.n[m],l.type==I&&(q||(c("Bounds"),q=1,r++),c(" 0 <= ~r_"+m+" <= "+(l.d-l.c)),r++);for(m=1;m<=a.i;m++)if(l=a.f[m],l.type!=Sa||0!=l.c)q||(c("Bounds"),q=1,r++),b=g(k,m),l.type==Ka?(c(" "+b+" free"),r++):l.type==Sa?(c(" "+b+" >= "+l.c),r++):l.type==Ta?(c(" -Inf <= "+b+" <= "+l.d),
r++):l.type==I?(c(" "+l.c+" <= "+b+" <= "+l.d),r++):l.type==B&&(c(" "+b+" = "+l.c),r++);q&&c("");r++;q=0;for(m=1;m<=a.i;m++)l=a.f[m],l.kind!=Ma&&(q||(c("Generals"),q=1,r++),c(" "+g(k,m)),r++);q&&(c(""),r++);return h()};exports.glp_read_lp_from_string=function(a,b,c){var d=0;return Ye(a,b,function(){return d<c.length?c[d++]:-1})};var ze=1,Be=2,Pe=3,Qe=4,Re=5;
function He(a,b,c){var d=a.Pb,e=a.Ze,f=a.af,g=a.$e,h=a.ia.wb,k=a.ia.xb,l,p,m;a.valid||w("fhv_h_solve: the factorization is not valid");if(b)for(b=d;1<=b;b--){if(a=e[b],m=c[a],0!=m)for(l=f[b],p=l+g[b]-1;l<=p;l++)c[h[l]]-=k[l]*m}else for(b=1;b<=d;b++){a=e[b];m=c[a];l=f[b];for(p=l+g[b]-1;l<=p;l++)m-=k[l]*c[h[l]];c[a]=m}}
function Oe(a,b,c,d,e,f){var g=a.g,h=a.ia,k=h.Fc,l=h.Ec,p=h.pd,m=h.Af,q=h.Dc,r=h.Cc,n=h.Rc,t=h.kb,y=h.vb,E=h.sf,C=h.me,D=h.wb,H=h.xb,R=h.ze,V=h.Mb,O=a.Ze,Q=a.af,F=a.$e,W=a.je,X=a.ie,ca=a.ug,ka=a.vg,P=a.ic,u,z;a.valid||w("fhv_update_it: the factorization is not valid");1<=b&&b<=g||w("fhv_update_it: j = "+b+"; column number out of range");if(a.Pb==a.$d)return a.valid=0,a=Qe;for(u=1;u<=g;u++)ka[u]=0;for(z=1;z<=c;z++)u=d[e+z],1<=u&&u<=g||w("fhv_update_it: ind["+z+"] = "+u+"; row number out of range"),
0!=ka[u]&&w("fhv_update_it: ind["+z+"] = "+u+"; duplicate row index not allowed"),0==f[z]&&w("fhv_update_it: val["+z+"] = "+f[z]+"; zero element not allowed"),ka[u]=f[z];a.ia.kb=W;a.ia.vb=X;Ge(a.ia,0,ka);a.ia.kb=t;a.ia.vb=y;He(a,0,ka);c=0;for(u=1;u<=g;u++)e=ka[u],0==e||Math.abs(e)<V||(c++,ca[c]=u,ka[c]=e);X=q[b];for(W=X+r[b]-1;X<=W;X++){u=D[X];f=k[u];for(z=f+l[u]-1;D[f]!=b;f++);D[f]=D[z];H[f]=H[z];l[u]--}h.Qb-=r[b];r[b]=0;e=E[b];d=0;for(z=1;z<=c;z++){u=ca[z];if(l[u]+1>p[u]&&Ze(h,u,l[u]+10))return a.valid=
0,h.Va=h.Ga+h.Ga,a=Re;f=k[u]+l[u];D[f]=b;H[f]=ka[z];l[u]++;d<y[u]&&(d=y[u])}if(n[b]<c&&$e(h,b,c))return a.valid=0,h.Va=h.Ga+h.Ga,a=Re;X=q[b];ga(D,X,ca,1,c);ga(H,X,ka,1,c);r[b]=c;h.Qb+=c;if(e>d)return a.valid=0,a=ze;u=t[e];b=C[e];for(z=e;z<d;z++)t[z]=t[z+1],y[t[z]]=z,C[z]=C[z+1],E[C[z]]=z;t[d]=u;y[u]=d;C[d]=b;E[b]=d;for(b=1;b<=g;b++)R[b]=0;f=k[u];for(z=f+l[u]-1;f<=z;f++){b=D[f];R[b]=H[f];X=q[b];for(W=X+r[b]-1;D[X]!=u;X++);D[X]=D[W];H[X]=H[W];r[b]--}h.Qb-=l[u];l[u]=0;a.Pb++;O[a.Pb]=u;F[a.Pb]=0;if(h.Ma-
h.Fa<d-e&&(af(h),h.Ma-h.Fa<d-e))return a.valid=h.valid=0,h.Va=h.Ga+h.Ga,a=Re;for(z=e;z<d;z++)if(b=t[z],c=C[z],0!=R[c]){y=R[c]/m[b];E=k[b];for(c=E+l[b]-1;E<=c;E++)R[D[E]]-=y*H[E];h.Ma--;D[h.Ma]=b;H[h.Ma]=y;F[a.Pb]++}0==F[a.Pb]?a.Pb--:(Q[a.Pb]=h.Ma,a.ag+=F[a.Pb]);m[u]=R[C[d]];c=0;for(z=d+1;z<=g;z++)if(b=C[z],e=R[b],!(Math.abs(e)<V)){if(r[b]+1>n[b]&&$e(h,b,r[b]+10))return a.valid=0,h.Va=h.Ga+h.Ga,a=Re;X=q[b]+r[b];D[X]=u;H[X]=e;r[b]++;c++;ca[c]=b;ka[c]=e}if(p[u]<c&&Ze(h,u,c))return a.valid=0,h.Va=h.Ga+
h.Ga,a=Re;f=k[u];ga(D,f,ca,1,c);ga(H,f,ka,1,c);l[u]=c;h.Qb+=c;e=0;u=t[d];f=k[u];for(z=f+l[u]-1;f<=z;f++)e<Math.abs(H[f])&&(e=Math.abs(H[f]));b=C[d];X=q[b];for(W=X+r[b]-1;X<=W;X++)e<Math.abs(H[X])&&(e=Math.abs(H[X]));return Math.abs(m[u])<P*e?(a.valid=0,a=Pe):0}
function ic(a){function b(a,b,c,d,k,l){var p,m,q,r,n,t,y,E,C,D,H,R,V,O,Q=0;0<a&&0<b||w("triang: m = "+a+"; n = "+b+"; invalid dimension");p=new Int32Array(1+(a>=b?a:b));m=new Int32Array(1+a);q=new Int32Array(1+b);r=new Int32Array(1+a);n=new Int32Array(1+a);y=new Int32Array(1+b);E=new Int32Array(1+b);for(D=1;D<=b;D++)H=d(c,-D,p),y[D]=m[H],m[H]=D;for(H=t=0;H<=a;H++)for(D=m[H];0!=D;D=y[D])E[D]=t,t=D;H=0;for(D=t;0!=D;D=E[D])y[D]=H,H=D;for(C=1;C<=a;C++)m[C]=H=d(c,+C,p),r[C]=0,n[C]=q[H],0!=n[C]&&(r[n[C]]=
C),q[H]=C;for(C=1;C<=a;C++)k[C]=0;for(D=1;D<=b;D++)l[D]=0;R=1;for(V=b;R<=V;){C=q[1];if(0!=C){D=0;for(O=d(c,+C,p);1<=O;O--)H=p[O],0==l[H]&&(D=H);k[C]=l[D]=R;R++;Q++}else D=t,l[D]=V,V--;0==y[D]?t=E[D]:E[y[D]]=E[D];0!=E[D]&&(y[E[D]]=y[D]);for(O=d(c,-D,p);1<=O;O--)C=p[O],H=m[C],0==r[C]?q[H]=n[C]:n[r[C]]=n[C],0!=n[C]&&(r[n[C]]=r[C]),m[C]=--H,r[C]=0,n[C]=q[H],0!=n[C]&&(r[n[C]]=C),q[H]=C}for(C=1;C<=a;C++)0==k[C]&&(k[C]=R++);for(D=1;D<=b;D++);for(r=1;r<=a;r++)m[r]=0;for(C=1;C<=a;C++)r=k[C],m[r]=C;for(H=1;H<=
b;H++)q[H]=0;for(D=1;D<=b;D++)H=l[D],q[H]=D;for(r=1;r<=Q;r++)for(C=m[r],O=d(c,+C,p);1<=O;O--);return Q}function c(a,b,c){var d=kb(a);lb(a);var k,l,p,m=0;if(0<b){k=+b;p=ub(a,k,c,null);for(b=1;b<=p;b++)bf(a,c[b],function(a){a!=cf&&(c[++m]=d+c[b])});df(a,k,function(a){a!=cf&&(c[++m]=k)})}else l=-b,p=function(b){b!=cf&&(l<=d?c[++m]=l:m=gb(a,l-d,c,null))},l<=d?df(a,l,p):bf(a,l-d,p);return m}function d(a){var d=kb(a),g=lb(a),h,k,l,p,m,q,r,n=new Int32Array(1+d+g);x("Constructing initial basis...");if(0==
d||0==g)Hb(a);else{m=new Int32Array(1+d);k=new Int32Array(1+d+g);p=b(d,d+g,a,c,m,k);3<=ef(a)&&x("Size of triangular part = "+p+"");q=new Int32Array(1+d);r=new Int32Array(1+d+g);for(h=1;h<=d;h++)q[m[h]]=h;for(h=1;h<=d+g;h++)r[k[h]]=h;for(l=1;l<=d+g;l++)n[l]=-1;for(k=1;k<=p;k++)h=r[k],n[h]=ff;for(k=p+1;k<=d;k++)h=q[k],n[h]=ff;for(l=1;l<=d+g;l++)n[l]!=ff&&(p=function(a,b,c){switch(a){case gf:n[l]=hf;break;case jf:n[l]=kf;break;case lf:n[l]=mf;break;case nf:n[l]=Math.abs(b)<=Math.abs(c)?kf:mf;break;case cf:n[l]=
of}},l<=d?df(a,l,p):bf(a,l-d,p));for(l=1;l<=d+g;l++)l<=d?Fb(a,l,n[l]-ff+A):Gb(a,l-d,n[l]-ff+A)}}0==a.g||0==a.i?Hb(a):d(a)}
function Mc(a,b){var c,d;if(0==a.Sc)for(c=a.fe,d=a.ya,a.fe=0==c?20:c+c,a.ya=Array(1+a.fe),ia(a.ya,0,1+a.fe),null!=d&&ga(a.ya,1,d,1,c),d=a.fe;d>c;d--)a.ya[d].rb=null,a.ya[d].e=a.Sc,a.Sc=d;d=a.Sc;a.Sc=a.ya[d].e;a.ya[d].e=0;c=d;d={};a.ya[c].rb=d;d.s=c;d.R=b;d.La=null==b?0:b.La+1;d.count=0;d.Na=null;d.zc=null;d.ec=null;d.eg=0;d.rc=null==b?a.A.dir==za?-s:+s:b.rc;d.bound=null==b?a.A.dir==za?-s:+s:b.bound;d.Tc=0;d.tg=0;d.Ag=0;d.Zc=0;d.Rd=0;d.data=0==a.p.Me?null:{};d.ja=null;d.ca=a.Xa;d.e=null;null==a.head?
a.head=d:a.Xa.e=d;a.Xa=d;a.Pd++;a.Zf++;a.Jg++;null!=b&&b.count++;return d}
function pf(a,b){var c=a.A,d,e,f,g;d=a.ya[b].rb;a.N=d;e=a.ya[1].rb;if(d!=e){for(d.ja=null;null!=d;d=d.R)null!=d.R&&(d.R.ja=d);for(d=e;null!=d;d=d.ja){var h=c.g;e=c.i;if(null==d.ja){a.Fg=h;a.Gg<h+e&&(f=h+e+100,a.Gg=f,a.qf=new Int8Array(1+f),a.of=new Float64Array(1+f),a.rf=new Float64Array(1+f),a.pf=new Int8Array(1+f));for(f=1;f<=h;f++)g=c.n[f],a.qf[f]=g.type,a.of[f]=g.c,a.rf[f]=g.d,a.pf[f]=g.m;for(f=1;f<=e;f++)g=c.f[f],a.qf[c.g+f]=g.type,a.of[c.g+f]=g.c,a.rf[c.g+f]=g.d,a.pf[c.g+f]=g.m}for(f=d.Na;null!=
f;f=f.e)f.pc<=h?Va(c,f.pc,f.type,f.c,f.d):Wa(c,f.pc-h,f.type,f.c,f.d);for(f=d.zc;null!=f;f=f.e)f.pc<=h?Fb(c,f.pc,f.m):Gb(c,f.pc-h,f.m);if(null!=d.ec){var k,l,h=new Int32Array(1+e);l=new Float64Array(1+e);for(e=d.ec;null!=e;e=e.e){f=La(c,1);Pa(c,f,e.name);c.n[f].La=d.La;c.n[f].origin=e.origin;c.n[f].qc=e.qc;Va(c,f,e.type,e.c,e.d);k=0;for(g=e.k;null!=g;g=g.e)k++,h[k]=g.C,l[k]=g.j;Ya(c,f,k,h,l);zb(c,f,e.ma);Fb(c,f,e.m)}}}for(d=a.N;null!=d.Na;)f=d.Na,d.Na=f.e;for(;null!=d.zc;)f=d.zc,d.zc=f.e;for(;null!=
d.ec;)for(e=d.ec,d.ec=e.e;null!=e.k;)g=e.k,e.k=g.e}}
function qf(a){var b=a.A,c=b.g,d=b.i,e=a.N,f,g,h;if(null==e.R)for(a.Ig=c,a.se=new Int8Array(1+c+d),a.qe=new Float64Array(1+c+d),a.te=new Float64Array(1+c+d),a.re=new Int8Array(1+c+d),f=1;f<=c+d;f++)h=f<=c?b.n[f]:b.f[f-c],a.se[f]=h.type,a.qe[f]=h.c,a.te[f]=h.d,a.re[f]=h.m;else{var k=a.Ig,l=a.Fg;for(f=1;f<=l+d;f++){var p,m,q,r,n,t;p=a.qf[f];q=a.of[f];r=a.rf[f];g=a.pf[f];h=f<=l?b.n[f]:b.f[f-l];m=h.type;n=h.c;t=h.d;h=h.m;if(p!=m||q!=n||r!=t)p={},p.pc=f,p.type=m,p.c=n,p.d=t,p.e=e.Na,e.Na=p;g!=h&&(g={},
g.pc=f,g.m=h,g.e=e.zc,e.zc=g)}if(l<c)for(m=new Int32Array(1+d),n=new Float64Array(1+d),g=c;g>l;g--){h=b.n[g];t={};f=mb(b,g);t.name=null==f?null:f;t.type=h.type;t.c=h.c;t.d=h.d;t.k=null;p=ub(b,g,m,n);for(f=1;f<=p;f++)q={},q.C=m[f],q.j=n[f],q.e=t.k,t.k=q;t.ma=h.ma;t.m=h.m;t.e=e.ec;e.ec=t}if(c!=k){c-=k;e=new Int32Array(1+c);for(g=1;g<=c;g++)e[g]=k+g;ab(b,c,e)}c=b.g;for(g=1;g<=c;g++)Va(b,g,a.se[g],a.qe[g],a.te[g]),Fb(b,g,a.re[g]);for(k=1;k<=d;k++)Wa(b,k,a.se[c+k],a.qe[c+k],a.te[c+k]),Gb(b,k,a.re[c+k])}a.N=
null}function rf(a,b,c){var d;b=a.ya[b].rb;null==b.ca?a.head=b.e:b.ca.e=b.e;null==b.e?a.Xa=b.ca:b.e.ca=b.ca;b.ca=b.e=null;a.Pd--;for(d=1;2>=d;d++)c[d]=Mc(a,b).s}
function sf(a,b){var c;c=a.ya[b].rb;null==c.ca?a.head=c.e:c.ca.e=c.e;null==c.e?a.Xa=c.ca:c.e.ca=c.ca;c.ca=c.e=null;for(a.Pd--;;){for(var d;null!=c.Na;)d=c.Na,c.Na=d.e;for(;null!=c.zc;)d=c.zc,c.zc=d.e;for(;null!=c.ec;){d=c.ec;for(d.name=null;null!=d.k;)d.k=d.k.e;c.ec=d.e}b=c.s;a.ya[b].rb=null;a.ya[b].e=a.Sc;a.Sc=b;c=c.R;a.Zf--;if(null!=c&&(c.count--,0==c.count))continue;break}}
function tf(a,b,c){var d=a.A,e=d.g,f,g,h,k,l=a.Bg,p=a.Tg,m,q;xc(d);Ib(d);a=d.f[b].r;b=Bd(d,e+b,l,p);for(f=-1;1>=f;f+=2)if(h=l,g=Fd(d,b,h,p,f,1E-9),g=0==g?0:h[g],0==g)d.dir==za?0>f?m=+s:q=+s:d.dir==Ea&&(0>f?m=-s:q=-s);else{for(h=1;h<=b&&l[h]!=g;h++);h=p[h];g<=e?(k=d.n[g].m,g=d.n[g].J):(k=d.f[g-e].m,g=d.f[g-e].J);if(d.dir==za){if(k==G&&0>g||k==Ua&&0<g||k==Ra)g=0}else d.dir==Ea&&(k==G&&0<g||k==Ua&&0>g||k==Ra)&&(g=0);k=(0>f?Math.floor(a):Math.ceil(a))-a;k/=h;h=g*k;0>f?m=d.aa+h:q=d.aa+h}c(m,q)}
function uf(a,b){var c=a.A,d=c.i,e,f,g,h=a.Bg,k;g=0;k=c.ha;e=0;for(f=1;f<=d;f++){var l=c.f[f];if(0!=l.u)if(l.type==B)k+=l.u*l.r;else{if(l.kind!=Fc||l.u!=Math.floor(l.u))return b;2147483647>=Math.abs(l.u)?h[++g]=Math.abs(l.u)|0:e=1}}if(0==e){if(0==g)return b;d=0;for(e=1;e<=g;e++){if(1==e)d=h[1];else for(f=h[e],l=void 0;0<f;)l=d%f,d=f,f=l;if(1==d)break}e=d}c.dir==za?b!=+s&&(c=(b-k)/e,c>=Math.floor(c)+0.001&&(c=Math.ceil(c),b=e*c+k)):c.dir==Ea&&b!=-s&&(c=(b-k)/e,c<=Math.ceil(c)-0.001&&(c=Math.floor(c),
b=e*c+k));return b}function vf(a,b){var c=a.A,d=1,e;if(c.za==dc)switch(e=a.p.we*(1+Math.abs(c.ta)),c.dir){case za:b>=c.ta-e&&(d=0);break;case Ea:b<=c.ta+e&&(d=0)}else switch(c.dir){case za:b==+s&&(d=0);break;case Ea:b==-s&&(d=0)}return d}function wf(a){var b=null;switch(a.A.dir){case za:for(a=a.head;null!=a;a=a.e)if(null==b||b.bound>a.bound)b=a;break;case Ea:for(a=a.head;null!=a;a=a.e)if(null==b||b.bound<a.bound)b=a}return null==b?0:b.s}
var xf=exports.glp_ios_relative_gap=function(a){var b=a.A,c;b.za==dc?(b=b.ta,c=wf(a),0==c?a=0:(a=a.ya[c].rb.bound,a=Math.abs(b-a)/(Math.abs(b)+2.220446049250313E-16))):a=s;return a};function yf(a){var b=a.A,c=new kc;switch(a.p.o){case lc:c.o=lc;break;case Lb:c.o=Lb;break;case fc:case Wb:c.o=fc;break;case mc:c.o=Wb}c.cb=Qb;c.fb=a.p.o<mc?a.p.fb:0;if(b.za==dc)switch(a.A.dir){case za:c.jf=b.ta;break;case Ea:c.hf=b.ta}b=sc(b,c);a.N.eg++;return b}
function Oc(a){for(;null!=a.head;){var b=a.head;for(a.head=b.e;null!=b.k;)b.k=b.k.e}a.size=0;a.head=a.Xa=null;a.fh=0;a.N=null}
function zf(a,b){function c(a,b,c,d,e){var f,g,h;g=h=0;for(f=1;f<=a;f++)if(0<b[f])if(c[f]==-s)if(0==g)g=f;else{h=-s;g=0;break}else h+=b[f]*c[f];else if(0>b[f])if(d[f]==+s)if(0==g)g=f;else{h=-s;g=0;break}else h+=b[f]*d[f];e.Wd=h;e.Uf=g;g=h=0;for(f=1;f<=a;f++)if(0<b[f])if(d[f]==+s)if(0==g)g=f;else{h=+s;g=0;break}else h+=b[f]*d[f];else if(0>b[f])if(c[f]==-s)if(0==g)g=f;else{h=+s;g=0;break}else h+=b[f]*c[f];e.Vd=h;e.Tf=g}function d(a,b){b(0==a.Uf?a.Wd:-s,0==a.Tf?a.Vd:+s)}function e(a,b,c,d,e,f,g,h){var k,
l,m,n;c==-s||a.Vd==+s?k=-s:0==a.Tf?0<b[g]?k=c-(a.Vd-b[g]*f[g]):0>b[g]&&(k=c-(a.Vd-b[g]*e[g])):k=a.Tf==g?c-a.Vd:-s;d==+s||a.Wd==-s?l=+s:0==a.Uf?0<b[g]?l=d-(a.Wd-b[g]*e[g]):0>b[g]&&(l=d-(a.Wd-b[g]*f[g])):l=a.Uf==g?d-a.Wd:+s;1E-6>Math.abs(b[g])?(m=-s,n=+s):0<b[g]?(m=k==-s?-s:k/b[g],n=l==+s?+s:l/b[g]):0>b[g]&&(m=l==+s?-s:l/b[g],n=k==-s?+s:k/b[g]);h(m,n)}function f(a,b,c,e,f){var g=0,h=b[c],k=e[f],l=null,m=null;d(a,function(a,b){l=a;m=b});if(h!=-s&&(a=0.001*(1+Math.abs(h)),m<h-a)||k!=+s&&(a=0.001*(1+Math.abs(k)),
l>k+a))return 1;h!=-s&&(a=1E-12*(1+Math.abs(h)),l>h-a&&(b[c]=-s));k!=+s&&(a=1E-12*(1+Math.abs(k)),m<k+a&&(e[f]=+s));return g}function g(a,b,c,d,f,g,h,k,l){var m=0,n,q,p=null,r=null;n=f[k];q=g[k];e(a,b,c,d,f,g,k,function(a,b){p=a;r=b});h&&(p!=-s&&(p=0.001>p-Math.floor(p)?Math.floor(p):Math.ceil(p)),r!=+s&&(r=0.001>Math.ceil(r)-r?Math.ceil(r):Math.floor(r)));if(n!=-s&&(a=0.001*(1+Math.abs(n)),r<n-a)||q!=+s&&(a=0.001*(1+Math.abs(q)),p>q+a))return 1;p!=-s&&(a=0.001*(1+Math.abs(p)),n<p-a&&(n=p));r!=+s&&
(a=0.001*(1+Math.abs(r)),q>r+a&&(q=r));n!=-s&&q!=+s&&(a=Math.abs(n),b=Math.abs(q),n>q-1E-10*(1+(a<=b?a:b))&&(n==f[k]?q=n:q==g[k]?n=q:a<=b?q=n:n=q));l(n,q);return m}function h(a,b,c,d,e){var f,g=0;b<d&&(a||b==-s?g++:(f=c==+s?1+Math.abs(b):1+(c-b),d-b>=0.25*f&&g++));c>e&&(a||c==+s?g++:(f=b==-s?1+Math.abs(c):1+(c-b),c-e>=0.25*f&&g++));return g}var k=a.A,l=k.g,p=k.i,m,q,r,n=0,t,y,E,C;t=new Float64Array(1+l);y=new Float64Array(1+l);switch(k.za){case Aa:t[0]=-s;y[0]=+s;break;case dc:switch(k.dir){case za:t[0]=
-s;y[0]=k.ta-k.ha;break;case Ea:t[0]=k.ta-k.ha,y[0]=+s}}for(m=1;m<=l;m++)t[m]=pb(k,m),y[m]=qb(k,m);E=new Float64Array(1+p);C=new Float64Array(1+p);for(m=1;m<=p;m++)E[m]=sb(k,m),C[m]=tb(k,m);q=l+1;r=new Int32Array(1+q);for(m=1;m<=q;m++)r[m]=m-1;if(function(a,b,d,e,k,l,m,n){var q=a.g,p=a.i,r={},t,u,E=0,C,v,y,M,ba,J,ea,fa;C=new Int32Array(1+p);v=new Int32Array(1+q+1);y=new Int32Array(1+q+1);M=new Int32Array(1+q+1);ba=new Float64Array(1+p);J=new Float64Array(1+p);ea=new Float64Array(1+p);u=0;for(t=1;t<=
l;t++)q=m[t],v[++u]=q,y[q]=1;for(;0<u;)if(q=v[u--],y[q]=0,M[q]++,b[q]!=-s||d[q]!=+s){l=0;if(0==q)for(m=1;m<=p;m++)fa=a.f[m],0!=fa.u&&(l++,C[l]=m,ba[l]=fa.u);else for(m=a.n[q].k;null!=m;m=m.B)l++,C[l]=m.f.C,ba[l]=m.j;for(t=1;t<=l;t++)m=C[t],J[t]=e[m],ea[t]=k[m];c(l,ba,J,ea,r);if(f(r,b,q,d,q)){E=1;break}if(b[q]!=-s||d[q]!=+s)for(t=1;t<=l;t++){var sa,K=null,oa=null;m=C[t];fa=a.f[m];sa=fa.kind!=Ma;if(g(r,ba,b[q],d[q],J,ea,sa,t,function(a,b){K=a;oa=b}))return E=1;sa=h(sa,e[m],k[m],K,oa);e[m]=K;k[m]=oa;
if(0<sa)for(m=fa.k;null!=m;m=m.I)fa=m.n.ea,M[fa]>=n||b[fa]==-s&&d[fa]==+s||0!=y[fa]||(v[++u]=fa,y[fa]=1)}}return E}(k,t,y,E,C,q,r,b))return 1;for(m=1;m<=l;m++)zc(k,m)==A&&(t[m]==-s&&y[m]==+s?Va(k,m,Ka,0,0):y[m]==+s?Va(k,m,Sa,t[m],0):t[m]==-s&&Va(k,m,Ta,0,y[m]));for(m=1;m<=p;m++)Wa(k,m,E[m]==-s&&C[m]==+s?Ka:C[m]==+s?Sa:E[m]==-s?Ta:E[m]!=C[m]?I:B,E[m],C[m]);return n}
function Nc(a){function b(a,b){var c,d,e,f;d=a.A.za==dc?String(a.A.ta):"not found yet";c=wf(a);0==c?e="tree is empty":(c=a.ya[c].rb.bound,e=c==-s?"-inf":c==+s?"+inf":c);a.A.dir==za?f=">=":a.A.dir==Ea&&(f="<=");c=xf(a);x("+"+a.A.$+": "+(b?">>>>>":"mip =")+" "+d+" "+f+" "+e+" "+(0==c?" 0.0%":0.001>c?" < 0.1%":9.999>=c?" "+Number(100*c).toFixed(1)+"%":"")+" ("+a.Pd+"; "+(a.Jg-a.Zf)+")");a.Lg=ja()}function c(a,b){return vf(a,a.ya[b].rb.bound)}function d(a){var b=a.A,c,d,e=0,f,g,h,k,l,m=0;for(c=1;c<=
b.i;c++)if(h=b.f[c],a.ad[c]=0,h.kind==Fc&&h.m==A){d=h.type;f=h.c;g=h.d;h=h.r;if(d==Sa||d==I||d==B){k=f-a.p.Ub;l=f+a.p.Ub;if(k<=h&&h<=l)continue;if(h<f)continue}if(d==Ta||d==I||d==B){k=g-a.p.Ub;l=g+a.p.Ub;if(k<=h&&h<=l)continue;if(h>g)continue}k=Math.floor(h+0.5)-a.p.Ub;l=Math.floor(h+0.5)+a.p.Ub;k<=h&&h<=l||(a.ad[c]=1,e++,k=h-Math.floor(h),l=Math.ceil(h)-h,m+=k<=l?k:l)}a.N.Ag=e;a.N.Zc=m;a.p.o>=mc&&(0==e?x("There are no fractional columns"):1==e?x("There is one fractional column, integer infeasibility is "+
m+""):x("There are "+e+" fractional columns, integer infeasibility is "+m+""))}function e(a){var b=a.A,c;b.za=dc;b.ta=b.aa;for(c=1;c<=b.g;c++){var d=b.n[c];d.Sa=d.r}for(c=1;c<=b.i;c++)d=b.f[c],d.kind==Ma?d.Sa=d.r:d.kind==Fc&&(d.Sa=Math.floor(d.r+0.5));a.qh++}function f(a,b,c){var d=a.A,e,f=d.g,g,h,k,l,m,n=Array(3),q,p,r,t,y=null,v=null,S;g=d.f[b].type;q=d.f[b].c;p=d.f[b].d;e=d.f[b].r;r=Math.floor(e);t=Math.ceil(e);switch(g){case Ka:h=Ta;k=Sa;break;case Sa:h=q==r?B:I;k=Sa;break;case Ta:h=Ta;k=t==p?
B:I;break;case I:h=q==r?B:I,k=t==p?B:I}tf(a,b,function(a,b){y=a;v=b});g=uf(a,y);S=uf(a,v);l=!vf(a,g);m=!vf(a,S);if(l&&m)return a.p.o>=mc&&x("Both down- and up-branches are hopeless"),2;if(m)return a.p.o>=mc&&x("Up-branch is hopeless"),Wa(d,b,h,q,r),a.N.rc=y,d.dir==za?a.N.bound<g&&(a.N.bound=g):d.dir==Ea&&a.N.bound>g&&(a.N.bound=g),1;if(l)return a.p.o>=mc&&x("Down-branch is hopeless"),Wa(d,b,k,t,p),a.N.rc=v,d.dir==za?a.N.bound<S&&(a.N.bound=S):d.dir==Ea&&a.N.bound>S&&(a.N.bound=S),1;a.p.o>=mc&&x("Branching on column "+
b+", primal value is "+e+"");l=a.N.s;a.N.Tc=b;a.N.tg=e;qf(a);rf(a,l,n);a.p.o>=mc&&x("Node "+n[1]+" begins down branch, node "+n[2]+" begins up branch ");e=a.ya[n[1]].rb;e.Na={};e.Na.pc=f+b;e.Na.type=h;e.Na.c=q;e.Na.d=r;e.Na.e=null;e.rc=y;d.dir==za?e.bound<g&&(e.bound=g):d.dir==Ea&&e.bound>g&&(e.bound=g);e=a.ya[n[2]].rb;e.Na={};e.Na.pc=f+b;e.Na.type=k;e.Na.c=t;e.Na.d=p;e.Na.e=null;e.rc=v;d.dir==za?e.bound<S&&(e.bound=S):d.dir==Ea&&e.bound>S&&(e.bound=S);c==Af?a.ud=0:c==Bf?a.ud=n[1]:c==Cf&&(a.ud=n[2]);
return 0}function g(a){var b=a.A,c,d,e=0,f,g,h,k;f=b.aa;for(c=1;c<=b.i;c++)if(k=b.f[c],k.kind==Fc)switch(g=k.c,h=k.d,d=k.m,k=k.J,b.dir){case za:d==G?(0>k&&(k=0),f+k>=b.ta&&(Wa(b,c,B,g,g),e++)):d==Ua&&(0<k&&(k=0),f-k>=b.ta&&(Wa(b,c,B,h,h),e++));break;case Ea:d==G?(0<k&&(k=0),f+k<=b.ta&&(Wa(b,c,B,g,g),e++)):d==Ua&&(0>k&&(k=0),f-k<=b.ta&&(Wa(b,c,B,h,h),e++))}a.p.o>=mc&&0!=e&&(1==e?x("One column has been fixed by reduced cost"):x(e+" columns have been fixed by reduced costs"))}function h(a){var b,c=0,
d=null;for(b=a.wc+1;b<=a.A.g;b++)a.A.n[b].origin==Ja&&a.A.n[b].La==a.N.La&&a.A.n[b].m==A&&(null==d&&(d=new Int32Array(1+a.A.g)),d[++c]=b);0<c&&(ab(a.A,c,d),Jb(a.A))}function k(a){var b=a.A,c,d=0,e=0,f=0,g=0,h=0;for(c=b.g;0<c;c--){var k=b.n[c];k.origin==Ja&&(k.qc==Df?d++:k.qc==Ef?e++:k.qc==Ff?f++:k.qc==Gf?g++:h++)}0<d+e+f+g+h&&(x("Cuts on level "+a.N.La+":"),0<d&&x(" gmi = "+d+";"),0<e&&x(" mir = "+e+";"),0<f&&x(" cov = "+f+";"),0<g&&x(" clq = "+g+";"),0<h&&x(" app = "+h+";"),x(""))}function l(a){if(a.p.Ed==
bb||a.p.Ad==bb||a.p.xd==bb||a.p.vd==bb){var b,c,d;c=a.i;1E3>c&&(c=1E3);d=0;for(b=a.wc+1;b<=a.A.g;b++)a.A.n[b].origin==Ja&&d++;if(!(d>=c)){a.p.Ad==bb&&5>a.N.Rd&&Hf(a);a.p.Ed==bb&&If(a,a.Xf);if(a.p.xd==bb){b=a.A;c=kb(b);var e=lb(b),f,g,h,k,l;xc(b);d=new Int32Array(1+e);k=new Float64Array(1+e);l=new Float64Array(1+e);for(e=1;e<=c;e++)for(h=1;2>=h;h++){g=ob(b,e)-Ka+gf;if(1==h){if(g!=lf&&g!=nf)continue;g=ub(b,e,d,k);k[0]=Jf(b,e)}else{if(g!=jf&&g!=nf)continue;g=ub(b,e,d,k);for(f=1;f<=g;f++)k[f]=-k[f];k[0]=
-Kf(b,e)}a:{var m=b;f=d;for(var n=k,q=l,p=null,r=null,t=Array(5),y=void 0,v=void 0,S=void 0,M=S=void 0,ba=void 0,J=M=M=void 0,S=0,v=1;v<=g;v++)y=f[v],rb(m,y)-Ka+gf==cf?n[0]-=n[v]*Lf(m,y):(S++,f[S]=f[v],n[S]=n[v]);g=S;S=0;for(v=1;v<=g;v++)y=f[v],(Ic(m,y)==Ma?Mf:Nf)==Nf&&rb(m,y)-Ka+gf==nf&&0==Lf(m,y)&&1==Of(m,y)&&(S++,ba=f[S],M=n[S],f[S]=f[v],n[S]=n[v],f[v]=ba,n[v]=M);if(2>S)g=0;else{ba=M=0;for(v=S+1;v<=g;v++){y=f[v];if(rb(m,y)-Ka+gf!=nf){g=0;break a}0<n[v]?(ba+=n[v]*Lf(m,y),M+=n[v]*Of(m,y)):(ba+=n[v]*
Of(m,y),M+=n[v]*Lf(m,y))}M-=ba;J=0;for(v=S+1;v<=g;v++)y=f[v],J+=n[v]*Dc(m,y);J-=ba;0>J&&(J=0);J>M&&(J=M);n[0]-=ba;for(v=1;v<=S;v++)y=f[v],q[v]=Dc(m,y),0>q[v]&&(q[v]=0),1<q[v]&&(q[v]=1);for(v=1;v<=S;v++)0>n[v]&&(f[v]=-f[v],n[v]=-n[v],n[0]+=n[v],q[v]=1-q[v]);m=S;v=n[0];y=J;J=void 0;for(J=1;J<=m;J++);for(J=1;J<=m;J++);J=void 0;b:{for(var ea=J=void 0,fa=0,sa=0,K=void 0,oa=void 0,Bb=0.001,K=0.001*(1+Math.abs(v)),J=1;J<=m;J++)for(ea=J+1;ea<=m;ea++){fa++;if(1E3<fa){J=sa;break b}n[J]+n[ea]+y>v+K&&(oa=n[J]+
n[ea]-v,p=1/(oa+M),r=2-p*oa,oa=q[J]+q[ea]+p*y-r,Bb<oa&&(Bb=oa,t[1]=J,t[2]=ea,sa=1))}J=sa}ea=void 0;if(J)ea=2;else{J=J=void 0;b:{for(var fa=ea=J=void 0,K=sa=0,Bb=oa=void 0,ec=0.001,oa=0.001*(1+Math.abs(v)),J=1;J<=m;J++)for(ea=J+1;ea<=m;ea++)for(fa=ea+1;fa<=m;fa++){sa++;if(1E3<sa){J=K;break b}n[J]+n[ea]+n[fa]+y>v+oa&&(Bb=n[J]+n[ea]+n[fa]-v,p=1/(Bb+M),r=3-p*Bb,Bb=q[J]+q[ea]+q[fa]+p*y-r,ec<Bb&&(ec=Bb,t[1]=J,t[2]=ea,t[3]=fa,K=1))}J=K}if(J)J=3;else{J=void 0;b:{for(var sa=fa=ea=J=void 0,oa=K=0,ec=Bb=void 0,
Wj=0.001,Bb=0.001*(1+Math.abs(v)),J=1;J<=m;J++)for(ea=J+1;ea<=m;ea++)for(fa=ea+1;fa<=m;fa++)for(sa=fa+1;sa<=m;sa++){K++;if(1E3<K){J=oa;break b}n[J]+n[ea]+n[fa]+n[sa]+y>v+Bb&&(ec=n[J]+n[ea]+n[fa]+n[sa]-v,p=1/(ec+M),r=4-p*ec,ec=q[J]+q[ea]+q[fa]+q[sa]+p*y-r,Wj<ec&&(Wj=ec,t[1]=J,t[2]=ea,t[3]=fa,t[4]=sa,oa=1))}J=oa}J=J?4:0}ea=J}M=ea;if(0==M)g=0;else{f[0]=0;n[0]=r;for(y=1;y<=M;y++)t[y]=f[t[y]];for(v=1;v<=M;v++)0<t[v]?(f[v]=+t[v],n[v]=1):(f[v]=-t[v],n[v]=-1,n[0]-=1);for(v=S+1;v<=g;v++)M++,f[M]=f[v],n[M]=
p*n[v];n[0]+=p*ba;g=M}}}if(0!=g){f=b;n=g;q=d;p=k;r=lb(f);S=t=void 0;ba=0;0>n&&w("lpx_eval_row: len = "+n+"; invalid row length");for(S=1;S<=n;S++)t=q[S],1<=t&&t<=r||w("lpx_eval_row: j = "+t+"; column number out of range"),ba+=p[S]*Dc(f,t);f=ba-k[0];0.001>f||Id(a,Ff,g,d,k,Ta,k[0])}}}a.p.vd==bb&&null!=a.Ne&&(0==a.N.La&&50>a.N.Rd||0<a.N.La&&5>a.N.Rd)&&(c=a.Ne,d=lb(a.A),b=new Int32Array(1+d),d=new Float64Array(1+d),c=Pf(a.A,c,b,d),0<c&&Id(a,Gf,c,b,d,Ta,d[0]))}}}function p(a){var b,d,e=0;for(b=a.head;null!=
b;b=d)d=b.e,c(a,b.s)||(sf(a,b.s),e++);a.p.o>=mc&&(1==e?x("One hopeless branch has been pruned"):1<e&&x(e+" hopeless branches have been pruned"))}var m,q,r,n,t=0,y=a.hc;for(q=0;;){r=null;switch(q){case 0:if(null==a.head){a.p.o>=mc&&x("Active list is empty!");n=0;r=3;break}if(null!=a.p.ob&&(a.reason=Qf,a.p.ob(a,a.p.Uc),a.reason=0,a.stop)){n=Rc;r=3;break}0==a.gf&&(a.gf=1==a.Pd?a.head.s:0!=a.ud?a.ud:Rf(a));pf(a,a.gf);a.gf=a.ud=0;null!=a.N.R&&a.N.R.s!=t&&(t=0);m=a.N.s;a.p.o>=mc&&(x("------------------------------------------------------------------------"),
x("Processing node "+m+" at level "+a.N.La+""));1==m&&(a.p.Ad==bb&&a.p.o>=Wb&&x("Gomory's cuts enabled"),a.p.Ed==bb&&(a.p.o>=Wb&&x("MIR cuts enabled"),a.Xf=Sf(a)),a.p.xd==bb&&a.p.o>=Wb&&x("Cover cuts enabled"),a.p.vd==bb&&(a.p.o>=Wb&&x("Clique cuts enabled"),a.Ne=Tf(a.A)));case 1:(a.p.o>=mc||a.p.o>=fc&&a.p.bc-1<=1E3*la(a.Lg))&&b(a,0);a.p.o>=Wb&&60<=la(y)&&(x("Time used: "+la(a.hc)+" secs"),y=ja());if(0<a.p.ce&&xf(a)<=a.p.ce){a.p.o>=mc&&x("Relative gap tolerance reached; search terminated ");n=Pc;
r=3;break}if(2147483647>a.p.sb&&a.p.sb-1<=1E3*la(a.hc)){a.p.o>=mc&&x("Time limit exhausted; search terminated");n=Qc;r=3;break}if(null!=a.p.ob&&(a.reason=Uf,a.p.ob(a,a.p.Uc),a.reason=0,a.stop)){n=Rc;r=3;break}if(a.p.ed!=hd)if(a.p.ed==id){if(0==a.N.La&&zf(a,100)){r=2;break}}else if(a.p.ed==jd&&zf(a,0==a.N.La?100:10)){r=2;break}if(!c(a,m)){x("*** not tested yet ***");r=2;break}a.p.o>=mc&&x("Solving LP relaxation...");n=yf(a);if(0!=n&&n!=Vf&&n!=Wf){a.p.o>=Lb&&x("ios_driver: unable to solve current LP relaxation; glp_simplex returned "+
n+"");n=Sb;r=3;break}q=a.A.na;r=a.A.sa;if(q==dc&&r==dc)a.p.o>=mc&&x("Found optimal solution to LP relaxation");else if(r==jc){a.p.o>=Lb&&x("ios_driver: current LP relaxation has no dual feasible solution");n=Sb;r=3;break}else if(q==Ad&&r==dc){a.p.o>=mc&&x("LP relaxation has no solution better than incumbent objective value");r=2;break}else if(q==jc){a.p.o>=mc&&x("LP relaxation has no feasible solution");r=2;break}q=a.N.rc=a.A.aa;q=uf(a,q);a.A.dir==za?a.N.bound<q&&(a.N.bound=q):a.A.dir==Ea&&a.N.bound>
q&&(a.N.bound=q);a.p.o>=mc&&x("Local bound is "+q+"");if(!c(a,m)){a.p.o>=mc&&x("Current branch is hopeless and can be pruned");r=2;break}if(null!=a.p.ob){a.reason=Ga;a.p.ob(a,a.p.Uc);a.reason=0;if(a.stop){n=Rc;r=3;break}if(a.pe){a.pe=a.tf=0;r=1;break}a.tf&&(a.tf=0,Jb(a.A))}d(a);if(0==a.N.Ag){a.p.o>=mc&&x("New integer feasible solution found");a.p.o>=Wb&&k(a);e(a);a.p.o>=fc&&b(a,1);if(null!=a.p.ob&&(a.reason=Xf,a.p.ob(a,a.p.Uc),a.reason=0,a.stop)){n=Rc;r=3;break}r=2;break}a.A.za==dc&&g(a);if(null!=
a.p.ob){a.reason=Yf;a.p.ob(a,a.p.Uc);a.reason=0;if(a.stop){n=Rc;r=3;break}if(!c(a,m)){a.p.o>=mc&&x("Current branch became hopeless and can be pruned");r=2;break}}if(a.p.Xe&&(a.reason=Yf,Zf(a),a.reason=0,!c(a,m))){a.p.o>=mc&&x("Current branch became hopeless and can be pruned");r=2;break}if(null!=a.p.ob&&(a.reason=Ia,a.p.ob(a,a.p.Uc),a.reason=0,a.stop)){n=Rc;r=3;break}if(0==a.N.La||0==t)a.reason=Ia,l(a),a.reason=0;0<a.Bd.size&&(a.reason=Ia,$f(a),a.reason=0);Oc(a.Bd);if(a.pe){a.pe=0;a.N.Rd++;r=1;break}h(a);
a.p.o>=Wb&&0==a.N.La&&k(a);null!=a.Fd&&ag(a);if(null!=a.p.ob&&(a.reason=bg,a.p.ob(a,a.p.Uc),a.reason=0,a.stop)){n=Rc;r=3;break}0==a.Tc&&(a.Tc=cg(a,function(b){a.Jf=b}));q=a.N.s;n=f(a,a.Tc,a.Jf);a.Tc=a.Jf=0;if(0==n){t=q;r=0;break}else if(1==n){a.N.eg=a.N.Rd=0;r=1;break}else if(2==n){r=2;break}case 2:a.p.o>=mc&&x("Node "+m+" fathomed");qf(a);sf(a,m);a.A.za==dc&&p(a);r=t=0;break;case 3:return a.p.o>=fc&&b(a,0),a.Xf=null,a.Ne=null,n}if(null==r)break;q=r}}
function dg(a){var b;b={};b.i=a;b.L=0;b.Ja=new Int32Array(1+a);b.Z=new Int32Array(1+a);b.j=new Float64Array(1+a);return b}function eg(a,b,c){var d=a.Ja[b];0==c?0!=d&&(a.Ja[b]=0,d<a.L&&(a.Ja[a.Z[a.L]]=d,a.Z[d]=a.Z[a.L],a.j[d]=a.j[a.L]),a.L--):(0==d&&(d=++a.L,a.Ja[b]=d,a.Z[d]=b),a.j[d]=c)}function fg(a){for(var b=1;b<=a.L;b++)a.Ja[a.Z[b]]=0;a.L=0}
function gg(a,b){for(var c=0,d=1;d<=a.L;d++)0==Math.abs(a.j[d])||Math.abs(a.j[d])<b?a.Ja[a.Z[d]]=0:(c++,a.Ja[a.Z[d]]=c,a.Z[c]=a.Z[d],a.j[c]=a.j[d]);a.L=c}function hg(a,b){fg(a);a.L=b.L;ga(a.Z,1,b.Z,1,a.L);ga(a.j,1,b.j,1,a.L);for(var c=1;c<=a.L;c++)a.Ja[a.Z[c]]=c}
function Hf(a){function b(a){return a-Math.floor(a)}function c(a,c,d){var e=a.A,f=e.g,g=e.i,h=c.Z,k=c.j;c=c.kh;var l,D,H,R,V,O,Q,F,W,X,ca;D=Bd(e,f+d,h,k);F=e.f[d].r;for(l=1;l<=f+g;l++)c[l]=0;ca=b(F);for(d=1;d<=D;d++){l=h[d];l<=f?(R=e.n[l],H=Ma):(R=e.f[l-f],H=R.kind);V=R.c;O=R.d;R=R.m;W=k[d];if(1E5<Math.abs(W))return;if(!(1E-10>Math.abs(W))){switch(R){case Ra:return;case G:Q=-W;break;case Ua:Q=+W;break;case Na:continue}switch(H){case Fc:if(1E-10>Math.abs(Q-Math.floor(Q+0.5)))continue;else X=b(Q)<=
b(F)?b(Q):b(F)/(1-b(F))*(1-b(Q));break;case Ma:X=0<=Q?+Q:b(F)/(1-b(F))*-Q}switch(R){case G:c[l]=+X;ca+=X*V;break;case Ua:c[l]=-X,ca-=X*O}}}for(d=1;d<=f;d++)if(!(1E-10>Math.abs(c[d])))for(R=e.n[d],Q=R.k;null!=Q;Q=Q.B)c[f+Q.f.C]+=c[d]*Q.j;D=0;for(d=1;d<=g;d++)1E-10>Math.abs(c[f+d])||(R=e.f[d],R.type==B?ca-=c[f+d]*R.c:(D++,h[D]=d,k[D]=c[f+d]));1E-12>Math.abs(ca)&&(ca=0);for(l=1;l<=D;l++)if(0.001>Math.abs(k[l])||1E3<Math.abs(k[l]))return;Id(a,Df,D,h,k,Sa,ca)}var d=a.A,e=d.g,f=d.i,g,h,k={};g=Array(1+f);
k.Z=new Int32Array(1+f);k.j=new Float64Array(1+f);k.kh=new Float64Array(1+e+f);e=0;for(h=1;h<=f;h++){var l=d.f[h];l.kind==Fc&&l.type!=B&&l.m==A&&(l=b(l.r),0.05<=l&&0.95>=l&&(e++,g[e].C=h,g[e].Nb=l))}ma(g,e,function(a,b){return a.Nb>b.Nb?-1:a.Nb<b.Nb?1:0});f=Hd(a);for(d=1;d<=e&&!(50<=Hd(a)-f);d++)c(a,k,g[d].C)}var ig=0,jg=5,kg=0,lg=1,mg=2;
function Sf(a){var b=a.A,c=b.g,b=b.i,d;ig&&x("ios_mir_init: warning: debug mode enabled");d={};d.g=c;d.i=b;d.Eb=new Int8Array(1+c);d.ab=new Int8Array(1+c+b);d.c=new Float64Array(1+c+b);d.Yb=new Int32Array(1+c+b);d.d=new Float64Array(1+c+b);d.zb=new Int32Array(1+c+b);d.x=new Float64Array(1+c+b);d.Ef=new Int32Array(1+jg);d.Ya=dg(c+b);d.lb=new Int8Array(1+c+b);d.oa=dg(c+b);d.G=dg(c+b);(function(a,b){var c=a.A,d=b.g,k;for(k=1;k<=d;k++){var l=c.n[k];b.Eb[k]=0;b.ab[k]=0;switch(l.type){case Ka:b.c[k]=-s;
b.d[k]=+s;break;case Sa:b.c[k]=l.c;b.d[k]=+s;break;case Ta:b.c[k]=-s;b.d[k]=l.d;break;case I:b.c[k]=l.c;b.d[k]=l.d;break;case B:b.c[k]=b.d[k]=l.c}b.Yb[k]=b.zb[k]=0}})(a,d);(function(a,b){var c=a.A,d=b.g,k=b.i,l;for(l=d+1;l<=d+k;l++){var p=c.f[l-d];switch(p.kind){case Ma:b.ab[l]=0;break;case Fc:b.ab[l]=1}switch(p.type){case Ka:b.c[l]=-s;b.d[l]=+s;break;case Sa:b.c[l]=p.c;b.d[l]=+s;break;case Ta:b.c[l]=-s;b.d[l]=p.d;break;case I:b.c[l]=p.c;b.d[l]=p.d;break;case B:b.c[l]=b.d[l]=p.c}b.Yb[l]=b.zb[l]=0}})(a,
d);(function(a,b){var c=a.A,d=b.g,k,l,p,m,q,r;for(l=1;l<=d;l++)if(0==b.c[l]&&b.d[l]==+s||b.c[l]==-s&&0==b.d[l])if(k=c.n[l].k,null!=k&&(p=d+k.f.C,q=k.j,k=k.B,null!=k&&(m=d+k.f.C,r=k.j,null==k.B))){if(b.ab[p]||!b.ab[m])if(b.ab[p]&&!b.ab[m])m=p,r=q,p=d+k.f.C,q=k.j;else continue;b.c[m]!=-s&&b.d[m]!=+s&&b.c[m]!=b.d[m]&&(0==b.d[l]&&(q=-q,r=-r),0<q?0==b.Yb[p]&&(b.c[p]=-r/q,b.Yb[p]=m,b.Eb[l]=1):0==b.zb[p]&&(b.d[p]=-r/q,b.zb[p]=m,b.Eb[l]=1))}})(a,d);(function(a,b){var c=a.A,d=b.g,k,l,p,m;for(l=1;l<=d;l++)if(b.c[l]==
-s&&b.d[l]==+s)b.Eb[l]=1;else{m=0;for(k=c.n[l].k;null!=k;k=k.B){p=d+k.f.C;if(b.c[p]==-s&&b.d[p]==+s){b.Eb[l]=1;break}if(b.ab[p]&&b.c[p]==-s||b.ab[p]&&b.d[p]==+s){b.Eb[l]=1;break}0==b.Yb[p]&&0==b.zb[p]&&b.c[p]==b.d[p]||m++}0==m&&(b.Eb[l]=1)}})(a,d);return d}
function If(a,b){function c(a,b,c,d,e,f,g){function k(a,b,c,d,e,f,g){var h;h=c;for(c=1;c<=a;c++)g[c]=b[c]/f,e[c]&&(g[c]=-g[c]),h-=b[c]*d[c];b=h/f;var l;if(0.01>Math.abs(b-Math.floor(b+0.5)))b=1;else{h=b-Math.floor(b);for(c=1;c<=a;c++)l=g[c]-Math.floor(g[c])-h,g[c]=0>=l?Math.floor(g[c]):Math.floor(g[c])+l/(1-h);q=Math.floor(b);r=1/(1-h);b=0}if(b)return 1;for(c=1;c<=a;c++)e[c]&&(g[c]=-g[c],q+=g[c]*d[c]);r/=f;return 0}var h,l,m,n,p;m=Array(4);var t,v,y,D;y=new Int8Array(1+a);D=Array(1+a);for(l=1;l<=
a;l++)y[l]=e[l]>=0.5*d[l];v=p=0;for(l=1;l<=a;l++)if(h=1E-9*(1+Math.abs(d[l])),!(e[l]<h||e[l]>d[l]-h||(h=k(a,b,c,d,y,Math.abs(b[l]),g),h))){t=-q-r*f;for(h=1;h<=a;h++)t+=g[h]*e[h];v<t&&(v=t,p=Math.abs(b[l]))}0.001>v&&(v=0);if(0==v)return v;m[1]=p/2;m[2]=p/4;m[3]=p/8;for(l=1;3>=l;l++)if(h=k(a,b,c,d,y,m[l],g),!h){t=-q-r*f;for(h=1;h<=a;h++)t+=g[h]*e[h];v<t&&(v=t,p=m[l])}m=0;for(l=1;l<=a;l++)h=1E-9*(1+Math.abs(d[l])),e[l]<h||e[l]>d[l]-h||(m++,D[m].C=l,D[m].xf=Math.abs(e[l]-0.5*d[l]));ma(D,m,function(a,
b){return a.xf<b.xf?-1:a.xf>b.xf?1:0});for(n=1;n<=m;n++)if(l=D[n].C,y[l]=!y[l],h=k(a,b,c,d,y,p,g),y[l]=!y[l],!h){t=-q-r*f;for(h=1;h<=a;h++)t+=g[h]*e[h];v<t&&(v=t,y[l]=!y[l])}h=k(a,b,c,d,y,p,g);return v}function d(a,b,c){var d=a.A;a=b.g;b.Eb[c]=2;b.Je=1;b.Ef[1]=c;fg(b.Ya);eg(b.Ya,c,1);for(c=d.n[c].k;null!=c;c=c.B)eg(b.Ya,a+c.f.C,-c.j);b.Df=0}function e(a){var b,c;for(b=1;b<=a.Ya.L;b++)c=a.Ya.Z[b],0==a.Yb[c]&&0==a.zb[c]&&a.c[c]==a.d[c]&&(a.Df-=a.Ya.j[b]*a.c[c],a.Ya.j[b]=0);gg(a.Ya,2.220446049250313E-16)}
function f(a){var b,c,d,e;for(b=1;b<=a.Ya.L;b++)c=a.Ya.Z[b],a.ab[c]||(d=a.Yb[c],e=0==d?a.c[c]==-s?s:a.x[c]-a.c[c]:a.x[c]-a.c[c]*a.x[d],d=a.zb[c],d=0==d?a.zb[c]==+s?s:a.d[c]-a.x[c]:a.d[c]*a.x[d]-a.x[c],a.lb[c]=e<=d?lg:mg)}function g(a){var b,c,d,e;hg(a.oa,a.Ya);a.tc=a.Df;for(b=a.oa.L;1<=b;b--)d=a.oa.Z[b],a.ab[d]||(a.lb[d]==lg?(e=a.Yb[d],0==e?a.tc-=a.oa.j[b]*a.c[d]:(c=a.oa.Ja[e],0==c&&(eg(a.oa,e,1),c=a.oa.Ja[e],a.oa.j[c]=0),a.oa.j[c]+=a.oa.j[b]*a.c[d])):a.lb[d]==mg&&(e=a.zb[d],0==e?a.tc-=a.oa.j[b]*
a.d[d]:(c=a.oa.Ja[e],0==c&&(eg(a.oa,e,1),c=a.oa.Ja[e],a.oa.j[c]=0),a.oa.j[c]+=a.oa.j[b]*a.d[d]),a.oa.j[b]=-a.oa.j[b]));for(b=1;b<=a.oa.L;b++)d=a.oa.Z[b],a.ab[d]&&(Math.abs(a.c[d])<=Math.abs(a.d[d])?(a.lb[d]=lg,a.tc-=a.oa.j[b]*a.c[d]):(a.lb[d]=mg,a.tc-=a.oa.j[b]*a.d[d],a.oa.j[b]=-a.oa.j[b]))}function h(a){var b=a.g,d=a.i,e,f,g,h,k,l,m;k=0;hg(a.G,a.oa);a.Lb=a.tc;gg(a.G,2.220446049250313E-16);for(e=1;e<=a.G.L;e++)f=a.G.Z[e],!a.ab[f]&&0<a.G.j[e]&&(a.G.j[e]=0);gg(a.G,0);h=0;for(e=1;e<=a.G.L;e++)f=a.G.Z[e],
a.ab[f]&&(h++,g=a.G.Z[h],a.G.Ja[f]=h,a.G.Ja[g]=e,a.G.Z[h]=f,a.G.Z[e]=g,f=a.G.j[h],a.G.j[h]=a.G.j[e],a.G.j[e]=f);if(0==h)return k;l=new Float64Array(1+h);g=new Float64Array(1+h);m=new Float64Array(1+h);for(e=1;e<=h;e++)f=a.G.Z[e],l[e]=a.d[f]-a.c[f],a.lb[f]==lg?g[e]=a.x[f]-a.c[f]:a.lb[f]==mg&&(g[e]=a.d[f]-a.x[f]),0>g[e]&&(g[e]=0);k=0;for(e=h+1;e<=a.G.L;e++)f=a.G.Z[e],a.lb[f]==lg?(g=a.Yb[f],g=0==g?a.x[f]-a.c[f]:a.x[f]-a.c[f]*a.x[g]):a.lb[f]==mg&&(g=a.zb[f],g=0==g?a.d[f]-a.x[f]:a.d[f]*a.x[g]-a.x[f]),
0>g&&(g=0),k-=a.G.j[e]*g;k=c(h,a.G.j,a.Lb,l,g,k,m);if(0==k)return k;for(e=1;e<=h;e++)a.G.j[e]=m[e];for(e=h+1;e<=a.G.L;e++)f=a.G.Z[e],f<=b+d&&(a.G.j[e]*=0);a.Lb=null;return k}function k(a){var b,c,d,e;for(b=1;b<=a.G.L;b++)d=a.G.Z[b],a.ab[d]&&(a.lb[d]==lg?a.Lb+=a.G.j[b]*a.c[d]:a.lb[d]==mg&&(a.Lb-=a.G.j[b]*a.d[d],a.G.j[b]=-a.G.j[b]));for(b=1;b<=a.G.L;b++)d=a.G.Z[b],a.ab[d]||(a.lb[d]==lg?(e=a.Yb[d],0==e?a.Lb+=a.G.j[b]*a.c[d]:(c=a.G.Ja[e],0==c&&(eg(a.G,e,1),c=a.G.Ja[e],a.G.j[c]=0),a.G.j[c]-=a.G.j[b]*a.c[d])):
a.lb[d]==mg&&(e=a.zb[d],0==e?a.Lb-=a.G.j[b]*a.d[d]:(c=a.G.Ja[e],0==c&&(eg(a.G,e,1),c=a.G.Ja[e],a.G.j[c]=0),a.G.j[c]+=a.G.j[b]*a.d[d]),a.G.j[b]=-a.G.j[b]))}function l(a,b){var c=a.A,d=b.g,e,f,g,h;for(f=b.G.L;1<=f;f--)if(e=b.G.Z[f],!(e>d)){for(e=c.n[e].k;null!=e;e=e.B)g=d+e.f.C,h=b.G.Ja[g],0==h&&(eg(b.G,g,1),h=b.G.Ja[g],b.G.j[h]=0),b.G.j[h]+=b.G.j[f]*e.j;b.G.j[f]=0}gg(b.G,0)}function p(a,b){var c=b.g,d=b.i,e,f,g=new Int32Array(1+d),h=new Float64Array(1+d);f=0;for(d=b.G.L;1<=d;d--)e=b.G.Z[d],f++,g[f]=
e-c,h[f]=b.G.j[d];Id(a,Ef,f,g,h,Ta,b.Lb)}function m(a,b){var c=a.A,d=b.g,e=b.i,f,g,h,k=0,l=0,m,n=0;for(f=1;f<=b.Ya.L;f++)g=b.Ya.Z[f],g<=d||b.ab[g]||0.001>Math.abs(b.Ya.j[f])||(h=b.Yb[g],m=0==h?b.c[g]==-s?s:b.x[g]-b.c[g]:b.x[g]-b.c[g]*b.x[h],h=b.zb[g],h=0==h?b.zb[g]==+s?s:b.d[g]-b.x[g]:b.d[g]*b.x[h]-b.x[g],m=m<=h?m:h,!(0.001>m)&&n<m&&(n=m,k=g));if(0==k)return 1;for(g=1;g<=d;g++)if(!b.Eb[g]){for(f=c.n[g].k;null!=f&&f.f.C!=k-d;f=f.B);if(null!=f&&0.001<=Math.abs(f.j))break}if(g>d)return 2;b.Je++;b.Ef[b.Je]=
g;b.Eb[g]=2;e=dg(d+e);eg(e,g,1);for(f=c.n[g].k;null!=f;f=f.B)eg(e,d+f.f.C,-f.j);f=b.Ya.Ja[k];c=b.Ya;d=-b.Ya.j[f]/e.j[e.Ja[k]];for(g=1;g<=e.L;g++)f=e.Z[g],n=void 0,n=c.Ja[f],n=0==n?0:c.j[n],m=e.j[g],eg(c,f,n+d*m);eg(b.Ya,k,0);return l}var q,r,n=b.g,t=b.i,y,E,C;(function(a,b){var c=a.A,d=b.g,e=b.i,f;for(f=1;f<=d;f++)b.x[f]=c.n[f].r;for(f=d+1;f<=d+e;f++)b.x[f]=c.f[f-d].r})(a,b);ha(b.lb,1,kg,n+t);for(y=1;y<=n;y++)if(!b.Eb[y]){for(d(a,b,y);;){e(b);if(ig)for(E=1;E<=n+t;E++);f(b);g(b);C=h(b);0<C&&(k(b),
l(a,b),p(a,b));for(var D=1;D<=b.oa.L;D++)E=b.oa.Z[D],b.lb[E]=kg;if(!(0==C&&b.Je<jg&&0==m(a,b)))break}for(E=1;E<=b.Je;E++)C=b.Ef[E],b.Eb[C]=0}}
function Tf(a){function b(a,b){var c;switch(ob(a,b)-Ka+gf){case gf:case lf:c=-s;break;case jf:case nf:case cf:c=Kf(a,b)}return c}function c(a,b){var c;switch(ob(a,b)-Ka+gf){case gf:case jf:c=+s;break;case lf:case nf:case cf:c=Jf(a,b)}return c}function d(a,b){var c;switch(rb(a,b)-Ka+gf){case gf:case lf:c=-s;break;case jf:case nf:case cf:c=Lf(a,b)}return c}function e(a,b){var c;switch(rb(a,b)-Ka+gf){case gf:case jf:c=+s;break;case lf:case nf:case cf:c=Of(a,b)}return c}function f(a,b){return(Ic(a,b)==
Ma?Mf:Nf)==Nf&&rb(a,b)-Ka+gf==nf&&0==Lf(a,b)&&1==Of(a,b)}function g(a,b,c,f){var g,h,k;k=0;for(h=1;h<=b;h++)if(g=c[h],0<f[h]){g=d(a,g);if(g==-s){k=-s;break}k+=f[h]*g}else if(0>f[h]){g=e(a,g);if(g==+s){k=-s;break}k+=f[h]*g}return k}function h(a,b,c,f){var g,h,k;k=0;for(h=1;h<=b;h++)if(g=c[h],0<f[h]){g=e(a,g);if(g==+s){k=+s;break}k+=f[h]*g}else if(0>f[h]){g=d(a,g);if(g==-s){k=+s;break}k+=f[h]*g}return k}function k(a,b,c,d,e,f,g,h){b!=-s&&g&&(b-=a[f]);c!=+s&&g&&(c-=a[f]);d!=-s&&(0>a[f]&&(d-=a[f]),0>
a[h]&&(d-=a[h]));e!=+s&&(0<a[f]&&(e-=a[f]),0<a[h]&&(e-=a[h]));f=0<a[h]?b==-s||e==+s?-s:(b-e)/a[h]:c==+s||d==-s?-s:(c-d)/a[h];if(0.001<f)return 2;f=0<a[h]?c==+s||d==-s?+s:(c-d)/a[h]:b==-s||e==+s?+s:(b-e)/a[h];return 0.999>f?1:0}var l=null,p,m,q,r,n,t,y,E,C,D,H,R,V,O,Q,F;x("Creating the conflict graph...");p=kb(a);m=lb(a);q=0;D=new Int32Array(1+m);H=new Int32Array(1+m);C=new Int32Array(1+m);F=new Float64Array(1+m);for(r=1;r<=p;r++)if(R=b(a,r),V=c(a,r),R!=-s||V!=+s)if(E=ub(a,r,C,F),!(500<E))for(O=g(a,
E,C,F),Q=h(a,E,C,F),t=1;t<=E;t++)if(f(a,C[t]))for(y=t+1;y<=E;y++)f(a,C[y])&&(k(F,R,V,O,Q,t,0,y)||k(F,R,V,O,Q,t,1,y))&&(n=C[t],0==D[n]&&(q++,D[n]=q,H[q]=n),n=C[y],0==D[n]&&(q++,D[n]=q,H[q]=n));if(0==q||4E3<q)return x("The conflict graph is either empty or too big"),l;l={};l.i=m;l.Cb=q;l.Dg=0;l.yf=D;l.ge=H;E=q+q;E=(E*(E-1)/2+0)/1;l.Jc=Array(E);for(n=1;n<=q;n++)ng(l,+H[n],-H[n]);for(r=1;r<=p;r++)if(R=b(a,r),V=c(a,r),R!=-s||V!=+s)if(E=ub(a,r,C,F),!(500<E))for(O=g(a,E,C,F),Q=h(a,E,C,F),t=1;t<=E;t++)if(f(a,
C[t]))for(y=t+1;y<=E;y++)if(f(a,C[y])){switch(k(F,R,V,O,Q,t,0,y)){case 1:ng(l,-C[t],+C[y]);break;case 2:ng(l,-C[t],-C[y])}switch(k(F,R,V,O,Q,t,1,y)){case 1:ng(l,+C[t],+C[y]);break;case 2:ng(l,+C[t],-C[y])}}x("The conflict graph has 2*"+l.Cb+" vertices and "+l.Dg+" edges");return l}function ng(a,b,c){var d;0<b?b=a.yf[b]:(b=a.yf[-b],b+=a.Cb);0<c?c=a.yf[c]:(c=a.yf[-c],c+=a.Cb);b<c&&(d=b,b=c,c=d);d=(b-1)*(b-2)/2+(c-1);a.Jc[d/1]|=1<<0-d%1;a.Dg++}
function Pf(a,b,c,d){function e(a,b,c){return b==c?0:b>c?f(a,b*(b-1)/2+c):f(a,c*(c-1)/2+b)}function f(a,b){return a.Jc[b/1]&1<<0-b%1}function g(a,b,c,d,f,h){var k,l,m,n,q,p,r,ca;ca=new Int32Array(a.i);if(0>=b){if(0==b&&(a.set[d++]=c[0],f+=h),f>a.gd)for(a.gd=f,a.bg=d,k=0;k<d;k++)a.oh[k+1]=a.set[k]}else for(k=b;0<=k&&!(0==d&&k<b);k--){m=c[k];if(0<d&&a.wg[m]<=a.gd-f)break;a.set[d]=m;n=f+a.Ic[m+1];h-=a.Ic[m+1];if(h<=a.gd-n)break;for(q=r=p=0;r<c+k;)l=c[r],r++,e(a,l,m)&&(ca[p]=l,p++,q+=a.Ic[l+1]);q<=a.gd-
n||g(a,p-1,ca,d+1,n,q)}}var h=lb(a),k,l,p,m=0,q,r,n;p=new Int32Array(1+2*b.Cb);q=new Int32Array(1+2*b.Cb);n=new Float64Array(1+h);for(l=1;l<=b.Cb;l++)k=b.ge[l],k=Dc(a,k),k=100*k+0.5|0,0>k&&(k=0),100<k&&(k=100),p[l]=k,p[b.Cb+l]=100-k;p=function(a,b,c,d){var f={},h,k,l,m,n,q;f.i=a;f.Ic=b;f.Jc=c;f.gd=0;f.bg=0;f.oh=d;f.wg=new Int32Array(f.i);f.set=new Int32Array(f.i);n=new Int32Array(f.i);q=new Int32Array(f.i);b=new Int32Array(f.i);c=ja();for(a=0;a<f.i;a++)for(h=q[a]=0;h<f.i;h++)e(f,a,h)&&(q[a]+=f.Ic[h+
1]);for(a=0;a<f.i;a++)n[a]=0;for(a=f.i-1;0<=a;a--){m=l=-1;for(h=0;h<f.i;h++)!n[h]&&(f.Ic[h+1]>l||f.Ic[h+1]==l&&q[h]>m)&&(l=f.Ic[h+1],m=q[h],k=h);b[a]=k;n[k]=1;for(h=0;h<f.i;h++)!n[h]&&h!=k&&e(f,k,h)&&(q[h]-=f.Ic[k+1])}for(a=k=0;a<f.i;a++)k+=f.Ic[b[a]+1],g(f,a,b,0,0,k),f.wg[b[a]]=f.gd,4.999<=la(c)&&(x("level = "+a+1+" ("+f.i+"); best = "+f.gd+""),c=ja());for(a=1;a<=f.bg;a++)d[a]++;return f.bg}(2*b.Cb,p,b.Jc,q);r=0;for(l=1;l<=p;l++)k=q[l],k<=b.Cb?(k=b.ge[k],k=Dc(a,k),r+=k):(k=b.ge[k-b.Cb],k=Dc(a,k),
r+=1-k);if(1.01<=r){for(l=a=1;l<=p;l++)k=q[l],k<=b.Cb?(k=b.ge[k],n[k]+=1):(k=b.ge[k-b.Cb],n[k]-=1,a-=1);for(k=1;k<=h;k++)0!=n[k]&&(m++,c[m]=k,d[m]=n[k]);c[0]=0;d[0]=a}return m}
function cg(a,b){var c;if(a.p.Jb==Zc){var d,e;for(d=1;d<=a.i&&!a.ad[d];d++);e=Dc(a.A,d);b(e-Math.floor(e)<Math.ceil(e)-e?Bf:Cf);c=d}else if(a.p.Jb==$c){for(d=a.i;1<=d&&!a.ad[d];d--);e=Dc(a.A,d);b(e-Math.floor(e)<Math.ceil(e)-e?Bf:Cf);c=d}else if(a.p.Jb==ad)c=og(a,b);else if(a.p.Jb==bd){c=a.A;var f=c.g,g=c.i,h=a.ad,k,l,p,m,q,r,n,t,y,E,C,D,H,R;xc(c);n=new Int32Array(1+g);R=new Float64Array(1+g);l=0;H=-1;for(k=1;k<=g;k++)if(h[k]){t=Dc(c,k);r=Bd(c,f+k,n,R);for(q=-1;1>=q;q+=2){p=Fd(c,r,n,R,q,1E-9);0!=
p&&(p=n[p]);if(0==p)p=a.A.dir==za?+s:-s;else{for(m=1;m<=r&&n[m]!=p;m++);m=R[m];y=(0>q?Math.floor(t):Math.ceil(t))-t;y/=m;p>f&&Ic(c,p-f)!=Ma&&0.001<Math.abs(y-Math.floor(y+0.5))&&(y=0<y?Math.ceil(y):Math.floor(y));p<=f?(m=zc(c,p),p=Bc(c,p)):(m=Cc(c,p-f),p=Ec(c,p-f));switch(a.A.dir){case za:if(m==G&&0>p||m==Ua&&0<p||m==Ra)p=0;break;case Ea:if(m==G&&0<p||m==Ua&&0>p||m==Ra)p=0}p*=y}0>q?e=p:E=p}if(H<Math.abs(e)||H<Math.abs(E))if(l=k,Math.abs(e)<Math.abs(E)?(d=Bf,H=Math.abs(E)):(d=Cf,H=Math.abs(e)),C=e,
D=E,H==s)break}H<1E-6*(1+0.001*Math.abs(c.aa))?l=og(a,b):(a.p.o>=mc&&(x("branch_drtom: column "+l+" chosen to branch on"),Math.abs(C)==s?x("branch_drtom: down-branch is infeasible"):x("branch_drtom: down-branch bound is "+(yc(c)+C)+""),Math.abs(D)==s?x("branch_drtom: up-branch is infeasible"):x("branch_drtom: up-branch bound is "+(yc(c)+D)+"")),b(d));c=l}else a.p.Jb==cd&&(c=pg(a,b));return c}
function og(a,b){var c,d,e,f,g,h;d=0;g=s;for(c=1;c<=a.i;c++)a.ad[c]&&(f=Dc(a.A,c),h=Math.floor(f)+0.5,g>Math.abs(f-h)&&(d=c,g=Math.abs(f-h),e=f<h?Bf:Cf));b(e);return d}function qg(a){a=a.i;var b,c={};c.yd=new Int32Array(1+a);c.Ud=new Float64Array(1+a);c.Id=new Int32Array(1+a);c.ye=new Float64Array(1+a);for(b=1;b<=a;b++)c.yd[b]=c.Id[b]=0,c.Ud[b]=c.ye[b]=0;return c}
function ag(a){var b,c,d=a.Fd;null!=a.N.R&&(b=a.N.R.Tc,c=a.A.f[b].r-a.N.R.tg,a=a.A.aa-a.N.R.rc,a=Math.abs(a/c),0>c?(d.yd[b]++,d.Ud[b]+=a):(d.Id[b]++,d.ye[b]+=a))}
function pg(a,b){function c(a,b,c){var d,e;xc(a);d=Ba();hb(d,a,0);Wa(d,b,B,c,c);b=new kc;b.o=lc;b.cb=Tb;b.oc=30;b.fb=1E3;b.cb=Tb;b=sc(d,b);0==b||b==rg?tc(d)==jc?e=s:uc(d)==dc?(a.dir==za?e=d.aa-a.aa:a.dir==Ea&&(e=a.aa-d.aa),e<1E-6*(1+0.001*Math.abs(a.aa))&&(e=0)):e=0:e=0;return e}function d(a,b,d){var e=a.Fd,f;if(d==Bf){if(0==e.yd[b]){d=a.A.f[b].r;a=c(a.A,b,Math.floor(d));if(a==s)return f=s;e.yd[b]=1;e.Ud[b]=a/(d-Math.floor(d))}f=e.Ud[b]/e.yd[b]}else if(d==Cf){if(0==e.Id[b]){d=a.A.f[b].r;a=c(a.A,b,
Math.ceil(d));if(a==s)return f=s;e.Id[b]=1;e.ye[b]=a/(Math.ceil(d)-d)}f=e.ye[b]/e.Id[b]}return f}function e(a){var b=a.Fd,c,d=0,e=0;for(c=1;c<=a.i;c++)Jd(a,c)&&(d++,0<b.yd[c]&&0<b.Id[c]&&e++);x("Pseudocosts initialized for "+e+" of "+d+" variables")}var f=ja(),g,h,k,l,p,m,q;null==a.Fd&&(a.Fd=qg(a));h=0;q=-1;for(g=1;g<=a.i;g++)if(Jd(a,g)){l=a.A.f[g].r;p=d(a,g,Bf);if(p==s)return h=g,k=Bf,b(k),h;m=p*(l-Math.floor(l));p=d(a,g,Cf);if(p==s)return h=g,k=Cf,b(k),h;l=p*(Math.ceil(l)-l);p=m>l?m:l;q<p&&(q=p,
h=g,k=m<=l?Bf:Cf);a.p.o>=bb&&10<=la(f)&&(e(a),f=ja())}if(0==q)return h=og(a,b);b(k);return h}
function Zf(a){var b=a.A,c=b.i,d=null,e=null,f=null,g,h,k,l,p,m,q,r;for(l=0;;){var n=null;switch(l){case 0:xc(b);if(0!=a.N.La||1!=a.N.eg){n=5;break}q=0;for(k=1;k<=c;k++)if(g=b.f[k],g.kind!=Ma&&g.type!=B)if(g.type==I&&0==g.c&&1==g.d)q++;else{a.p.o>=Wb&&x("FPUMP heuristic cannot be applied due to general integer variables");n=5;break}if(null!=n)break;if(0==q){n=5;break}a.p.o>=Wb&&x("Applying FPUMP heuristic...");e=Array(1+q);ia(e,1,q);l=0;for(k=1;k<=c;k++)g=b.f[k],g.kind==Fc&&g.type==I&&(e[++l].C=k);
d=Ba();case 1:hb(d,b,cb);if(b.za==dc){La(d,1);p=new Int32Array(1+c);m=new Float64Array(1+c);for(k=1;k<=c;k++)p[k]=k,m[k]=b.f[k].u;Ya(d,d.g,c,p,m);p=0.1*b.aa+0.9*b.ta;b.dir==za?Va(d,d.g,Ta,0,p-b.ha):b.dir==Ea&&Va(d,d.g,Sa,p-b.ha,0)}m=0;for(l=1;l<=q;l++)e[l].x=-1;case 2:if(m++,a.p.o>=Wb&&x("Pass "+m+""),r=s,p=0,1<m){null==f&&(f=sg());for(l=1;l<=q;l++)k=e[l].C,g=d.f[k],n=tg(f),0>n&&(n=0),g=Math.abs(e[l].x-g.r),0.5<g+n&&(e[l].x=1-e[l].x);n=4;break}case 3:for(l=h=1;l<=q;l++)g=d.f[e[l].C],g=0.5>g.r?0:1,
e[l].x!=g&&(h=0,e[l].x=g);if(h){for(l=1;l<=q;l++)g=d.f[e[l].C],e[l].Td=Math.abs(g.r-e[l].x);ma(e,q,function(a,b){return a.Td>b.Td?-1:a.Td<b.Td?1:0});for(l=1;l<=q&&!(5<=l&&0.35>e[l].Td||10<=l);l++)e[l].x=1-e[l].x}case 4:if(2147483647>a.p.sb&&a.p.sb-1<=1E3*la(a.hc)){n=5;break}d.dir=za;d.ha=0;for(k=1;k<=c;k++)d.f[k].u=0;for(l=1;l<=q;l++)k=e[l].C,0==e[l].x?d.f[k].u=1:(d.f[k].u=-1,d.ha+=1);h=new kc;a.p.o<=Lb?h.o=a.p.o:a.p.o<=Wb&&(h.o=fc,h.fb=1E4);l=sc(d,h);if(0!=l){a.p.o>=Lb&&x("Warning: glp_simplex returned "+
l+"");n=5;break}l=xc(d);if(l!=vc){a.p.o>=Lb&&x("Warning: glp_get_status returned "+l+"");n=5;break}a.p.o>=mc&&x("delta = "+d.aa+"");k=0.3*a.p.Ub;for(l=1;l<=q&&!(g=d.f[e[l].C],k<g.r&&g.r<1-k);l++);if(l>q){g=new Float64Array(1+c);for(k=1;k<=c;k++)g[k]=d.f[k].r,b.f[k].kind==Fc&&(g[k]=Math.floor(g[k]+0.5));d.ha=b.ha;d.dir=b.dir;for(l=1;l<=q;l++)d.f[e[l].C].c=g[e[l].C],d.f[e[l].C].d=g[e[l].C],d.f[e[l].C].type=B;for(k=1;k<=c;k++)d.f[k].u=b.f[k].u;l=sc(d,h);if(0!=l){a.p.o>=Lb&&x("Warning: glp_simplex returned "+
l+"");n=5;break}l=xc(d);if(l!=vc){a.p.o>=Lb&&x("Warning: glp_get_status returned "+l+"");n=5;break}for(k=1;k<=c;k++)b.f[k].kind!=Fc&&(g[k]=d.f[k].r);l=Kd(a,g);if(0==l){n=vf(a,a.N.bound)?1:5;break}}r==s||d.aa<=r-1E-6*(1+r)?(p=0,r=d.aa):p++;if(3>p){n=3;break}5>m&&(n=2)}if(null==n)break;l=n}}
function $f(a){function b(a,b,c){var d,e=0,f=0,g=0;for(d=a.k;null!=d;d=d.e)c[d.C]=d.j,f+=d.j*d.j;for(d=b.k;null!=d;d=d.e)e+=c[d.C]*d.j,g+=d.j*d.j;for(d=a.k;null!=d;d=d.e)c[d.C]=0;a=Math.sqrt(f)*Math.sqrt(g);4.930380657631324E-32>a&&(a=2.220446049250313E-16);return e/a}var c,d,e,f,g,h,k,l,p,m;c=a.Bd;f=Array(1+c.size);l=new Int32Array(1+a.i);p=new Float64Array(1+a.i);m=new Float64Array(1+a.i);g=0;for(d=c.head;null!=d;d=d.e)g++,f[g].Re=d,f[g].ba=0;for(g=1;g<=c.size;g++){var q=null,r=null;d=f[g].Re;h=
k=0;for(e=d.k;null!=e;e=e.e)k++,l[k]=e.C,p[k]=e.j,h+=e.j*e.j;4.930380657631324E-32>h&&(h=2.220446049250313E-16);k=Dd(a.A,k,l,p);d=Gd(a.A,k,l,p,d.type,d.cg,function(a,b,c,d,e,f){q=e;r=f});0==d?(f[g].Xc=Math.abs(q)/Math.sqrt(h),a.A.dir==za?(0>r&&(r=0),f[g].Ab=+r):(0<r&&(r=0),f[g].Ab=-r)):1==d?f[g].Xc=f[g].Ab=0:2==d&&(f[g].Xc=1,f[g].Ab=s);0.01>f[g].Ab&&(f[g].Ab=0)}ma(f,c.size,function(a,b){if(0==a.Ab&&0==b.Ab){if(a.Xc>b.Xc)return-1;if(a.Xc<b.Xc)return 1}else{if(a.Ab>b.Ab)return-1;if(a.Ab<b.Ab)return 1}return 0});
h=0==a.N.La?90:10;h>c.size&&(h=c.size);for(g=1;g<=h;g++)if(!(0.01>f[g].Ab&&0.01>f[g].Xc)){for(c=1;c<g&&!(f[c].ba&&0.9<b(f[g].Re,f[c].Re,m));c++);if(!(c<g)){d=f[g].Re;f[g].ba=1;c=La(a.A,1);null!=d.name&&Pa(a.A,c,d.name);a.A.n[c].qc=d.qc;k=0;for(e=d.k;null!=e;e=e.e)k++,l[k]=e.C,p[k]=e.j;Ya(a.A,c,k,l,p);Va(a.A,c,d.type,d.cg,d.cg)}}}
function Rf(a){function b(a){var b,c;b=0;c=s;for(a=a.head;null!=a;a=a.e)c>a.R.Zc&&(b=a.s,c=a.R.Zc);return b}function c(a){var b,c,d,e,p;b=a.ya[1].rb;e=(a.A.ta-b.bound)/b.Zc;c=0;d=s;for(b=a.head;null!=b;b=b.e)p=b.R.bound+e*b.R.Zc,a.A.dir==Ea&&(p=-p),d>p&&(c=b.s,d=p);return c}function d(a){var b,c=null,d,e;switch(a.A.dir){case za:d=+s;for(b=a.head;null!=b;b=b.e)d>b.bound&&(d=b.bound);e=0.001*(1+Math.abs(d));for(b=a.head;null!=b;b=b.e)b.bound<=d+e&&(null==c||c.R.Zc>b.R.Zc)&&(c=b);break;case Ea:d=-s;
for(b=a.head;null!=b;b=b.e)d<b.bound&&(d=b.bound);e=0.001*(1+Math.abs(d));for(b=a.head;null!=b;b=b.e)b.bound>=d-e&&(null==c||c.rc<b.rc)&&(c=b)}return c.s}var e;a.p.kc==dd?e=a.Xa.s:a.p.kc==ed?e=a.head.s:a.p.kc==fd?e=d(a):a.p.kc==gd&&(e=a.A.za==Aa?b(a):c(a));return e}
var pa=exports.GLP_MAJOR_VERSION=4,qa=exports.GLP_MINOR_VERSION=49,za=exports.GLP_MIN=1,Ea=exports.GLP_MAX=2,Ma=exports.GLP_CV=1,Fc=exports.GLP_IV=2,Gc=exports.GLP_BV=3,Ka=exports.GLP_FR=1,Sa=exports.GLP_LO=2,Ta=exports.GLP_UP=3,I=exports.GLP_DB=4,B=exports.GLP_FX=5,A=exports.GLP_BS=1,G=exports.GLP_NL=2,Ua=exports.GLP_NU=3,Ra=exports.GLP_NF=4,Na=exports.GLP_NS=5,Uc=exports.GLP_SF_GM=1,Vc=exports.GLP_SF_EQ=16,Wc=exports.GLP_SF_2N=32,Xc=exports.GLP_SF_SKIP=64,hc=exports.GLP_SF_AUTO=128,Zb=exports.GLP_SOL=
1,le=exports.GLP_IPT=2,Sc=exports.GLP_MIP=3,Aa=exports.GLP_UNDEF=1,dc=exports.GLP_FEAS=2,Ad=exports.GLP_INFEAS=3,jc=exports.GLP_NOFEAS=4,vc=exports.GLP_OPT=5,wc=exports.GLP_UNBND=6,md=exports.GLP_BF_FT=1,rd=exports.GLP_BF_BG=2,sd=exports.GLP_BF_GR=3,lc=exports.GLP_MSG_OFF=0,Lb=exports.GLP_MSG_ERR=1,fc=exports.GLP_MSG_ON=2,Wb=exports.GLP_MSG_ALL=3,mc=exports.GLP_MSG_DBG=4,Ob=exports.GLP_PRIMAL=1,Qb=exports.GLP_DUALP=2,Tb=exports.GLP_DUAL=3,nc=exports.GLP_PT_STD=17,oc=exports.GLP_PT_PSE=34,pc=exports.GLP_RT_STD=
17,qc=exports.GLP_RT_HAR=34;exports.GLP_ORD_NONE=0;exports.GLP_ORD_QMD=1;exports.GLP_ORD_AMD=2;exports.GLP_ORD_SYMAMD=3;var Zc=exports.GLP_BR_FFV=1,$c=exports.GLP_BR_LFV=2,ad=exports.GLP_BR_MFV=3,bd=exports.GLP_BR_DTH=4,cd=exports.GLP_BR_PCH=5,dd=exports.GLP_BT_DFS=1,ed=exports.GLP_BT_BFS=2,fd=exports.GLP_BT_BLB=3,gd=exports.GLP_BT_BPH=4,hd=exports.GLP_PP_NONE=0,id=exports.GLP_PP_ROOT=1,jd=exports.GLP_PP_ALL=2;exports.GLP_RF_REG=0;
var Ha=exports.GLP_RF_LAZY=1,Ja=exports.GLP_RF_CUT=2,Df=exports.GLP_RF_GMI=1,Ef=exports.GLP_RF_MIR=2,Ff=exports.GLP_RF_COV=3,Gf=exports.GLP_RF_CLQ=4,bb=exports.GLP_ON=1,cb=exports.GLP_OFF=0,Ga=exports.GLP_IROWGEN=1,Xf=exports.GLP_IBINGO=2,Yf=exports.GLP_IHEUR=3,Ia=exports.GLP_ICUTGEN=4,bg=exports.GLP_IBRANCH=5,Qf=exports.GLP_ISELECT=6,Uf=exports.GLP_IPREPRO=7,Af=exports.GLP_NO_BRNCH=0,Bf=exports.GLP_DN_BRNCH=1,Cf=exports.GLP_UP_BRNCH=2,Kb=exports.GLP_EBADB=1,Mb=exports.GLP_ESING=2,Nb=exports.GLP_ECOND=
3,rc=exports.GLP_EBOUND=4,Sb=exports.GLP_EFAIL=5,Vf=exports.GLP_EOBJLL=6,Wf=exports.GLP_EOBJUL=7,rg=exports.GLP_EITLIM=8,Qc=exports.GLP_ETMLIM=9,ac=exports.GLP_ENOPFS=10,bc=exports.GLP_ENODFS=11,Lc=exports.GLP_EROOT=12,Rc=exports.GLP_ESTOP=13,Pc=exports.GLP_EMIPGAP=14;exports.GLP_ENOFEAS=15;exports.GLP_ENOCVG=16;exports.GLP_EINSTAB=17;exports.GLP_EDATA=18;exports.GLP_ERANGE=19;exports.GLP_KKT_PE=1;exports.GLP_KKT_PB=2;exports.GLP_KKT_DE=3;exports.GLP_KKT_DB=4;exports.GLP_KKT_CS=5;
exports.GLP_MPS_DECK=1;exports.GLP_MPS_FILE=2;exports.GLP_ASN_MIN=1;exports.GLP_ASN_MAX=2;exports.GLP_ASN_MMP=3;function ug(a){var b=Math.floor(Math.log(a)/Math.log(2))+1;return Math.pow(2,0.75>=a/Math.pow(2,b)?b-1:b)}function vg(a,b){var c=Number(a);if(isNaN(c))return 2;switch(c){case Number.POSITIVE_INFINITY:case Number.NEGATIVE_INFINITY:return 1;default:return b(c),0}}
function wg(a,b){var c=Number(a);if(isNaN(c))return 2;switch(c){case Number.POSITIVE_INFINITY:case Number.NEGATIVE_INFINITY:return 1;default:return 0==c%1?(b(c),0):2}}function xg(a,b,c){var d,e;if(!(1<=a&&31>=a&&1<=b&&12>=b&&1<=c&&4E3>=c))return-1;3<=b?b-=3:(b+=9,c--);d=c/100|0;c=(146097*d/4|0)+(1461*(c-100*d)/4|0);c+=(153*b+2)/5|0;c+=a+1721119;yg(c,function(a){e=a});a!=e&&(c=-1);return c}
function yg(a,b){var c,d,e;1721426<=a&&3182395>=a&&(a-=1721119,e=(4*a-1)/146097|0,c=(4*a-1)%146097/4|0,a=(4*c+3)/1461|0,c=((4*c+3)%1461+4)/4|0,d=(5*c-3)/153|0,c=(5*c-3)%153,c=(c+5)/5|0,e=100*e+a,9>=d?d+=3:(d-=9,e++),b(c,d,e))}var Ee=1;LPF_ECOND=2;LPF_ELIMIT=3;var we=0;function Me(a,b,c,d){var e=a.i,f=a.Md,g=a.Ld,h=a.Wb;a=a.Xb;var k,l,p,m;for(k=1;k<=e;k++){m=0;l=f[k];for(p=l+g[k];l<p;l++)m+=a[l]*d[h[l]];b[k+c]+=-1*m}}
function Je(a,b,c,d){var e=a.i,f=a.Od,g=a.Nd,h=a.Wb;a=a.Xb;var k,l,p,m;for(k=1;k<=e;k++){m=0;l=f[k];for(p=l+g[k];l<p;l++)m+=a[l]*d[h[l]];b[k+c]+=-1*m}}if(we)var Le=function(a,b,c,d){var e=a.g;a=a.Cf;var f,g,h=0,k,l,p;for(f=1;f<=e;f++){k=0;for(g=p=1;g<=e;g++)l=b?a[e*(g-1)+f]*c[g]:a[e*(f-1)+g]*c[g],p<Math.abs(l)&&(p=Math.abs(l)),k+=l;g=Math.abs(k-d[f])/p;h<g&&(h=g)}1E-8<h&&x((b?"lpf_btran":"lpf_ftran")+": dmax = "+h+"; relative error too large")};exports.LPX_LP=100;exports.LPX_MIP=101;
var gf=exports.LPX_FR=110,jf=exports.LPX_LO=111,lf=exports.LPX_UP=112,nf=exports.LPX_DB=113,cf=exports.LPX_FX=114;exports.LPX_MIN=120;exports.LPX_MAX=121;exports.LPX_P_UNDEF=132;exports.LPX_P_FEAS=133;exports.LPX_P_INFEAS=134;exports.LPX_P_NOFEAS=135;exports.LPX_D_UNDEF=136;exports.LPX_D_FEAS=137;exports.LPX_D_INFEAS=138;exports.LPX_D_NOFEAS=139;var ff=exports.LPX_BS=140,kf=exports.LPX_NL=141,mf=exports.LPX_NU=142,hf=exports.LPX_NF=143,of=exports.LPX_NS=144;exports.LPX_T_UNDEF=150;
exports.LPX_T_OPT=151;var Mf=exports.LPX_CV=160,Nf=exports.LPX_IV=161;exports.LPX_I_UNDEF=170;exports.LPX_I_OPT=171;exports.LPX_I_FEAS=172;exports.LPX_I_NOFEAS=173;exports.LPX_OPT=180;exports.LPX_FEAS=181;exports.LPX_INFEAS=182;exports.LPX_NOFEAS=183;exports.LPX_UNBND=184;exports.LPX_UNDEF=185;exports.LPX_E_OK=200;exports.LPX_E_EMPTY=201;exports.LPX_E_BADB=202;exports.LPX_E_INFEAS=203;exports.LPX_E_FAULT=204;exports.LPX_E_OBJLL=205;exports.LPX_E_OBJUL=206;exports.LPX_E_ITLIM=207;
exports.LPX_E_TMLIM=208;exports.LPX_E_NOFEAS=209;exports.LPX_E_INSTAB=210;exports.LPX_E_SING=211;exports.LPX_E_NOCONV=212;exports.LPX_E_NOPFS=213;exports.LPX_E_NODFS=214;exports.LPX_E_MIPGAP=215;var zg=exports.LPX_K_MSGLEV=300,Ag=exports.LPX_K_SCALE=301,Bg=exports.LPX_K_DUAL=302,Cg=exports.LPX_K_PRICE=303;exports.LPX_K_RELAX=304;exports.LPX_K_TOLBND=305;exports.LPX_K_TOLDJ=306;exports.LPX_K_TOLPIV=307;var Dg=exports.LPX_K_ROUND=308;exports.LPX_K_OBJLL=309;exports.LPX_K_OBJUL=310;
var Eg=exports.LPX_K_ITLIM=311,Fg=exports.LPX_K_ITCNT=312;exports.LPX_K_TMLIM=313;var Gg=exports.LPX_K_OUTFRQ=314;exports.LPX_K_OUTDLY=315;var Hg=exports.LPX_K_BRANCH=316,Ig=exports.LPX_K_BTRACK=317;exports.LPX_K_TOLINT=318;exports.LPX_K_TOLOBJ=319;
var Jg=exports.LPX_K_MPSINFO=320,Kg=exports.LPX_K_MPSOBJ=321,Lg=exports.LPX_K_MPSORIG=322,Mg=exports.LPX_K_MPSWIDE=323,Ng=exports.LPX_K_MPSFREE=324,Og=exports.LPX_K_MPSSKIP=325,Pg=exports.LPX_K_LPTORIG=326,Qg=exports.LPX_K_PRESOL=327,Rg=exports.LPX_K_BINARIZE=328,Sg=exports.LPX_K_USECUTS=329,Tg=exports.LPX_K_BFTYPE=330;exports.LPX_K_MIPGAP=331;exports.LPX_C_COVER=1;exports.LPX_C_CLIQUE=2;exports.LPX_C_GOMORY=4;exports.LPX_C_MIR=8;exports.LPX_C_ALL=255;
function Kf(a,b){var c=pb(a,b);c==-s&&(c=0);return c}function Jf(a,b){var c=qb(a,b);c==+s&&(c=0);return c}function df(a,b,c){c(ob(a,b)-Ka+gf,Kf(a,b),Jf(a,b))}function Lf(a,b){var c=sb(a,b);c==-s&&(c=0);return c}function Of(a,b){var c=tb(a,b);c==+s&&(c=0);return c}function bf(a,b,c){c(rb(a,b)-Ka+gf,Lf(a,b),Of(a,b))}
function ef(a){var b=zg,c;null==a.ke&&(a.ke={},c=a.ke,c.o=3,c.scale=1,c.J=0,c.mh=1,c.yh=0.07,c.Gb=1E-7,c.tb=1E-7,c.xe=1E-9,c.round=0,c.hf=-s,c.jf=+s,c.oc=-1,c.sb=-1,c.bc=200,c.fb=0,c.Og=2,c.Pg=3,c.Ub=1E-5,c.we=1E-7,c.Xg=1,c.Yg=2,c.Zg=0,c.ah=1,c.Wg=0,c.$g=0,c.Vg=0,c.lh=0,c.sd=0,c.wh=0,c.ce=0);c=a.ke;var d=0;switch(b){case zg:d=c.o;break;case Ag:d=c.scale;break;case Bg:d=c.J;break;case Cg:d=c.mh;break;case Dg:d=c.round;break;case Eg:d=c.oc;break;case Fg:d=a.$;break;case Gg:d=c.bc;break;case Hg:d=c.Og;
break;case Ig:d=c.Pg;break;case Jg:d=c.Xg;break;case Kg:d=c.Yg;break;case Lg:d=c.Zg;break;case Mg:d=c.ah;break;case Ng:d=c.Wg;break;case Og:d=c.$g;break;case Pg:d=c.Vg;break;case Qg:d=c.lh;break;case Rg:d=c.sd;break;case Sg:d=c.wh;break;case Tg:b={};eb(a,b);switch(b.type){case md:d=1;break;case rd:d=2;break;case sd:d=3}break;default:w("lpx_get_int_parm: parm = "+b+"; invalid parameter")}return d}var ye=1,Ae=2;
function ve(){var a={};a.K=a.i=0;a.valid=0;a.Rf=a.Ye=null;a.Yd=a.Xd=null;a.Fc=a.Ec=a.pd=null;a.Af=null;a.Dc=a.Cc=a.Rc=null;a.kb=a.vb=null;a.sf=a.me=null;a.Ga=0;a.Fa=a.Ma=0;a.wb=null;a.xb=null;a.ld=a.Sb=0;a.Hd=a.md=null;a.zf=null;a.vf=a.dg=a.wf=null;a.Oe=a.Qe=a.Pe=null;a.ba=null;a.ze=null;a.Va=0;a.cc=0.1;a.xc=4;a.gc=1;a.Mb=1E-15;a.sc=1E10;a.dh=a.$f=a.Qb=0;a.Cg=a.rd=0;a.pa=0;return a}
function af(a){var b=a.i,c=a.Fc,d=a.Ec,e=a.pd,f=a.Dc,g=a.Cc,h=a.Rc,k=a.wb,l=a.xb,p=a.md,m=1,q,r;for(r=a.ld;0!=r;r=p[r])if(r<=b){q=r;if(c[q]!=m)break;e[q]=d[q];m+=e[q]}else{q=r-b;if(f[q]!=m)break;h[q]=g[q];m+=h[q]}for(;0!=r;r=p[r])r<=b?(q=r,ga(k,m,k,c[q],d[q]),ga(l,m,l,c[q],d[q]),c[q]=m,e[q]=d[q],m+=e[q]):(q=r-b,ga(k,m,k,f[q],g[q]),ga(l,m,l,f[q],g[q]),f[q]=m,h[q]=g[q],m+=h[q]);a.Fa=m}
function Ze(a,b,c){var d=a.i,e=a.Fc,f=a.Ec,g=a.pd,h=a.Rc,k=a.wb,l=a.xb,p=a.Hd,m=a.md,q=0,r;if(a.Ma-a.Fa<c&&(af(a),a.Ma-a.Fa<c))return 1;r=g[b];ga(k,a.Fa,k,e[b],f[b]);ga(l,a.Fa,l,e[b],f[b]);e[b]=a.Fa;g[b]=c;a.Fa+=c;0==p[b]?a.ld=m[b]:(c=p[b],c<=d?g[c]+=r:h[c-d]+=r,m[p[b]]=m[b]);0==m[b]?a.Sb=p[b]:p[m[b]]=p[b];p[b]=a.Sb;m[b]=0;0==p[b]?a.ld=b:m[p[b]]=b;a.Sb=b;return q}
function $e(a,b,c){var d=a.i,e=a.pd,f=a.Dc,g=a.Cc,h=a.Rc,k=a.wb,l=a.xb,p=a.Hd,m=a.md,q=0,r;if(a.Ma-a.Fa<c&&(af(a),a.Ma-a.Fa<c))return 1;r=h[b];ga(k,a.Fa,k,f[b],g[b]);ga(l,a.Fa,l,f[b],g[b]);f[b]=a.Fa;h[b]=c;a.Fa+=c;b=d+b;0==p[b]?a.ld=m[b]:(c=p[b],c<=d?e[c]+=r:h[c-d]+=r,m[p[b]]=m[b]);0==m[b]?a.Sb=p[b]:p[m[b]]=p[b];p[b]=a.Sb;m[b]=0;0==p[b]?a.ld=b:m[p[b]]=b;a.Sb=b;return q}
function Ug(a,b){var c=a.K;a.i=b;b<=c||(a.K=c=b+100,a.Rf=new Int32Array(1+c),a.Ye=new Int32Array(1+c),a.Yd=new Int32Array(1+c),a.Xd=new Int32Array(1+c),a.Fc=new Int32Array(1+c),a.Ec=new Int32Array(1+c),a.pd=new Int32Array(1+c),a.Af=new Float64Array(1+c),a.Dc=new Int32Array(1+c),a.Cc=new Int32Array(1+c),a.Rc=new Int32Array(1+c),a.kb=new Int32Array(1+c),a.vb=new Int32Array(1+c),a.sf=new Int32Array(1+c),a.me=new Int32Array(1+c),a.Hd=new Int32Array(1+c+c),a.md=new Int32Array(1+c+c),a.zf=new Float64Array(1+
c),a.vf=new Int32Array(1+c),a.dg=new Int32Array(1+c),a.wf=new Int32Array(1+c),a.Oe=new Int32Array(1+c),a.Qe=new Int32Array(1+c),a.Pe=new Int32Array(1+c),a.ba=new Int32Array(1+c),a.ze=new Float64Array(1+c))}
function Vg(a,b,c){var d=a.i,e=a.Yd,f=a.Xd,g=a.Fc,h=a.Ec,k=a.pd,l=a.Dc,p=a.Cc,m=a.Rc,q=a.kb,r=a.vb,n=a.sf,t=a.me,y=a.wb,E=a.xb,C=a.Hd,D=a.md,H=a.zf,R=a.vf,V=a.dg,O=a.wf,Q=a.Oe,F=a.Qe,W=a.Pe,X=a.ba,ca=a.ze,ka=0,P,u,z,L,v,S,M;L=1;v=a.Ga+1;for(u=1;u<=d;u++)e[u]=v,f[u]=0;for(P=1;P<=d;P++)h[P]=k[P]=0,X[P]=0;f=e=0;for(u=1;u<=d;u++){var ba=q,J=ca;z=b(c,u,ba,J);0<=z&&z<=d||w("luf_factorize: j = "+u+"; len = "+z+"; invalid column length");if(v-L<z)return ka=1;l[u]=L;p[u]=m[u]=z;e+=z;for(S=1;S<=z;S++)P=ba[S],
M=J[S],1<=P&&P<=d||w("luf_factorize: i = "+P+"; j = "+u+"; invalid row index"),X[P]&&w("luf_factorize: i = "+P+"; j = "+u+"; duplicate element not allowed"),0==M&&w("luf_factorize: i = "+P+"; j = "+u+"; zero element not allowed"),y[L]=P,E[L]=M,L++,0>M&&(M=-M),f<M&&(f=M),X[P]=1,k[P]++;for(S=1;S<=z;S++)X[ba[S]]=0}for(P=1;P<=d;P++){z=k[P];if(v-L<z)return ka=1;g[P]=L;L+=z}for(u=1;u<=d;u++)for(P=l[u],b=P+p[u]-1,k=P;k<=b;k++)P=y[k],M=E[k],c=g[P]+h[P],y[c]=u,E[c]=M,h[P]++;for(k=1;k<=d;k++)q[k]=r[k]=n[k]=
t[k]=k;a.Fa=L;a.Ma=v;a.ld=d+1;a.Sb=d;for(P=1;P<=d;P++)C[P]=P-1,D[P]=P+1;C[1]=d+d;D[d]=0;for(u=1;u<=d;u++)C[d+u]=d+u-1,D[d+u]=d+u+1;C[d+1]=0;for(k=D[d+d]=1;k<=d;k++)X[k]=0,ca[k]=0;a.dh=e;a.$f=0;a.Qb=e;a.Cg=f;a.rd=f;a.pa=-1;for(P=1;P<=d;P++)H[P]=-1;for(z=0;z<=d;z++)R[z]=0;for(P=1;P<=d;P++)z=h[P],V[P]=0,O[P]=R[z],0!=O[P]&&(V[O[P]]=P),R[z]=P;for(z=0;z<=d;z++)Q[z]=0;for(u=1;u<=d;u++)z=p[u],F[u]=0,W[u]=Q[z],0!=W[u]&&(F[W[u]]=u),Q[z]=u;return ka}
function Wg(a,b){function c(){b(D,H);return 0==D}var d=a.i,e=a.Fc,f=a.Ec,g=a.Dc,h=a.Cc,k=a.wb,l=a.xb,p=a.zf,m=a.vf,q=a.wf,r=a.Oe,n=a.Qe,t=a.Pe,y=a.cc,E=a.xc,C=a.gc,D,H,R,V,O,Q,F,W,X,ca,ka,P,u,z,L,v,S,M;D=H=0;v=s;ka=0;W=r[1];if(0!=W)return D=k[g[W]],H=W,c();V=m[1];if(0!=V)return D=V,H=k[e[V]],c();for(R=2;R<=d;R++){for(W=r[R];0!=W;W=P){V=g[W];X=V+h[W]-1;P=t[W];u=z=0;L=2147483647;for(ca=V;ca<=X;ca++)if(V=k[ca],O=e[V],Q=O+f[V]-1,!(f[V]>=L)){S=p[V];if(0>S){for(F=O;F<=Q;F++)M=l[F],0>M&&(M=-M),S<M&&(S=M);
p[V]=S}for(F=e[V];k[F]!=W;F++);M=l[F];0>M&&(M=-M);if(!(M<y*S)&&(u=V,z=W,L=f[V],L<=R))return D=u,H=z,c()}if(0!=u){if(ka++,W=(L-1)*(R-1),W<v&&(D=u,H=z,v=W),ka==E)return c()}else C&&(0==n[W]?r[R]=t[W]:t[n[W]]=t[W],0!=t[W]&&(n[t[W]]=n[W]),n[W]=t[W]=W)}for(V=m[R];0!=V;V=q[V]){O=e[V];Q=O+f[V]-1;S=p[V];if(0>S){for(F=O;F<=Q;F++)M=l[F],0>M&&(M=-M),S<M&&(S=M);p[V]=S}u=z=0;L=2147483647;for(F=O;F<=Q;F++)if(W=k[F],!(h[W]>=L)&&(M=l[F],0>M&&(M=-M),!(M<y*S)&&(u=V,z=W,L=h[W],L<=R)))return D=u,H=z,c();if(0!=u&&(ka++,
W=(R-1)*(L-1),W<v&&(D=u,H=z,v=W),ka==E))return c()}}return c()}
function Xg(a,b,c){var d=a.i,e=a.Yd,f=a.Xd,g=a.Fc,h=a.Ec,k=a.pd,l=a.Af,p=a.Dc,m=a.Cc,q=a.Rc,r=a.wb,n=a.xb,t=a.Hd,y=a.md,E=a.zf,C=a.vf,D=a.dg,H=a.wf,R=a.Oe,V=a.Qe,O=a.Pe,Q=a.ba,F=a.ze,W=a.Mb,X=a.Ye,ca=0,ka,P,u,z,L,v,S,M,ba,J,ea,fa;0==D[b]?C[h[b]]=H[b]:H[D[b]]=H[b];0!=H[b]&&(D[H[b]]=D[b]);0==V[c]?R[m[c]]=O[c]:O[V[c]]=O[c];0!=O[c]&&(V[O[c]]=V[c]);M=g[b];ba=M+h[b]-1;for(P=M;r[P]!=c;P++);fa=l[b]=n[P];r[P]=r[ba];n[P]=n[ba];h[b]--;ba--;l=p[c];J=l+m[c]-1;for(u=l;r[u]!=b;u++);r[u]=r[J];m[c]--;J--;for(P=M;P<=
ba;P++){z=r[P];Q[z]=1;F[z]=n[P];0==V[z]?R[m[z]]=O[z]:O[V[z]]=O[z];0!=O[z]&&(V[O[z]]=V[z]);v=p[z];for(S=v+m[z]-1;r[v]!=b;v++);r[v]=r[S];m[z]--}for(;l<=J;){u=r[l];0==D[u]?C[h[u]]=H[u]:H[D[u]]=H[u];0!=H[u]&&(D[H[u]]=D[u]);z=g[u];ka=z+h[u]-1;for(L=z;r[L]!=c;L++);ea=n[L]/fa;r[L]=r[ka];n[L]=n[ka];h[u]--;ka--;r[l]=r[J];m[c]--;J--;P=h[b];for(L=z;L<=ka;L++)if(z=r[L],Q[z])if(v=n[L]-=ea*F[z],0>v&&(v=-v),Q[z]=0,P--,0==v||v<W){r[L]=r[ka];n[L]=n[ka];h[u]--;L--;ka--;v=p[z];for(S=v+m[z]-1;r[v]!=u;v++);r[v]=r[S];
m[z]--}else a.rd<v&&(a.rd=v);if(h[u]+P>k[u]){if(Ze(a,u,h[u]+P))return ca=1;M=g[b];ba=M+h[b]-1;l=p[c];J=l+m[c]-1}ka=0;for(P=M;P<=ba;P++)z=r[P],Q[z]?(v=S=-ea*F[z],0>v&&(v=-v),0==v||v<W||(L=g[u]+h[u],r[L]=z,n[L]=S,h[u]++,X[++ka]=z,a.rd<v&&(a.rd=v))):Q[z]=1;for(L=1;L<=ka;L++){z=X[L];if(m[z]+1>q[z]){if($e(a,z,m[z]+10))return ca=1;M=g[b];ba=M+h[b]-1;l=p[c];J=l+m[c]-1}v=p[z]+m[z];r[v]=u;m[z]++}D[u]=0;H[u]=C[h[u]];0!=H[u]&&(D[H[u]]=u);C[h[u]]=u;E[u]=-1;if(1>a.Ma-a.Fa){af(a);if(1>a.Ma-a.Fa)return ca=1;M=g[b];
ba=M+h[b]-1;l=p[c];J=l+m[c]-1}a.Ma--;r[a.Ma]=u;n[a.Ma]=ea;f[b]++}q[c]=0;L=d+c;0==t[L]?a.ld=y[L]:y[t[L]]=y[L];0==y[L]?a.Sb=t[L]:t[y[L]]=t[L];e[b]=a.Ma;for(P=M;P<=ba;P++)if(z=r[P],Q[z]=0,F[z]=0,1==m[z]||V[z]!=z||O[z]!=z)V[z]=0,O[z]=R[m[z]],0!=O[z]&&(V[O[z]]=z),R[m[z]]=z;return ca}
function Yg(a){var b=a.i,c=a.Fc,d=a.Ec,e=a.Dc,f=a.Cc,g=a.Rc,h=a.wb,k=a.xb,l=a.Hd,p=a.md,m,q,r,n;n=0;for(m=1;m<=b;m++){q=c[m];for(r=q+d[m]-1;q<=r;q++)g[h[q]]++;n+=d[m]}a.Qb=n;if(a.Ma-a.Fa<n)return 1;for(n=1;n<=b;n++)e[n]=a.Fa,a.Fa+=g[n];for(m=1;m<=b;m++)for(q=c[m],r=q+d[m]-1;q<=r;q++)n=h[q],g=e[n]+f[n],h[g]=m,k[g]=k[q],f[n]++;for(c=b+1;c<=b+b;c++)l[c]=c-1,p[c]=c+1;l[b+1]=a.Sb;p[a.Sb]=b+1;p[b+b]=0;a.Sb=b+b;return 0}
function Zg(a){var b=a.i,c=a.Rf,d=a.Ye,e=a.Yd,f=a.Xd,g=a.wb,h=a.xb,k,l,p,m;for(k=1;k<=b;k++)d[k]=0;k=0;for(l=1;l<=b;l++){p=e[l];for(m=p+f[l]-1;p<=m;p++)d[g[p]]++;k+=f[l]}a.$f=k;if(a.Ma-a.Fa<k)return 1;for(k=1;k<=b;k++)c[k]=a.Ma,a.Ma-=d[k];for(l=1;l<=b;l++)for(p=e[l],m=p+f[l]-1;p<=m;p++)k=g[p],a=--c[k],g[a]=l,h[a]=h[p];return 0}
function xe(a,b,c,d){function e(){0<a.Va&&(a.Ga=a.Va,a.wb=new Int32Array(1+a.Ga),a.xb=new Float64Array(1+a.Ga),a.Va=0);if(Vg(a,c,d))return a.Va=a.Ga+a.Ga,!0;for(q=1;q<=b;q++){if(Wg(a,function(a,b){r=a;n=b}))return a.pa=q-1,y=ye,!1;p=g[r];m=h[n];t=f[q];f[p]=t;g[t]=p;f[q]=r;g[r]=q;t=k[q];k[m]=t;h[t]=m;k[q]=n;h[n]=q;if(Xg(a,r,n))return a.Va=a.Ga+a.Ga,!0;if(a.rd>l*a.Cg)return a.pa=q-1,y=Ae,!1}af(a);return Yg(a)||Zg(a)?(a.Va=a.Ga+a.Ga,!0):!1}var f,g,h,k,l=a.sc,p,m,q,r,n,t,y=null;1>b&&w("luf_factorize: n = "+
b+"; invalid parameter");1E8<b&&w("luf_factorize: n = "+b+"; matrix too big");a.valid=0;Ug(a,b);f=a.kb;g=a.vb;h=a.sf;k=a.me;0==a.Ga&&0==a.Va&&(a.Va=5*(b+10));for(;e(););if(null!=y)return y;a.valid=1;a.pa=b;y=0;t=3*(b+a.Qb)+2*a.$f;if(a.Ga<t)for(a.Va=a.Ga;a.Va<t;)q=a.Va,a.Va=q+q;return y}
function Ge(a,b,c){var d=a.i,e=a.Rf,f=a.Ye,g=a.Yd,h=a.Xd,k=a.kb,l=a.wb,p=a.xb,m;a.valid||w("luf_f_solve: LU-factorization is not valid");if(b)for(;1<=d;d--){if(m=k[d],a=c[m],0!=a)for(b=e[m],m=b+f[m]-1;b<=m;b++)c[l[b]]-=p[b]*a}else for(e=1;e<=d;e++)if(m=k[e],a=c[m],0!=a)for(b=g[m],m=b+h[m]-1;b<=m;b++)c[l[b]]-=p[b]*a}
function Ie(a,b,c){var d=a.i,e=a.Fc,f=a.Ec,g=a.Af,h=a.Dc,k=a.Cc,l=a.kb,p=a.me,m=a.wb,q=a.xb,r=a.ze,n,t,y;a.valid||w("luf_v_solve: LU-factorization is not valid");for(a=1;a<=d;a++)r[a]=c[a],c[a]=0;if(b)for(a=1;a<=d;a++){if(n=l[a],t=p[a],b=r[t],0!=b)for(c[n]=b/=g[n],y=e[n],n=y+f[n]-1;y<=n;y++)r[m[y]]-=q[y]*b}else for(a=d;1<=a;a--)if(n=l[a],t=p[a],b=r[n],0!=b)for(c[t]=b/=g[n],y=h[t],n=y+k[t]-1;y<=n;y++)r[m[y]]-=q[y]*b}
var $g=-1,ah=101,bh=102,ch=103,dh=104,eh=105,fh=106,gh=107,hh=108,ih=109,jh=110,kh=111,lh=112,mh=113,nh=114,oh=115,ph=116,qh=117,N=118,rh=119,sh=120,th=121,uh=122,vh=123,T=124,wh=125,xh=126,yh=127,zh=60,Ah=201,Bh=202,Ch=203,Dh=204,Eh=205,Fh=206,Gh=207,Hh=208,Ih=209,Jh=210,Kh=211,Lh=212,Mh=213,Nh=214,Oh=215,Ph=216,Qh=217,Rh=218,Sh=219,Th=220,Uh=221,Vh=222,Wh=223,Xh=224,Yh=225,Zh=226,$h=227,ai=228,bi=229,ci=230,di=231,ei=232,fi=233,gi=234,hi=235,ii=236,ji=237,ki=238,li=239,mi=240,ni=241,oi=242,pi=243,
qi=244,ri=245,si=246,ti=247,ui=248,vi=249,wi=250,xi=251,yi=252,zi=0,Ai=1,Bi=2,Ci=3,Di=4,Ei=5,Fi=301,Gi=302,Hi=303,Ii=304,Ji=305,Ki=306,Li=307,Mi=308,Ni=309,Oi=310,Pi=311,Qi=312,Ri=313,Si=314,Ti=315,Ui=316,Vi=317,Wi=318,Xi=319,Yi=320,Zi=321,$i=322,aj=323,bj=324,cj=325,dj=326,ej=327,fj=328,gj=329,hj=330,ij=331,jj=332,kj=333,lj=334,mj=335,nj=336,oj=337,pj=338,qj=339,rj=340,sj=341,tj=342,uj=343,vj=344,wj=345,xj=346,yj=347,zj=348,Aj=349,Bj=350,Cj=351,Dj=352,Ej=353,Fj=354,Gj=355,Hj=356,Ij=357,Jj=358,Kj=
359,Lj=360,Mj=361,Nj=362,Oj=363,Pj=364,Qj=365,Rj=366,Sj=367,Tj=368,Uj=369,Vj=370,Xj=371,Yj=372,Zj=373,ak=374,bk=375,ck=376,dk=377,ek=378,fk=379,gk=380,hk=381,ik=382,jk=383,kk=384,Wd=401,Xd=402,Yd=403,Zd=404,$d=405,je=412,ke=413,ee=422,fe=423;function lk(){return{index:{},S:{},set:{},t:{},H:{},a:{},loop:{}}}function mk(a){var b;b=a.b==Ah?"_|_":a.b==Eh?"'...'":a.h;a.Zb[a.lc++]=" ";a.lc==zh&&(a.lc=0);for(var c=0;c<b.length;c++)a.Zb[a.lc++]=b[c],a.lc==zh&&(a.lc=0)}
function nk(a){var b;a.l!=$g&&("\n"==a.l&&(a.bb++,a.Vc=0),b=a.cf(),0>b&&(b=$g),a.Vc++,b==$g?"\n"==a.l?a.bb--:ok(a,"final NL missing before end of file"):"\n"!=b&&(0<=" \t\n\v\f\r".indexOf(b)?b=" ":ta(b)&&(mk(a),U(a,"control character "+b+" not allowed"))),a.l=b)}function pk(a){a.h+=a.l;a.Bb++;nk(a)}
function Y(a){function b(){mk(a);U(a,"keyword s.t. incomplete")}function c(){mk(a);U(a,"cannot convert numeric literal "+a.h+" to floating-point number")}function d(){if("e"==a.l||"E"==a.l)for(pk(a),"+"!=a.l&&"-"!=a.l||pk(a),wa(a.l)||(mk(a),U(a,"numeric literal "+a.h+" incomplete"));wa(a.l);)pk(a);if(ua(a.l)||"_"==a.l)mk(a),U(a,"symbol "+a.h+a.l+"... should be enclosed in quotes")}a.Hf=a.b;a.Gf=a.Bb;a.Ff=a.h;a.If=a.value;if(a.Ue)a.Ue=0,a.b=a.Mf,a.Bb=a.Lf,a.h=a.Kf,a.value=a.Nf;else{for(;;){a.b=0;a.Bb=
0;a.h="";for(a.value=0;" "==a.l||"\n"==a.l;)nk(a);if(a.l==$g)a.b=Ah;else if("#"==a.l){for(;"\n"!=a.l&&a.l!=$g;)nk(a);continue}else if(a.nc||!ua(a.l)&&"_"!=a.l)if(!a.nc&&wa(a.l)){for(a.b=Dh;wa(a.l);)pk(a);var e=!1;if("."==a.l)if(pk(a),"."==a.l)a.Bb--,a.h=a.h.substr(0,a.h.length-1),a.Te=1,e=!0;else for(;wa(a.l);)pk(a);e||d();vg(a.h,function(b){a.value=b})&&c()}else if("'"==a.l||'"'==a.l){var f=a.l,g=!1;a.b=Eh;nk(a);e=function(){for(;;){if("\n"==a.l&&!g||a.l==$g)mk(a),U(a,"unexpected end of line; string literal incomplete");
if(a.l==f)if(nk(a),a.l==f){if(g)if(nk(a),a.l==f){nk(a);break}else a.h+='""',a.Bb+=2}else if(g)a.h+='"',a.Bb++;else break;pk(a)}};a.l==f?(nk(a),a.l==f&&(g=!0,nk(a),e())):e()}else if(a.nc||"+"!=a.l)if(a.nc||"-"!=a.l)if("*"==a.l)a.b=$h,pk(a),"*"==a.l&&(a.b=bi,pk(a));else if("/"==a.l){if(a.b=ai,pk(a),"*"==a.l){for(nk(a);;)if(a.l==$g)U(a,"unexpected end of file; comment sequence incomplete");else if("*"==a.l){if(nk(a),"/"==a.l)break}else nk(a);nk(a);continue}}else if("^"==a.l)a.b=bi,pk(a);else if("<"==
a.l)a.b=ci,pk(a),"="==a.l?(a.b=di,pk(a)):">"==a.l?(a.b=hi,pk(a)):"-"==a.l&&(a.b=yi,pk(a));else if("="==a.l)a.b=ei,pk(a),"="==a.l&&pk(a);else if(">"==a.l)a.b=gi,pk(a),"="==a.l?(a.b=fi,pk(a)):">"==a.l&&(a.b=wi,pk(a));else if("!"==a.l)a.b=Rh,pk(a),"="==a.l&&(a.b=hi,pk(a));else if("&"==a.l)a.b=ii,pk(a),"&"==a.l&&(a.b=Fh,pk(a));else if("|"==a.l)a.b=ji,pk(a),"|"==a.l&&(a.b=Sh,pk(a));else if(a.nc||"."!=a.l)if(","==a.l)a.b=li,pk(a);else if(":"==a.l)a.b=mi,pk(a),"="==a.l&&(a.b=oi,pk(a));else if(";"==a.l)a.b=
ni,pk(a);else if("("==a.l)a.b=qi,pk(a);else if(")"==a.l)a.b=ri,pk(a);else if("["==a.l)a.b=si,pk(a);else if("]"==a.l)a.b=ti,pk(a);else if("{"==a.l)a.b=ui,pk(a);else if("}"==a.l)a.b=vi,pk(a);else if("~"==a.l)a.b=xi,pk(a);else if(va(a.l)||0<="+-._".indexOf(a.l)){for(a.b=Ch;va(a.l)||0<="+-._".indexOf(a.l);)pk(a);switch(vg(a.h,function(b){a.value=b})){case 0:a.b=Dh;break;case 1:c()}}else mk(a),U(a,"character "+a.l+" not allowed");else if(a.b=ki,pk(a),a.Te)a.b=pi,a.Bb=2,a.h="..",a.Te=0;else if("."==a.l)a.b=
pi,pk(a);else{if(wa(a.l)){a.b=Dh;for(pk(a);wa(a.l);)pk(a);d();vg(a.h,function(b){a.value=b})&&c()}}else a.b=Zh,pk(a);else a.b=Yh,pk(a);else{for(a.b=Bh;va(a.l)||"_"==a.l;)pk(a);"and"==a.h?a.b=Fh:"by"==a.h?a.b=Gh:"cross"==a.h?a.b=Hh:"diff"==a.h?a.b=Ih:"div"==a.h?a.b=Jh:"else"==a.h?a.b=Kh:"if"==a.h?a.b=Lh:"in"==a.h?a.b=Mh:"Infinity"==a.h?a.b=Nh:"inter"==a.h?a.b=Oh:"less"==a.h?a.b=Ph:"mod"==a.h?a.b=Qh:"not"==a.h?a.b=Rh:"or"==a.h?a.b=Sh:"s"==a.h&&"."==a.l?(a.b=Th,pk(a),"t"!=a.l&&b(),pk(a),"."!=a.l&&b(),
pk(a)):"symdiff"==a.h?a.b=Uh:"then"==a.h?a.b=Vh:"union"==a.h?a.b=Wh:"within"==a.h&&(a.b=Xh)}break}mk(a);a.Pf=0}}function qk(a){a.Ue=1;a.Mf=a.b;a.Lf=a.Bb;a.Kf=a.h;a.Nf=a.value;a.b=a.Hf;a.Bb=a.Gf;a.h=a.Ff;a.value=a.If}function rk(a,b){return a.b==Bh&&a.h==b}function sk(a){return a.b==Fh&&"a"==a.h[0]||a.b==Gh||a.b==Hh||a.b==Ih||a.b==Jh||a.b==Kh||a.b==Lh||a.b==Mh||a.b==Oh||a.b==Ph||a.b==Qh||a.b==Rh&&"n"==a.h[0]||a.b==Sh&&"o"==a.h[0]||a.b==Uh||a.b==Vh||a.b==Wh||a.b==Xh}
function tk(a,b,c,d){var e={};e.Ta=a;e.T=0;e.a=lk();e.value={};switch(a){case Fi:e.a.Q=b.Q;break;case Gi:e.a.M=b.M;break;case Hi:e.a.index.ya=b.index.ya;e.a.index.e=b.index.e;break;case Ii:case Ji:for(a=b.S.list;null!=a;a=a.e)a.x.R=e,e.T|=a.x.T;e.a.S.S=b.S.S;e.a.S.list=b.S.list;break;case Ki:for(a=b.set.list;null!=a;a=a.e)a.x.R=e,e.T|=a.x.T;e.a.set.set=b.set.set;e.a.set.list=b.set.list;break;case Li:for(a=b.t.list;null!=a;a=a.e)a.x.R=e,e.T|=a.x.T;e.a.t.t=b.t.t;e.a.t.list=b.t.list;e.a.t.Ac=b.t.Ac;
break;case Mi:for(a=b.H.list;null!=a;a=a.e)a.x.R=e,e.T|=a.x.T;e.a.H.H=b.H.H;e.a.H.list=b.H.list;e.a.H.Ac=b.H.Ac;break;case Ni:case Oi:for(a=b.list;null!=a;a=a.e)a.x.R=e,e.T|=a.x.T;e.a.list=b.list;break;case Pi:e.a.slice=b.slice;break;case Qi:case Ri:case Si:case Ti:e.T=1;break;case Ui:case Vi:case Wi:case Xi:case Yi:case Zi:case $i:case aj:case bj:case cj:case dj:case ej:case fj:case gj:case hj:case ij:case jj:case kj:case lj:case mj:case nj:case oj:b.a.x.R=e;e.T|=b.a.x.T;e.a.a.x=b.a.x;break;case pj:case qj:case rj:case sj:case tj:case uj:case vj:case wj:case xj:case yj:case zj:case Aj:a==
Aj&&(e.T=1);case Bj:a==Bj&&(e.T=1);case Cj:case Dj:case Ej:case Fj:case Gj:case Hj:case Ij:case Jj:case Kj:case Lj:case Mj:case Nj:case Oj:case Pj:case Qj:case Rj:case Sj:case Tj:case Uj:case Vj:case Xj:b.a.x.R=e;e.T|=b.a.x.T;b.a.y.R=e;e.T|=b.a.y.T;e.a.a.x=b.a.x;e.a.a.y=b.a.y;break;case Yj:case Zj:case ak:b.a.x.R=e;e.T|=b.a.x.T;b.a.y.R=e;e.T|=b.a.y.T;null!=b.a.z&&(b.a.z.R=e,e.T|=b.a.z.T);e.a.a.x=b.a.x;e.a.a.y=b.a.y;e.a.a.z=b.a.z;break;case bk:case ck:for(a=b.list;null!=a;a=a.e)a.x.R=e,e.T|=a.x.T;
e.a.list=b.list;break;case dk:case ek:case fk:case gk:case hk:case ik:case jk:case kk:a=b.loop.domain;null!=a.code&&(a.code.R=e,e.T|=a.code.T);for(a=a.list;null!=a;a=a.e)a.code.R=e,e.T|=a.code.T;null!=b.loop.x&&(b.loop.x.R=e,e.T|=b.loop.x.T);e.a.loop.domain=b.loop.domain;e.a.loop.x=b.loop.x}e.type=c;e.q=d;e.R=null;e.valid=0;e.value={};return e}function Z(a,b,c,d){var e=lk();e.a.x=b;return tk(a,e,c,d)}function uk(a,b,c,d,e){var f=lk();f.a.x=b;f.a.y=c;return tk(a,f,d,e)}
function vk(a,b,c,d,e,f){var g=lk();g.a.x=b;g.a.y=c;g.a.z=d;return tk(a,g,e,f)}function wk(a,b){var c={},d;c.x=b;c.e=null;if(null==a)a=c;else{for(d=a;null!=d.e;d=d.e);d.e=c}return a}function xk(a){var b;for(b=0;null!=a;a=a.e)b++;return b}
function yk(a){var b,c,d,e,f,g,h,k,l,p=lk(),m=a.V[a.h];null==m&&U(a,a.h+" not defined");switch(m.type){case kh:b=m.link;k=b.name;l=0;break;case uh:c=m.link;k=c.name;l=c.q;0==c.X&&(c.X=1);break;case sh:d=m.link;k=d.name;l=d.q;break;case yh:e=m.link;k=e.name;l=e.q;break;case ch:f=m.link,k=f.name,l=f.q}Y(a);if(a.b==si){0==l&&U(a,k+" cannot be subscripted");Y(a);for(var q=null;;)if(g=zk(a),g.type==N&&(g=Z(Vi,g,T,0)),g.type!=T&&U(a,"subscript expression has invalid type"),q=wk(q,g),a.b==li)Y(a);else if(a.b==
ti)break;else U(a,"syntax error in subscript list");g=q;l!=xk(g)&&U(a,k+" must have "+l+" subscript"+(1==l?"":"s")+" rather than "+xk(g));Y(a)}else 0!=l&&U(a,k+" must be subscripted"),g=null;l=a.Ob||m.type!=yh?Di:zi;a.b==ki&&(Y(a),a.b!=Bh&&U(a,"invalid use of period"),m.type!=yh&&m.type!=ch&&U(a,k+" cannot have a suffix"),"lb"==a.h?l=Ai:"ub"==a.h?l=Bi:"status"==a.h?l=Ci:"val"==a.h?l=Di:"dual"==a.h?l=Ei:U(a,"suffix ."+a.h+" invalid"),Y(a));switch(m.type){case kh:p.index.ya=b;p.index.e=b.list;h=tk(Hi,
p,T,0);b.list=h;break;case uh:p.set.set=c;p.set.list=g;h=tk(Ki,p,fh,c.X);break;case sh:p.S.S=d;p.S.list=g;h=d.type==T?tk(Ji,p,T,0):tk(Ii,p,N,0);break;case yh:a.Ob||l!=Ci&&l!=Di&&l!=Ei||U(a,"invalid reference to status, primal value, or dual value of variable "+e.name+" above solve statement");p.t.t=e;p.t.list=g;p.t.Ac=l;h=tk(Li,p,l==zi?jh:N,0);break;case ch:a.Ob||l!=Ci&&l!=Di&&l!=Ei||U(a,"invalid reference to status, primal value, or dual value of "+(f.type==ch?"constraint":"objective")+" "+f.name+
" above solve statement"),p.H.H=f,p.H.list=g,p.H.Ac=l,h=tk(Mi,p,N,0)}return h}function Ak(a,b){var c=zk(a);c.type==T&&(c=Z(Ui,c,N,0));c.type!=N&&U(a,"argument for "+b+" has invalid type");return c}function Bk(a,b){var c=zk(a);c.type==N&&(c=Z(Vi,c,T,0));c.type!=T&&U(a,"argument for "+b+" has invalid type");return c}function Ck(a,b,c){var d={};d.name=b;d.code=c;d.value=null;d.list=null;d.e=null;if(null==a.list)a.list=d;else{for(a=a.list;null!=a.e;a=a.e);a.e=d}}
function Dk(a){var b,c=lk(),d=Array(21);ia(d,0,21);var e,f,g,h=0;e=a.Pf;Y(a);for(g=1;;g++){20<g&&U(a,"too many components within parentheses");var k=function(){b=Ek(a);if(a.b==li||1<g)b.type==N&&(b=Z(Vi,b,T,0)),b.type!=T&&U(a,"component expression has invalid type");d[g].name=null;d[g].code=b};if(a.b==Bh)if(Y(a),f=a.b,qk(a),!e||f!=li&&f!=ri||null!=a.V[a.h])k();else{for(f=1;f<g;f++)null!=d[f].name&&d[f].name==a.h&&U(a,"duplicate dummy index "+a.h+" not allowed");d[g].name=a.h;d[g].code=null;Y(a);h=
1;1==g&&a.b==ri&&U(a,d[g].name+" not defined")}else k();if(a.b==li)Y(a);else if(a.b==ri)break;else U(a,"right parenthesis missing where expected")}if(1!=g||h)if(h){c.slice={};for(f=1;f<=g;f++)Ck(c.slice,d[f].name,d[f].code);b=tk(Pi,c,xh,g)}else{c.list=null;for(f=1;f<=g;f++)c.list=wk(c.list,d[f].code);b=tk(Ni,c,xh,g)}else b=d[1].code;Y(a);h&&a.b!=Mh&&U(a,"keyword in missing where expected");e&&a.b==Mh&&!h&&(1==g?U(a,"syntax error in indexing expression"):U(a,"0-ary slice not allowed"));return b}
function Fk(a){var b,c,d,e;Y(a);a.b==vi&&U(a,"empty indexing expression not allowed");for(b={};;){e=c=null;a.b==Bh?(Y(a),d=a.b,qk(a),d==Mh&&null==a.V[a.h]&&(c={},d=a.h,Ck(c,d,null),Y(a),Y(a))):a.b==qi&&(a.Pf=1,e=Gk(a),e.Ta==Pi&&(c=e.a.slice,e=null,Y(a)));null==e&&(e=Gk(a));if(e.type!=fh){null!=c&&U(a,"domain expression has invalid type");d=a;var f=lk(),g=void 0;f.list=null;for(g=1;;g++){e.type==N&&(e=Z(Vi,e,T,0));e.type==T&&(e=Z(Xi,e,xh,1));e.type!=xh&&U(d,"member expression has invalid type");null!=
f.list&&f.list.x.q!=e.q&&U(d,"member "+(g-1)+" has "+f.list.x.q+" component"+(1==f.list.x.q?"":"s")+" while member "+g+" has "+e.q+" component"+(1==e.q?"":"s"));f.list=wk(f.list,e);if(d.b==li)Y(d);else if(d.b==vi)break;else U(d,"syntax error in literal set");e=zk(d)}e=tk(Oi,f,fh,f.list.x.q)}if(null==c)for(c={},d=1;d<=e.q;d++)Ck(c,null,null);f=0;for(d=c.list;null!=d;d=d.e)f++;f!=e.q&&U(a,f+" "+(1==f?"index":"indices")+" specified for set of dimension "+e.q);c.code=e;e=b;d=c;f=void 0;if(null==e.list)e.list=
d;else{for(f=e.list;null!=f.e;f=f.e);f.e=d}for(d=c.list;null!=d;d=d.e)null!=d.name&&(a.V[d.name]={type:kh,link:d});if(a.b==li)Y(a);else if(a.b==mi||a.b==vi)break;else U(a,"syntax error in indexing expression")}a.b==mi&&(Y(a),e=Ek(a),e.type==T&&(e=Z(Ui,e,N,0)),e.type==N&&(e=Z(Wi,e,nh,0)),e.type!=nh&&U(a,"expression following colon has invalid type"),b.code=e,a.b!=vi&&U(a,"syntax error in indexing expression"));Y(a);return b}
function Hk(a,b){var c,d;for(c=b.list;null!=c;c=c.e)for(d=c.list;null!=d;d=d.e)null!=d.name&&delete a.V[d.name]}function Ik(a){var b,c;for(b=a.a.loop.domain.list;null!=b;b=b.e)for(c=b.list;null!=c;c=c.e)null!=c.code&&(c.code.R=a)}
function Jk(a){function b(){U(a,"integrand following "+f+"{...} has invalid type")}var c,d=lk(),e,f;"sum"==a.h?e=dk:"prod"==a.h?e=ek:"min"==a.h?e=fk:"max"==a.h?e=gk:"forall"==a.h?e=hk:"exists"==a.h?e=ik:"setof"==a.h?e=jk:U(a,"operator "+a.h+" unknown");f=a.h;Y(a);d.loop.domain=Fk(a);switch(e){case dk:case ek:case fk:case gk:d.loop.x=Kk(a);d.loop.x.type==T&&(d.loop.x=Z(Ui,d.loop.x,N,0));d.loop.x.type==N||e==dk&&d.loop.x.type==jh||b();c=tk(e,d,d.loop.x.type,0);break;case hk:case ik:d.loop.x=Lk(a);d.loop.x.type==
T&&(d.loop.x=Z(Ui,d.loop.x,N,0));d.loop.x.type==N&&(d.loop.x=Z(Wi,d.loop.x,nh,0));d.loop.x.type!=nh&&b();c=tk(e,d,nh,0);break;case jk:d.loop.x=zk(a),d.loop.x.type==N&&(d.loop.x=Z(Vi,d.loop.x,T,0)),d.loop.x.type==T&&(d.loop.x=Z(Xi,d.loop.x,xh,1)),d.loop.x.type!=xh&&b(),c=tk(e,d,fh,d.loop.x.q)}Hk(a,d.loop.domain);Ik(c);return c}function Mk(a){var b=0;for(a=a.list;null!=a;a=a.e)for(var c=a.list;null!=c;c=c.e)null==c.code&&b++;return b}
function Nk(a,b){U(a,"operand preceding "+b+" has invalid type")}function Ok(a,b){U(a,"operand following "+b+" has invalid type")}function Pk(a,b,c,d){U(a,"operands preceding and following "+b+" have different dimensions "+c+" and "+d+", respectively")}
function Qk(a){var b,c;if(a.b==Dh)b=lk(),b.Q=a.value,b=tk(Fi,b,N,0),Y(a),c=b;else if(a.b==Nh)b=lk(),b.Q=s,c=tk(Fi,b,N,0),Y(a);else if(a.b==Eh)b=lk(),b.M=a.h,b=tk(Gi,b,T,0),Y(a),c=b;else if(a.b==Bh)switch(Y(a),c=a.b,qk(a),c){case si:c=yk(a);break;case qi:c=lk();var d;"abs"==a.h?b=bj:"ceil"==a.h?b=cj:"floor"==a.h?b=dj:"exp"==a.h?b=ej:"log"==a.h?b=fj:"log10"==a.h?b=gj:"sqrt"==a.h?b=hj:"sin"==a.h?b=ij:"cos"==a.h?b=jj:"atan"==a.h?b=kj:"min"==a.h?b=bk:"max"==a.h?b=ck:"round"==a.h?b=lj:"trunc"==a.h?b=mj:
"Irand224"==a.h?b=Qi:"Uniform01"==a.h?b=Ri:"Uniform"==a.h?b=Aj:"Normal01"==a.h?b=Si:"Normal"==a.h?b=Bj:"card"==a.h?b=nj:"length"==a.h?b=oj:"substr"==a.h?b=Uj:"str2time"==a.h?b=Vj:"time2str"==a.h?b=Xj:"gmtime"==a.h?b=Ti:U(a,"function "+a.h+" unknown");d=a.h;Y(a);Y(a);if(b==bk||b==ck)for(c.list=null;;)if(c.list=wk(c.list,Ak(a,d)),a.b==li)Y(a);else if(a.b==ri)break;else U(a,"syntax error in argument list for "+d);else if(b==Qi||b==Ri||b==Si||b==Ti)a.b!=ri&&U(a,d+" needs no arguments");else if(b==Aj||
b==Bj)c.a.x=Ak(a,d),a.b!=li&&(a.b==ri?U(a,d+" needs two arguments"):U(a,"syntax error in argument for "+d)),Y(a),c.a.y=Ak(a,d),a.b==li?U(a,d+" needs two argument"):a.b!=ri&&U(a,"syntax error in argument for "+d);else if(b==kj||b==lj||b==mj){c.a.x=Ak(a,d);if(a.b==li){switch(b){case kj:b=xj;break;case lj:b=yj;break;case mj:b=zj}Y(a);c.a.y=Ak(a,d)}a.b==li?U(a,d+" needs one or two arguments"):a.b!=ri&&U(a,"syntax error in argument for "+d)}else if(b==Uj)c.a.x=Bk(a,d),a.b!=li&&(a.b==ri?U(a,d+" needs two or three arguments"):
U(a,"syntax error in argument for "+d)),Y(a),c.a.y=Ak(a,d),a.b==li&&(b=ak,Y(a),c.a.z=Ak(a,d)),a.b==li?U(a,d+" needs two or three arguments"):a.b!=ri&&U(a,"syntax error in argument for "+d);else if(b==Vj)c.a.x=Bk(a,d),a.b!=li&&(a.b==ri?U(a,d+" needs two arguments"):U(a,"syntax error in argument for "+d)),Y(a),c.a.y=Bk(a,d),a.b==li?U(a,d+" needs two argument"):a.b!=ri&&U(a,"syntax error in argument for "+d);else if(b==Xj)c.a.x=Ak(a,d),a.b!=li&&(a.b==ri?U(a,d+" needs two arguments"):U(a,"syntax error in argument for "+
d)),Y(a),c.a.y=Bk(a,d),a.b==li?U(a,d+" needs two argument"):a.b!=ri&&U(a,"syntax error in argument for "+d);else{var e=c.a,f;b==nj?(f=Gk(a),f.type!=fh&&U(a,"argument for "+d+" has invalid type")):f=b==oj?Bk(a,d):Ak(a,d);e.x=f;a.b==li?U(a,d+" needs one argument"):a.b!=ri&&U(a,"syntax error in argument for "+d)}b=b==Uj||b==ak||b==Xj?tk(b,c,T,0):tk(b,c,N,0);Y(a);c=b;break;case ui:c=Jk(a);break;default:c=yk(a)}else if(a.b==qi)c=Dk(a);else if(a.b==ui)b=lk(),Y(a),a.b==vi?(b.list=null,b=tk(Oi,b,fh,1),Y(a)):
(qk(a),b.loop.domain=Fk(a),b.loop.x=null,Hk(a,b.loop.domain),b=tk(kk,b,fh,Mk(b.loop.domain)),Ik(b)),c=b;else if(a.b==Lh){Y(a);b=Ek(a);b.type==T&&(b=Z(Ui,b,N,0));b.type==N&&(b=Z(Wi,b,nh,0));b.type!=nh&&U(a,"expression following if has invalid type");a.b!=Vh&&U(a,"keyword then missing where expected");Y(a);c=Gk(a);c.type!=N&&c.type!=T&&c.type!=fh&&c.type!=jh&&U(a,"expression following then has invalid type");if(a.b!=Kh)c.type==fh&&U(a,"keyword else missing where expected"),d=null;else{Y(a);d=Gk(a);
d.type!=N&&d.type!=T&&d.type!=fh&&d.type!=jh&&U(a,"expression following else has invalid type");if(c.type==jh||d.type==jh)c.type==T&&(c=Z(Ui,c,N,0)),c.type==N&&(c=Z(Yi,c,jh,0)),d.type==T&&(d=Z(Ui,d,N,0)),d.type==N&&(d=Z(Yi,d,jh,0));if(c.type==T||d.type==T)c.type==N&&(c=Z(Vi,c,T,0)),d.type==N&&(d=Z(Vi,d,T,0));c.type!=d.type&&U(a,"expressions following then and else have incompatible types");c.q!=d.q&&U(a,"expressions following then and else have different dimensions "+c.q+" and "+d.q+", respectively")}c=
vk(Zj,b,c,d,c.type,c.q)}else sk(a)?U(a,"invalid use of reserved keyword "+a.h):U(a,"syntax error in expression");a.b==bi&&(d=a.h,c.type==T&&(c=Z(Ui,c,N,0)),c.type!=N&&Nk(a,d),Y(a),b=a.b==Yh||a.b==Zh?Rk(a):Qk(a),b.type==T&&(b=Z(Ui,b,N,0)),b.type!=N&&Ok(a,d),c=uk(wj,c,b,N,0));return c}
function Rk(a){var b;a.b==Yh?(Y(a),b=Qk(a),b.type==T&&(b=Z(Ui,b,N,0)),b.type!=N&&b.type!=jh&&Ok(a,"+"),b=Z(Zi,b,b.type,0)):a.b==Zh?(Y(a),b=Qk(a),b.type==T&&(b=Z(Ui,b,N,0)),b.type!=N&&b.type!=jh&&Ok(a,"-"),b=Z($i,b,b.type,0)):b=Qk(a);return b}
function Kk(a){for(var b,c=Rk(a);;)if(a.b==$h)c.type==T&&(c=Z(Ui,c,N,0)),c.type!=N&&c.type!=jh&&Nk(a,"*"),Y(a),b=Rk(a),b.type==T&&(b=Z(Ui,b,N,0)),b.type!=N&&b.type!=jh&&Ok(a,"*"),c.type==jh&&b.type==jh&&U(a,"multiplication of linear forms not allowed"),c=c.type==N&&b.type==N?uk(sj,c,b,N,0):uk(sj,c,b,jh,0);else if(a.b==ai)c.type==T&&(c=Z(Ui,c,N,0)),c.type!=N&&c.type!=jh&&Nk(a,"/"),Y(a),b=Rk(a),b.type==T&&(b=Z(Ui,b,N,0)),b.type!=N&&Ok(a,"/"),c=c.type==N?uk(tj,c,b,N,0):uk(tj,c,b,jh,0);else if(a.b==Jh)c.type==
T&&(c=Z(Ui,c,N,0)),c.type!=N&&Nk(a,"div"),Y(a),b=Rk(a),b.type==T&&(b=Z(Ui,b,N,0)),b.type!=N&&Ok(a,"div"),c=uk(uj,c,b,N,0);else if(a.b==Qh)c.type==T&&(c=Z(Ui,c,N,0)),c.type!=N&&Nk(a,"mod"),Y(a),b=Rk(a),b.type==T&&(b=Z(Ui,b,N,0)),b.type!=N&&Ok(a,"mod"),c=uk(vj,c,b,N,0);else break;return c}
function Sk(a){for(var b,c=Kk(a);;)if(a.b==Yh)c.type==T&&(c=Z(Ui,c,N,0)),c.type!=N&&c.type!=jh&&Nk(a,"+"),Y(a),b=Kk(a),b.type==T&&(b=Z(Ui,b,N,0)),b.type!=N&&b.type!=jh&&Ok(a,"+"),c.type==N&&b.type==jh&&(c=Z(Yi,c,jh,0)),c.type==jh&&b.type==N&&(b=Z(Yi,b,jh,0)),c=uk(pj,c,b,c.type,0);else if(a.b==Zh)c.type==T&&(c=Z(Ui,c,N,0)),c.type!=N&&c.type!=jh&&Nk(a,"-"),Y(a),b=Kk(a),b.type==T&&(b=Z(Ui,b,N,0)),b.type!=N&&b.type!=jh&&Ok(a,"-"),c.type==N&&b.type==jh&&(c=Z(Yi,c,jh,0)),c.type==jh&&b.type==N&&(b=Z(Yi,
b,jh,0)),c=uk(qj,c,b,c.type,0);else if(a.b==Ph)c.type==T&&(c=Z(Ui,c,N,0)),c.type!=N&&Nk(a,"less"),Y(a),b=Kk(a),b.type==T&&(b=Z(Ui,b,N,0)),b.type!=N&&Ok(a,"less"),c=uk(rj,c,b,N,0);else break;return c}function zk(a){for(var b,c=Sk(a);;)if(a.b==ii)c.type==N&&(c=Z(Vi,c,T,0)),c.type!=T&&Nk(a,"&"),Y(a),b=Sk(a),b.type==N&&(b=Z(Vi,b,T,0)),b.type!=T&&Ok(a,"&"),c=uk(Cj,c,b,T,0);else break;return c}
function Tk(a){var b,c,d=zk(a);a.b==pi&&(d.type==T&&(d=Z(Ui,d,N,0)),d.type!=N&&Nk(a,".."),Y(a),b=zk(a),b.type==T&&(b=Z(Ui,b,N,0)),b.type!=N&&Ok(a,".."),a.b==Gh?(Y(a),c=zk(a),c.type==T&&(c=Z(Ui,c,N,0)),c.type!=N&&Ok(a,"by")):c=null,d=vk(Yj,d,b,c,fh,1));return d}function Uk(a){for(var b,c=Tk(a);;)if(a.b==Hh)c.type!=fh&&Nk(a,"cross"),Y(a),b=Tk(a),b.type!=fh&&Ok(a,"cross"),c=uk(Pj,c,b,fh,c.q+b.q);else break;return c}
function Vk(a){for(var b,c=Uk(a);;)if(a.b==Oh)c.type!=fh&&Nk(a,"inter"),Y(a),b=Uk(a),b.type!=fh&&Ok(a,"inter"),c.q!=b.q&&Pk(a,"inter",c.q,b.q),c=uk(Oj,c,b,fh,c.q);else break;return c}
function Gk(a){for(var b,c=Vk(a);;)if(a.b==Wh)c.type!=fh&&Nk(a,"union"),Y(a),b=Vk(a),b.type!=fh&&Ok(a,"union"),c.q!=b.q&&Pk(a,"union",c.q,b.q),c=uk(Lj,c,b,fh,c.q);else if(a.b==Ih)c.type!=fh&&Nk(a,"diff"),Y(a),b=Vk(a),b.type!=fh&&Ok(a,"diff"),c.q!=b.q&&Pk(a,"diff",c.q,b.q),c=uk(Mj,c,b,fh,c.q);else if(a.b==Uh)c.type!=fh&&Nk(a,"symdiff"),Y(a),b=Vk(a),b.type!=fh&&Ok(a,"symdiff"),c.q!=b.q&&Pk(a,"symdiff",c.q,b.q),c=uk(Nj,c,b,fh,c.q);else break;return c}
function Wk(a){var b,c=-1,d="",e=Gk(a);switch(a.b){case ci:c=Dj;break;case di:c=Ej;break;case ei:c=Fj;break;case fi:c=Gj;break;case gi:c=Hj;break;case hi:c=Ij;break;case Mh:c=Qj;break;case Xh:c=Sj;break;case Rh:d=a.h;Y(a);a.b==Mh?c=Rj:a.b==Xh?c=Tj:U(a,"invalid use of "+d);d+=" ";break;default:return e}d+=a.h;switch(c){case Fj:case Ij:case Dj:case Ej:case Hj:case Gj:e.type!=N&&e.type!=T&&Nk(a,d);Y(a);b=Gk(a);b.type!=N&&b.type!=T&&Ok(a,d);e.type==N&&b.type==T&&(e=Z(Vi,e,T,0));e.type==T&&b.type==N&&
(b=Z(Vi,b,T,0));e=uk(c,e,b,nh,0);break;case Qj:case Rj:e.type==N&&(e=Z(Vi,e,T,0));e.type==T&&(e=Z(Xi,e,xh,1));e.type!=xh&&Nk(a,d);Y(a);b=Gk(a);b.type!=fh&&Ok(a,d);e.q!=b.q&&Pk(a,d,e.q,b.q);e=uk(c,e,b,nh,0);break;case Sj:case Tj:e.type!=fh&&Nk(a,d),Y(a),b=Gk(a),b.type!=fh&&Ok(a,d),e.q!=b.q&&Pk(a,d,e.q,b.q),e=uk(c,e,b,nh,0)}return e}function Xk(a){var b,c;a.b==Rh?(c=a.h,Y(a),b=Wk(a),b.type==T&&(b=Z(Ui,b,N,0)),b.type==N&&(b=Z(Wi,b,nh,0)),b.type!=nh&&Ok(a,c),b=Z(aj,b,nh,0)):b=Wk(a);return b}
function Lk(a){for(var b,c="",d=Xk(a);;)if(a.b==Fh)c=a.h,d.type==T&&(d=Z(Ui,d,N,0)),d.type==N&&(d=Z(Wi,d,nh,0)),d.type!=nh&&Nk(a,c),Y(a),b=Xk(a),b.type==T&&(b=Z(Ui,b,N,0)),b.type==N&&(b=Z(Wi,b,nh,0)),b.type!=nh&&Ok(a,c),d=uk(Jj,d,b,nh,0);else break;return d}
function Ek(a){for(var b,c=Lk(a);;)if(a.b==Sh){var d=a.h;c.type==T&&(c=Z(Ui,c,N,0));c.type==N&&(c=Z(Wi,c,nh,0));c.type!=nh&&Nk(a,d);Y(a);b=Lk(a);b.type==T&&(b=Z(Ui,b,N,0));b.type==N&&(b=Z(Wi,b,nh,0));b.type!=nh&&Ok(a,d);c=uk(Kj,c,b,nh,0)}else break;return c}
function Yk(a){function b(){U(a,"at most one := or default/data allowed")}function c(){U(a,a.h+" not a plain set")}function d(){U(a,"dimension of "+a.h+" too small")}function e(){U(a,"component number must be integer between 1 and "+k.set.X)}var f,g,h=0,k;Y(a);a.b!=Bh&&(sk(a)?U(a,"invalid use of reserved keyword "+a.h):U(a,"symbolic name missing where expected"));null!=a.V[a.h]&&U(a,a.h+" multiply declared");f={};f.name=a.h;f.Ib=null;f.q=0;f.domain=null;f.X=0;f.Bf=null;f.assign=null;f.xa=null;f.Yc=
null;f.data=0;f.O=null;Y(a);a.b==Eh&&(f.Ib=a.h,Y(a));a.b==ui&&(f.domain=Fk(a),f.q=Mk(f.domain));g=a.V[f.name]={};g.type=uh;for(g.link=f;;){if(a.b==li)Y(a);else if(a.b==ni)break;if(rk(a,"dimen")){var l;Y(a);a.b==Dh&&1<=a.value&&20>=a.value&&Math.floor(a.value)==a.value||U(a,"dimension must be integer between 1 and 20");l=a.value+0.5|0;h&&U(a,"at most one dimension attribute allowed");0<f.X&&U(a,"dimension "+l+" conflicts with dimension "+f.X+" already determined");f.X=l;h=1;Y(a)}else if(a.b==Xh||a.b==
Mh){a.b!=Mh||a.rg||(ok(a,"keyword in understood as within"),a.rg=1);Y(a);l={code:null,e:null};if(null==f.Bf)f.Bf=l;else{for(g=f.Bf;null!=g.e;g=g.e);g.e=l}l.code=Gk(a);l.code.type!=fh&&U(a,"expression following within has invalid type");0==f.X&&(f.X=l.code.q);f.X!=l.code.q&&U(a,"set expression following within must have dimension "+f.X+" rather than "+l.code.q)}else if(a.b==oi)null==f.assign&&null==f.xa&&null==f.Yc||b(),Y(a),f.assign=Gk(a),f.assign.type!=fh&&U(a,"expression following := has invalid type"),
0==f.X&&(f.X=f.assign.q),f.X!=f.assign.q&&U(a,"set expression following := must have dimension "+f.X+" rather than "+f.assign.q);else if(rk(a,"default"))null==f.assign&&null==f.xa||b(),Y(a),f.xa=Gk(a),f.xa.type!=fh&&U(a,"expression following default has invalid type"),0==f.X&&(f.X=f.xa.q),f.X!=f.xa.q&&U(a,"set expression following default must have dimension "+f.X+" rather than "+f.xa.q);else if(rk(a,"data")){var p=0;l=Array(20);null==f.assign&&null==f.Yc||b();Y(a);f.Yc=k={};a.b!=Bh&&(sk(a)?U(a,"invalid use of reserved keyword "+
a.h):U(a,"set name missing where expected"));g=a.V[a.h];null==g&&U(a,a.h+" not defined");g.type!=uh&&c();k.set=g.link;0!=k.set.q&&c();k.set==f&&U(a,"set cannot be initialized by itself");f.q>=k.set.X&&d();0==f.X&&(f.X=k.set.X-f.q);f.q+f.X>k.set.X?d():f.q+f.X<k.set.X&&U(a,"dimension of "+a.h+" too big");Y(a);a.b==qi?Y(a):U(a,"left parenthesis missing where expected");for(g=0;g<k.set.X;g++)l[g]=0;for(g=0;;)if(a.b!=Dh&&U(a,"component number missing where expected"),0!=wg(a.h,function(a){p=a})&&e(),1<=
p&&p<=k.set.X||e(),0!=l[p-1]&&U(a,"component "+p+" multiply specified"),k.Z[g++]=p,l[p-1]=1,Y(a),a.b==li)Y(a);else if(a.b==ri)break;else U(a,"syntax error in data attribute");g<k.set.X&&U(a,"there are must be "+k.set.X+" components rather than "+g);Y(a)}else U(a,"syntax error in set statement")}null!=f.domain&&Hk(a,f.domain);0==f.X&&(f.X=1);Y(a);return f}
function Zk(a){function b(){g&&U(a,"at most one binary allowed");d.type==T&&U(a,"symbolic parameter cannot be binary");d.type=ah;g=1;Y(a)}function c(){U(a,"at most one := or default allowed")}var d,e,f=0,g=0,h=0;Y(a);a.b!=Bh&&(sk(a)?U(a,"invalid use of reserved keyword "+a.h):U(a,"symbolic name missing where expected"));null!=a.V[a.h]&&U(a,a.h+" multiply declared");d={};d.name=a.h;d.Ib=null;d.q=0;d.domain=null;d.type=N;d.wd=null;d.qa=null;d.assign=null;d.xa=null;d.data=0;d.Wc=null;d.O=null;Y(a);a.b==
Eh&&(d.Ib=a.h,Y(a));a.b==ui&&(d.domain=Fk(a),d.q=Mk(d.domain));e=a.V[d.name]={};e.type=sh;for(e.link=d;;){if(a.b==li)Y(a);else if(a.b==ni)break;if(rk(a,"integer"))f&&U(a,"at most one integer allowed"),d.type==T&&U(a,"symbolic parameter cannot be integer"),d.type!=ah&&(d.type=mh),f=1,Y(a);else if(rk(a,"binary"))b();else if(rk(a,"logical"))a.Ke||(ok(a,"keyword logical understood as binary"),a.Ke=1),b();else if(rk(a,"symbolic"))h&&U(a,"at most one symbolic allowed"),d.type!=N&&U(a,"integer or binary parameter cannot be symbolic"),
null==d.wd&&null==d.qa&&null==d.assign&&null==d.xa||U(a,"keyword symbolic must precede any other parameter attributes"),d.type=T,h=1,Y(a);else if(a.b==ci||a.b==di||a.b==ei||a.b==fi||a.b==gi||a.b==hi){var k,l={};switch(a.b){case ci:l.jd=Dj;k=a.h;break;case di:l.jd=Ej;k=a.h;break;case ei:l.jd=Fj;k=a.h;break;case fi:l.jd=Gj;k=a.h;break;case gi:l.jd=Hj;k=a.h;break;case hi:l.jd=Ij,k=a.h}l.code=null;l.e=null;if(null==d.wd)d.wd=l;else{for(e=d.wd;null!=e.e;e=e.e);e.e=l}Y(a);l.code=zk(a);l.code.type!=N&&l.code.type!=
T&&U(a,"expression following "+k+" has invalid type");d.type!=T&&l.code.type==T&&(l.code=Z(Ui,l.code,N,0));d.type==T&&l.code.type!=T&&(l.code=Z(Vi,l.code,T,0))}else if(a.b==Mh||a.b==Xh){a.b!=Xh||a.qg||(ok(a,"keyword within understood as in"),a.qg=1);Y(a);l={code:null,e:null};if(null==d.qa)d.qa=l;else{for(e=d.qa;null!=e.e;e=e.e);e.e=l}l.code=Gk(a);l.code.type!=fh&&U(a,"expression following in has invalid type");1!=l.code.q&&U(a,"set expression following in must have dimension 1 rather than "+l.code.q)}else a.b==
oi?(null==d.assign&&null==d.xa||c(),Y(a),d.assign=zk(a),d.assign.type!=N&&d.assign.type!=T&&U(a,"expression following := has invalid type"),d.type!=T&&d.assign.type==T&&(d.assign=Z(Ui,d.assign,N,0)),d.type==T&&d.assign.type!=T&&(d.assign=Z(Vi,d.assign,T,0))):rk(a,"default")?(null==d.assign&&null==d.xa||c(),Y(a),d.xa=zk(a),d.xa.type!=N&&d.xa.type!=T&&U(a,"expression following default has invalid type"),d.type!=T&&d.xa.type==T&&(d.xa=Z(Ui,d.xa,N,0)),d.type==T&&d.xa.type!=T&&(d.xa=Z(Vi,d.xa,T,0))):U(a,
"syntax error in parameter statement")}null!=d.domain&&Hk(a,d.domain);Y(a);return d}
function $k(a){function b(){d&&U(a,"at most one binary allowed");e.type=ah;d=1;Y(a)}var c=0,d=0;a.Ob&&U(a,"variable statement must precede solve statement");Y(a);a.b!=Bh&&(sk(a)?U(a,"invalid use of reserved keyword "+a.h):U(a,"symbolic name missing where expected"));null!=a.V[a.h]&&U(a,a.h+" multiply declared");var e={};e.name=a.h;e.Ib=null;e.q=0;e.domain=null;e.type=N;e.P=null;e.W=null;e.O=null;Y(a);a.b==Eh&&(e.Ib=a.h,Y(a));a.b==ui&&(e.domain=Fk(a),e.q=Mk(e.domain));var f=a.V[e.name]={};f.type=yh;
for(f.link=e;;){if(a.b==li)Y(a);else if(a.b==ni)break;if(rk(a,"integer"))c&&U(a,"at most one integer allowed"),e.type!=ah&&(e.type=mh),c=1,Y(a);else if(rk(a,"binary"))b();else if(rk(a,"logical"))a.Ke||(ok(a,"keyword logical understood as binary"),a.Ke=1),b();else if(rk(a,"symbolic"))U(a,"variable cannot be symbolic");else if(a.b==fi)null!=e.P&&(e.P==e.W?U(a,"both fixed value and lower bound not allowed"):U(a,"at most one lower bound allowed")),Y(a),e.P=zk(a),e.P.type==T&&(e.P=Z(Ui,e.P,N,0)),e.P.type!=
N&&U(a,"expression following >= has invalid type");else if(a.b==di)null!=e.W&&(e.W==e.P?U(a,"both fixed value and upper bound not allowed"):U(a,"at most one upper bound allowed")),Y(a),e.W=zk(a),e.W.type==T&&(e.W=Z(Ui,e.W,N,0)),e.W.type!=N&&U(a,"expression following <= has invalid type");else if(a.b==ei){if(null!=e.P||null!=e.W)e.P==e.W?U(a,"at most one fixed value allowed"):null!=e.P?U(a,"both lower bound and fixed value not allowed"):U(a,"both upper bound and fixed value not allowed");f=a.h;Y(a);
e.P=zk(a);e.P.type==T&&(e.P=Z(Ui,e.P,N,0));e.P.type!=N&&U(a,"expression following "+f+" has invalid type");e.W=e.P}else a.b==ci||a.b==gi||a.b==hi?U(a,"strict bound not allowed"):U(a,"syntax error in variable statement")}null!=e.domain&&Hk(a,e.domain);Y(a);return e}
function al(a){function b(){U(a,"syntax error in constraint statement")}var c,d,e,f;a.Ob&&U(a,"constraint statement must precede solve statement");rk(a,"subject")?(Y(a),rk(a,"to")||U(a,"keyword subject to incomplete"),Y(a)):rk(a,"subj")?(Y(a),rk(a,"to")||U(a,"keyword subj to incomplete"),Y(a)):a.b==Th&&Y(a);a.b!=Bh&&(sk(a)?U(a,"invalid use of reserved keyword "+a.h):U(a,"symbolic name missing where expected"));null!=a.V[a.h]&&U(a,a.h+" multiply declared");var g={};g.name=a.h;g.Ib=null;g.q=0;g.domain=
null;g.type=ch;g.code=null;g.P=null;g.W=null;g.O=null;Y(a);a.b==Eh&&(g.Ib=a.h,Y(a));a.b==ui&&(g.domain=Fk(a),g.q=Mk(g.domain));c=a.V[g.name]={};c.type=ch;c.link=g;a.b!=mi&&U(a,"colon missing where expected");Y(a);c=zk(a);c.type==T&&(c=Z(Ui,c,N,0));c.type!=N&&c.type!=jh&&U(a,"expression following colon has invalid type");a.b==li&&Y(a);switch(a.b){case di:case fi:case ei:break;case ci:case gi:case hi:U(a,"strict inequality not allowed");break;case ni:U(a,"constraint must be equality or inequality");
break;default:b()}f=a.b;e=a.h;Y(a);d=zk(a);d.type==T&&(d=Z(Ui,d,N,0));d.type!=N&&d.type!=jh&&U(a,"expression following "+e+" has invalid type");a.b==li&&(Y(a),a.b==ni&&b());a.b==ci||a.b==di||a.b==ei||a.b==fi||a.b==gi||a.b==hi?(f!=ei&&a.b==f||U(a,"double inequality must be ... <= ... <= ... or ... >= ... >= ..."),c.type==jh&&U(a,"leftmost expression in double inequality cannot be linear form"),Y(a),e=zk(a),e.type==T&&(e=Z(Ui,d,N,0)),e.type!=N&&e.type!=jh&&U(a,"rightmost expression in double inequality constraint has invalid type"),
e.type==jh&&U(a,"rightmost expression in double inequality cannot be linear form")):e=null;null!=g.domain&&Hk(a,g.domain);c.type!=jh&&(c=Z(Yi,c,jh,0));d.type!=jh&&(d=Z(Yi,d,jh,0));null!=e&&(e=Z(Yi,e,jh,0));if(null==e)switch(f){case di:g.code=c;g.P=null;g.W=d;break;case fi:g.code=c;g.P=d;g.W=null;break;case ei:g.code=c,g.P=d,g.W=d}else switch(f){case di:g.code=d;g.P=c;g.W=e;break;case fi:g.code=d,g.P=e,g.W=c}a.b!=ni&&b();Y(a);return g}
function bl(a){var b,c={domain:null};c.list=b=null;Y(a);a.b==ui&&(c.domain=Fk(a));for(a.b==mi&&Y(a);;){var d={v:{}},e=function(){d.type=hh;d.v.code=Ek(a)};d.type=0;d.e=null;null==c.list?c.list=d:b.e=d;b=d;if(a.b==Bh){var f;Y(a);f=a.b;qk(a);if(f!=li&&f!=ni)e();else{e=a.V[a.h];null==e&&U(a,a.h+" not defined");d.type=e.type;switch(e.type){case kh:d.v.ya=e.link;break;case uh:d.v.set=e.link;break;case sh:d.v.S=e.link;break;case yh:d.v.t=e.link;a.Ob||U(a,"invalid reference to variable "+d.v.t.name+" above solve statement");
break;case ch:d.v.H=e.link,a.Ob||U(a,"invalid reference to "+(d.v.H.type==ch?"constraint":"objective")+" "+d.v.H.name+" above solve statement")}Y(a)}}else e();if(a.b==li)Y(a);else break}null!=c.domain&&Hk(a,c.domain);a.b!=ni&&U(a,"syntax error in display statement");Y(a);return c}
function cl(a){!a.nc&&rk(a,"end")||a.nc&&dl(a,"end")?(Y(a),a.b==ni?Y(a):ok(a,"no semicolon following end statement; missing semicolon inserted")):ok(a,"unexpected end of file; missing end statement inserted");a.b!=Ah&&ok(a,"some text detected beyond end statement; text ignored")}
function el(a,b){var c={v:{}};c.bb=a.bb;c.Vc=a.Vc;c.e=null;if(rk(a,"set"))b&&U(a,"set statement not allowed here"),c.type=uh,c.v.set=Yk(a);else if(rk(a,"param"))b&&U(a,"parameter statement not allowed here"),c.type=sh,c.v.S=Zk(a);else if(rk(a,"var"))b&&U(a,"variable statement not allowed here"),c.type=yh,c.v.t=$k(a);else if(rk(a,"subject")||rk(a,"subj")||a.b==Th)b&&U(a,"constraint statement not allowed here"),c.type=ch,c.v.H=al(a);else if(rk(a,"minimize")||rk(a,"maximize")){b&&U(a,"objective statement not allowed here");
c.type=ch;var d=c.v,e,f;rk(a,"minimize")?f=ph:rk(a,"maximize")&&(f=oh);a.Ob&&U(a,"objective statement must precede solve statement");Y(a);a.b!=Bh&&(sk(a)?U(a,"invalid use of reserved keyword "+a.h):U(a,"symbolic name missing where expected"));null!=a.V[a.h]&&U(a,a.h+" multiply declared");e={};e.name=a.h;e.Ib=null;e.q=0;e.domain=null;e.type=f;e.code=null;e.P=null;e.W=null;e.O=null;Y(a);a.b==Eh&&(e.Ib=a.h,Y(a));a.b==ui&&(e.domain=Fk(a),e.q=Mk(e.domain));f=a.V[e.name]={};f.type=ch;f.link=e;a.b!=mi&&
U(a,"colon missing where expected");Y(a);e.code=zk(a);e.code.type==T&&(e.code=Z(Ui,e.code,N,0));e.code.type==N&&(e.code=Z(Yi,e.code,jh,0));e.code.type!=jh&&U(a,"expression following colon has invalid type");null!=e.domain&&Hk(a,e.domain);a.b!=ni&&U(a,"syntax error in objective statement");Y(a);d.H=e}else if(rk(a,"table")){b&&U(a,"table statement not allowed here");c.type=wh;var d=c.v,g,h,k;Y(a);a.b!=Bh&&(sk(a)?U(a,"invalid use of reserved keyword "+a.h):U(a,"symbolic name missing where expected"));
null!=a.V[a.h]&&U(a,a.h+" multiply declared");e={v:{qa:{},Oc:{}}};e.name=a.h;Y(a);a.b==Eh?(e.Ib=a.h,Y(a)):e.Ib=null;a.b==ui?(e.type=rh,e.v.Oc.domain=Fk(a),rk(a,"OUT")||U(a,"keyword OUT missing where expected")):(e.type=lh,rk(a,"IN")||U(a,"keyword IN missing where expected"));Y(a);for(e.a=f=null;;)if(g={},a.b!=li&&a.b!=mi&&a.b!=ni||U(a,"argument expression missing where expected"),g.code=zk(a),g.code.type==N&&(g.code=Z(Vi,g.code,T,0)),g.code.type!=T&&U(a,"argument expression has invalid type"),g.e=
null,null==f?e.a=g:f.e=g,f=g,a.b==li)Y(a);else if(a.b==mi||a.b==ni)break;a.b==mi?Y(a):U(a,"colon missing where expected");switch(e.type){case lh:a.b==Bh?(g=a.V[a.h],null==g&&U(a,a.h+" not defined"),g.type!=uh&&U(a,a.h+" not a set"),e.v.qa.set=g.link,null!=e.v.qa.set.assign&&U(a,a.h+" needs no data"),0!=e.v.qa.set.q&&U(a,a.h+" must be a simple set"),Y(a),a.b==yi?Y(a):U(a,"delimiter <- missing where expected")):sk(a)?U(a,"invalid use of reserved keyword "+a.h):e.v.qa.set=null;e.v.qa.We=g=null;f=0;for(a.b==
si?Y(a):U(a,"field list missing where expected");;)if(h={},a.b!=Bh&&(sk(a)?U(a,"invalid use of reserved keyword "+a.h):U(a,"field name missing where expected")),h.name=a.h,Y(a),h.e=null,null==g?e.v.qa.We=h:g.e=h,g=h,f++,a.b==li)Y(a);else if(a.b==ti)break;else U(a,"syntax error in field list");null!=e.v.qa.set&&e.v.qa.set.X!=f&&U(a,"there must be "+e.v.qa.set.X+" field"+(1==e.v.qa.set.X?"":"s")+" rather than "+f);Y(a);for(e.v.qa.list=h=null;a.b==li;)Y(a),k={},a.b!=Bh&&(sk(a)?U(a,"invalid use of reserved keyword "+
a.h):U(a,"parameter name missing where expected")),g=a.V[a.h],null==g&&U(a,a.h+" not defined"),g.type!=sh&&U(a,a.h+" not a parameter"),k.S=g.link,k.S.q!=f&&U(a,a.h+" must have "+f+" subscript"+(1==f?"":"s")+" rather than "+k.S.q),null!=k.S.assign&&U(a,a.h+" needs no data"),Y(a),a.b==xi?(Y(a),a.b!=Bh&&(sk(a)?U(a,"invalid use of reserved keyword "+a.h):U(a,"field name missing where expected")),g=a.h,Y(a)):g=k.S.name,k.name=g,k.e=null,null==h?e.v.qa.list=k:h.e=k,h=k;break;case rh:for(e.v.Oc.list=f=null;;)if(h=
{},a.b!=li&&a.b!=ni||U(a,"expression missing where expected"),g=a.b==Bh?a.h:"",h.code=zk(a),a.b==xi&&(Y(a),a.b!=Bh&&(sk(a)?U(a,"invalid use of reserved keyword "+a.h):U(a,"field name missing where expected")),g=a.h,Y(a)),""==g&&U(a,"field name required"),h.name=g,h.e=null,null==f?e.v.Oc.list=h:f.e=h,f=h,a.b==li)Y(a);else if(a.b==ni)break;else U(a,"syntax error in output list");Hk(a,e.v.Oc.domain)}a.b!=ni&&U(a,"syntax error in table statement");Y(a);d.nd=e}else if(rk(a,"solve"))b&&U(a,"solve statement not allowed here"),
c.type=vh,d=c.v,a.Ob&&U(a,"at most one solve statement allowed"),a.Ob=1,Y(a),a.b!=ni&&U(a,"syntax error in solve statement"),Y(a),d.zh=null;else if(rk(a,"check"))c.type=bh,d=c.v,e={domain:null,code:null},Y(a),a.b==ui&&(e.domain=Fk(a)),a.b==mi&&Y(a),e.code=Ek(a),e.code.type!=nh&&U(a,"expression has invalid type"),null!=e.domain&&Hk(a,e.domain),a.b!=ni&&U(a,"syntax error in check statement"),Y(a),d.Rg=e;else if(rk(a,"display"))c.type=dh,c.v.Sg=bl(a);else if(rk(a,"printf")){c.type=th;d=c.v;g={domain:null,
zd:null};g.list=f=null;Y(a);a.b==ui&&(g.domain=Fk(a));a.b==mi&&Y(a);g.zd=zk(a);g.zd.type==N&&(g.zd=Z(Vi,g.zd,T,0));for(g.zd.type!=T&&U(a,"format expression has invalid type");a.b==li;)Y(a),e={code:null,e:null},null==g.list?g.list=e:f.e=e,f=e,e.code=Gk(a),e.code.type!=N&&e.code.type!=T&&e.code.type!=nh&&U(a,"only numeric, symbolic, or logical expression allowed");null!=g.domain&&Hk(a,g.domain);g.Ea=null;g.Mg=0;if(a.b==gi||a.b==wi)g.Mg=a.b==wi,Y(a),g.Ea=zk(a),g.Ea.type==N&&(g.Ea=Z(Vi,g.Ea,T,0)),g.Ea.type!=
T&&U(a,"file name expression has invalid type");a.b!=ni&&U(a,"syntax error in printf statement");Y(a);d.nh=g}else if(rk(a,"for")){c.type=ih;d=c.v;g={domain:null};g.list=f=null;Y(a);a.b!=ui&&U(a,"indexing expression missing where expected");g.domain=Fk(a);a.b==mi&&Y(a);if(a.b!=ui)g.list=el(a,1);else{for(Y(a);a.b!=vi;)e=el(a,1),null==f?g.list=e:f.e=e,f=e;Y(a)}Hk(a,g.domain);d.Ug=g}else a.b==Bh?(b&&U(a,"constraint statement not allowed here"),c.type=ch,c.v.H=al(a)):sk(a)?U(a,"invalid use of reserved keyword "+
a.h):U(a,"syntax error in model section");return c}function fl(a){var b,c;for(c=null;a.b!=Ah&&!rk(a,"data")&&!rk(a,"end");)b=el(a,0),null==c?a.uc=b:c.e=b,c=b}function gl(a,b){var c,d={};d.Y=b;d.e=null;if(null==a)a=d;else{for(c=a;null!=c.e;c=c.e);c.e=d}return a}function hl(a){for(var b=0;null!=a;a=a.e)b++;return b}function il(a){for(var b=0;null!=a;a=a.e)null==a.Y&&b++;return b}function jl(a){for(var b=null;0<a--;)b=gl(b,null);return b}function kl(a){return a.b==Dh||a.b==Ch||a.b==Eh}
function dl(a,b){return kl(a)&&a.h==b}function ll(a){var b;b=a.b==Dh?ml(a.value):nl(a.h);Y(a);return b}
function ol(a,b,c){var d,e;switch(a.b){case si:e=ti;break;case qi:e=ri}0==c&&U(a,b+" cannot be subscripted");Y(a);for(d=null;;)if(kl(a)?d=gl(d,ll(a)):a.b==$h?(d=gl(d,null),Y(a)):U(a,"number, symbol, or asterisk missing where expected"),a.b==li)Y(a);else if(a.b==e)break;else U(a,"syntax error in slice");if(hl(d)!=c)switch(e){case ti:U(a,b+" must have "+c+" subscript"+(1==c?"":"s")+", not "+hl(d));break;case ri:U(a,b+" has dimension "+c+", not "+hl(d))}Y(a);return d}
function pl(a,b){var c;c=a.V[b];null!=c&&c.type==uh||U(a,b+" not a set");c=c.link;null==c.assign&&null==c.Yc||U(a,b+" needs no data");c.data=1;return c}function ql(a,b,c){var d,e,f=null;for(d=null;null!=c;c=c.e)null==c.Y?(kl(a)||(e=il(c),1==e?U(a,"one item missing in data group beginning with "+rl(f)):U(a,e+" items missing in data group beginning with "+rl(f))),e=ll(a),null==f&&(f=e)):e=sl(c.Y),d=tl(d,e),null!=c.e&&a.b==li&&Y(a);ul(a,b.value.set,d)}
function vl(a,b,c,d){var e,f,g,h,k;for(e=null;a.b!=oi;)kl(a)||U(a,"number, symbol, or := missing where expected"),e=gl(e,ll(a));for(Y(a);kl(a);)for(k=ll(a),f=e;null!=f;f=f.e){var l=0;if(!dl(a,"+"))if(dl(a,"-")){Y(a);continue}else g=hl(f),1==g?U(a,"one item missing in data group beginning with "+rl(k)):U(a,g+" items missing in data group beginning with "+rl(k));h=null;for(g=c;null!=g;g=g.e)if(null==g.Y)switch(++l){case 1:h=tl(h,sl(d?f.Y:k));break;case 2:h=tl(h,sl(d?k:f.Y))}else h=tl(h,sl(g.Y));ul(a,
b.value.set,h);Y(a)}}
function wl(a){function b(){U(a,"slice currently used must specify 2 asterisks, not "+il(h))}function c(){U(a,"transpose indicator (tr) incomplete")}function d(){Y(a);dl(a,"tr")||c();2!=il(h)&&b();Y(a);a.b!=ri&&c();Y(a);a.b==mi&&Y(a);k=1;vl(a,g,h,k)}var e,f,g,h,k=0;Y(a);kl(a)||U(a,"set name missing where expected");e=pl(a,a.h);Y(a);f=null;if(a.b==si){0==e.q&&U(a,e.name+" cannot be subscripted");for(Y(a);;)if(kl(a)||U(a,"number or symbol missing where expected"),f=tl(f,ll(a)),a.b==li)Y(a);else if(a.b==
ti)break;else U(a,"syntax error in subscript list");e.q!=xl(f)&&U(a,e.name+" must have "+e.q+" subscript"+(1==e.q?"":"s")+" rather than "+xl(f));Y(a)}else 0!=e.q&&U(a,e.name+" must be subscripted");null!=yl(a,e.O,f)&&U(a,e.name+zl("[",f)+" already defined");g=Al(e.O,f);g.value.set=Bl(a,qh,e.X);for(h=jl(e.X);;)if(a.b==li&&Y(a),a.b==oi)Y(a);else if(a.b==qi)Y(a),f=dl(a,"tr"),qk(a),f?d():(h=ol(a,e.name,e.X),k=0,0==il(h)&&ql(a,g,h));else if(kl(a))ql(a,g,h);else if(a.b==mi)2!=il(h)&&b(),Y(a),vl(a,g,h,k);
else if(a.b==qi)d();else if(a.b==ni){Y(a);break}else U(a,"syntax error in set data block")}function Cl(a,b){var c;c=a.V[b];null!=c&&c.type==sh||U(a,b+" not a parameter");c=c.link;null!=c.assign&&U(a,b+" needs no data");c.data&&U(a,b+" already provided with data");c.data=1;return c}function Dl(a,b,c){null!=b.xa&&U(a,"default value for "+b.name+" already specified in model section");b.Wc=c}
function El(a,b,c){null!=yl(a,b.O,c)&&U(a,b.name+zl("[",c)+" already defined");c=Al(b.O,c);switch(b.type){case N:case mh:case ah:a.b==Dh||U(a,b.name+" requires numeric data");b=c.value;c=a.value;Y(a);b.Q=c;break;case T:c.value.Y=ll(a)}}
function Fl(a,b,c){var d,e,f=null;for(d=null;null!=c;c=c.e)null==c.Y?(kl(a)||U(a,il(c)+1+" items missing in data group beginning with "+rl(f)),e=ll(a),null==f&&(f=e)):e=sl(c.Y),d=tl(d,e),a.b==li&&Y(a);kl(a)||U(a,"one item missing in data group beginning with "+rl(f));El(a,b,d)}
function Gl(a,b,c,d){var e,f,g,h,k;for(e=null;a.b!=oi;)kl(a)||U(a,"number, symbol, or := missing where expected"),e=gl(e,ll(a));for(Y(a);kl(a);)for(k=ll(a),f=e;null!=f;f=f.e){var l=0;if(dl(a,"."))Y(a);else{h=null;for(g=c;null!=g;g=g.e)if(null==g.Y)switch(++l){case 1:h=tl(h,sl(d?f.Y:k));break;case 2:h=tl(h,sl(d?k:f.Y))}else h=tl(h,sl(g.Y));kl(a)||(g=hl(f),1==g?U(a,"one item missing in data group beginning with "+rl(k)):U(a,g+" items missing in data group beginning with "+rl(k)));El(a,b,h)}}}
function Hl(a,b){var c=null,d,e,f,g,h=0;g=null;kl(a)&&(Y(a),e=a.b,qk(a),e==mi&&(c=pl(a,a.h),0!=c.q&&U(a,c.name+" must be a simple set"),null!=c.O.head&&U(a,c.name+" already defined"),Al(c.O,null).value.set=Bl(a,qh,c.X),g=c.name,h=c.X,Y(a),Y(a)));for(e=null;a.b!=oi;)kl(a)||U(a,"parameter name or := missing where expected"),d=Cl(a,a.h),0==d.q&&U(a,a.h+" not a subscripted parameter"),0!=h&&d.q!=h&&U(a,g+" has dimension "+h+" while "+d.name+" has dimension "+d.q),null!=b&&Dl(a,d,sl(b)),e=gl(e,d),g=d.name,
h=d.q,Y(a),a.b==li&&Y(a);0==hl(e)&&U(a,"at least one parameter name required");Y(a);for(a.b==li&&Y(a);kl(a);){g=null;for(f=1;f<=h;f++)kl(a)||(d=hl(e)+h-f+1,U(a,d+" items missing in data group beginning with "+rl(g.Y))),g=tl(g,ll(a)),f<h&&a.b==li&&Y(a);null!=c&&ul(a,c.O.head.value.set,Il(g));a.b==li&&Y(a);for(f=e;null!=f;f=f.e)dl(a,".")?Y(a):(kl(a)||(d=hl(f),1==d?U(a,"one item missing in data group beginning with "+rl(g.Y)):U(a,d+" items missing in data group beginning with "+rl(g.Y))),El(a,f.Y,Il(g)),
null!=f.e&&a.b==li&&Y(a));a.b==li&&(Y(a),kl(a)||qk(a))}for(f=e;null!=f;f=f.e)f.Y=null}
function Jl(a){function b(){U(a,e.name+" not a subscripted parameter")}function c(){U(a,"slice currently used must specify 2 asterisks, not "+il(g))}function d(){U(a,"transpose indicator (tr) incomplete")}var e,f=null,g,h=0;Y(a);dl(a,"default")&&(Y(a),kl(a)||U(a,"default value missing where expected"),f=ll(a),a.b!=mi&&U(a,"colon missing where expected"));if(a.b==mi)Y(a),a.b==li&&Y(a),Hl(a,f),a.b!=ni&&U(a,"symbol, number, or semicolon missing where expected"),Y(a);else for(kl(a)||U(a,"parameter name missing where expected"),
e=Cl(a,a.h),Y(a),dl(a,"default")&&(Y(a),kl(a)||U(a,"default value missing where expected"),f=ll(a),Dl(a,e,f)),g=jl(e.q);;)if(a.b==li&&Y(a),a.b==oi)Y(a);else if(a.b==si)g=ol(a,e.name,e.q),h=0;else if(kl(a))Fl(a,e,g);else if(a.b==mi)0==e.q&&b(),2!=il(g)&&c(),Y(a),Gl(a,e,g,h);else if(a.b==qi)Y(a),dl(a,"tr")||d(),0==e.q&&b(),2!=il(g)&&c(),Y(a),a.b!=ri&&d(),Y(a),a.b==mi&&Y(a),h=1,Gl(a,e,g,h);else if(a.b==ni){Y(a);break}else U(a,"syntax error in parameter data block")}
function Kl(a){for(;a.b!=Ah&&!dl(a,"end");)dl(a,"set")?wl(a):dl(a,"param")?Jl(a):U(a,"syntax error in data section")}function Ll(a,b,c){(0<b&&0<c&&b>0.999*s-c||0>b&&0>c&&b<-0.999*s-c)&&U(a,b+" + "+c+"; floating-point overflow");return b+c}function Ml(a,b,c){(0<b&&0>c&&b>0.999*s+c||0>b&&0<c&&b<-0.999*s+c)&&U(a,b+" - "+c+"; floating-point overflow");return b-c}function Nl(a,b,c){if(b<c)return 0;0<b&&0>c&&b>0.999*s+c&&U(a,b+" less "+c+"; floating-point overflow");return b-c}
function Ol(a,b,c){1<Math.abs(c)&&Math.abs(b)>0.999*s/Math.abs(c)&&U(a,b+" * "+c+"; floating-point overflow");return b*c}function Pl(a,b,c){Math.abs(c)<aa&&U(a,b+" / "+c+"; floating-point zero divide");1>Math.abs(c)&&Math.abs(b)>0.999*s*Math.abs(c)&&U(a,b+" / "+c+"; floating-point overflow");return b/c}
function Ql(a,b,c){Math.abs(c)<aa&&U(a,b+" div "+c+"; floating-point zero divide");1>Math.abs(c)&&Math.abs(b)>0.999*s*Math.abs(c)&&U(a,b+" div "+c+"; floating-point overflow");b/=c;return 0<b?Math.floor(b):0>b?Math.ceil(b):0}function Rl(a,b){var c;if(0==a)c=0;else if(0==b)c=a;else if(c=Math.abs(a)%Math.abs(b),0!=c&&(0>a&&(c=-c),0<a&&0>b||0>a&&0<b))c+=b;return c}
function Sl(a,b,c){(0==b&&0>=c||0>b&&c!=Math.floor(c))&&U(a,b+" ** "+c+"; result undefined");0==b?a=Math.pow(b,c):((1<Math.abs(b)&&1<c&&+Math.log(Math.abs(b))>0.999*Math.log(s)/c||1>Math.abs(b)&&-1>c&&+Math.log(Math.abs(b))<0.999*Math.log(s)/c)&&U(a,b+" ** "+c+"; floating-point overflow"),a=1<Math.abs(b)&&-1>c&&-Math.log(Math.abs(b))<0.999*Math.log(s)/c||1>Math.abs(b)&&1<c&&-Math.log(Math.abs(b))>0.999*Math.log(s)/c?0:Math.pow(b,c));return a}
function Tl(a,b){b>0.999*Math.log(s)&&U(a,"exp("+b+"); floating-point overflow");return Math.exp(b)}function Ul(a,b){0>=b&&U(a,"log("+b+"); non-positive argument");return Math.log(b)}function Vl(a,b){0>=b&&U(a,"log10("+b+"); non-positive argument");return Math.log(b)/Math.LN10}function Wl(a,b){0>b&&U(a,"sqrt("+b+"); negative argument");return Math.sqrt(b)}function Xl(a,b){-1E6<=b&&1E6>=b||U(a,"sin("+b+"); argument too large");return Math.sin(b)}
function Yl(a,b){-1E6<=b&&1E6>=b||U(a,"cos("+b+"); argument too large");return Math.cos(b)}function Zl(a){return Math.atan(a)}function $l(a,b){return Math.atan2(a,b)}function am(a,b,c){c!=Math.floor(c)&&U(a,"round("+b+", "+c+"); non-integer second argument");18>=c&&(a=Math.pow(10,c),Math.abs(b)<0.999*s/a&&(b=Math.floor(b*a+0.5),0!=b&&(b/=a)));return b}
function bm(a,b,c){c!=Math.floor(c)&&U(a,"trunc("+b+", "+c+"); non-integer second argument");18>=c&&(a=Math.pow(10,c),Math.abs(b)<0.999*s/a&&(b=0<=b?Math.floor(b*a):Math.ceil(b*a),0!=b&&(b/=a)));return b}function cm(a,b,c){var d;b>=c&&U(a,"Uniform("+b+", "+c+"); invalid range");d=dm(a.Gd)/2147483648;return d=Ll(a,b*(1-d),c*d)}function em(a){var b,c;do b=-1+2*(dm(a.Gd)/2147483648),c=-1+2*(dm(a.Gd)/2147483648),b=b*b+c*c;while(1<b||0==b);return c*Math.sqrt(-2*Math.log(b)/b)}
function fm(a,b,c){return Ll(a,b,Ol(a,c,em(a)))}function ml(a){var b={};b.Q=a;b.M=null;return b}function nl(a){var b={Q:0};b.M=a;return b}function sl(a){var b={};null==a.M?(b.Q=a.Q,b.M=null):(b.Q=0,b.M=a.M);return b}function gm(a,b){var c;if(null==a.M&&null==b.M)c=a.Q<b.Q?-1:a.Q>b.Q?1:0;else if(null==a.M)c=-1;else if(null==b.M)c=1;else{c=a.M;var d=b.M;c=c==d?0:c>d?1:-1}return c}
function rl(a){var b;if(null==a.M)b=String(a.Q);else{var c,d,e=a.M;if(ua(e[0])||"_"==e[0])for(a=!1,c=1;c<e.length;c++){if(!(va(e[c])||0<="+-._".indexOf(e[c]))){a=!0;break}}else a=!0;b="";d=0;var f=function(a){255>d&&(b+=a,d++)};a&&f("'");for(c=0;c<e.length;c++)a&&"'"==e[c]&&f("'"),f(e[c]);a&&f("'");255==d&&(b=b.slice(0,252)+"...")}return b}function tl(a,b){var c,d={};d.Y=b;d.e=null;if(null==a)a=d;else{for(c=a;null!=c.e;c=c.e);c.e=d}return a}function xl(a){for(var b=0;null!=a;a=a.e)b++;return b}
function Il(a){var b,c;if(null==a)b=null;else{for(b=c={};null!=a;a=a.e)c.Y=sl(a.Y),null!=a.e&&(c=c.e={});c.e=null}return b}function hm(a,b){var c,d,e;c=a;for(d=b;null!=c;c=c.e,d=d.e)if(e=gm(c.Y,d.Y),0!=e)return e;return 0}function im(a,b){for(var c=null,d=1,e=a;d<=b;d++,e=e.e)c=tl(c,sl(e.Y));return c}
function zl(a,b){function c(a){255>f&&(g+=a);f++}var d,e,f=0,g="",h="",k=xl(b);"["==a&&0<k&&c("[");"("==a&&1<k&&c("(");for(d=b;null!=d;d=d.e)for(d!=b&&c(","),h=rl(d.Y),e=0;e<h.length;e++)c(h[e]);"["==a&&0<k&&c("]");"("==a&&1<k&&c(")");255==f&&(g=g.slice(0,252)+"...");return g}function jm(a,b){Al(a,b).value.eh=null}function ul(a,b,c){null!=yl(a,b,c)&&U(a,"duplicate tuple "+zl("(",c)+" detected");jm(b,c)}function km(a,b){var c,d;c=Bl(a,qh,b.q);for(d=b.head;null!=d;d=d.e)jm(c,Il(d.w));return c}
function lm(a,b,c,d){var e;0==d&&U(a,b+" .. "+c+" by "+d+"; zero stride not allowed");e=0<c&&0>b&&c>0.999*s+b?+s:0>c&&0<b&&c<-0.999*s+b?-s:c-b;1>Math.abs(d)&&Math.abs(e)>0.999*s*Math.abs(d)?e=0<e&&0<d||0>e&&0>d?+s:0:(e=Math.floor(e/d)+1,0>e&&(e=0));2147483646<e&&U(a,b+" .. "+c+" by "+d+"; set too large");return e+0.5|0}function mm(a,b,c,d,e){1<=e&&lm(a,b,c,d);return b+(e-1)*d}function nm(a){var b;0==a?b=null:(b={},b.u=a,b.t=null,b.e=null);return b}
function om(a){var b,c;if(null==a)b=null;else{for(b=c={};null!=a;a=a.e)c.u=a.u,c.t=a.t,null!=a.e&&(c=c.e={});c.e=null}return b}
function pm(a,b,c,d,e){var f=null,g,h=0;for(g=c;null!=g;g=g.e)null==g.t?h=Ll(a,h,Ol(a,b,g.u)):g.t.ja=Ll(a,g.t.ja,Ol(a,b,g.u));for(g=e;null!=g;g=g.e)null==g.t?h=Ll(a,h,Ol(a,d,g.u)):g.t.ja=Ll(a,g.t.ja,Ol(a,d,g.u));for(g=c;null!=g;g=g.e)null!=g.t&&0!=g.t.ja&&(a={},a.u=g.t.ja,a.t=g.t,a.e=f,f=a,g.t.ja=0);for(g=e;null!=g;g=g.e)null!=g.t&&0!=g.t.ja&&(a={},a.u=g.t.ja,a.t=g.t,a.e=f,f=a,g.t.ja=0);0!=h&&(a={},a.u=h,a.t=null,a.e=f,f=a);return f}
function qm(a,b,c){for(var d=null,e,f=0;null!=b;)e=b,b=b.e,null==e.t?f=Ll(a,f,e.u):(e.e=d,d=e);c(f);return d}function rm(a,b){switch(a){case qh:b.eh=null;break;case N:b.Q=0;break;case T:b.Y=null;break;case nh:b.sg=0;break;case xh:b.w=null;break;case fh:b.set=null;break;case gh:b.t=null;break;case jh:b.form=null;break;case eh:b.H=null}}function Bl(a,b,c){var d={};d.type=b;d.q=c;d.size=0;d.head=null;d.Xa=null;d.V=!1;d.ca=null;d.e=a.pg;null!=d.e&&(d.e.ca=d);return a.pg=d}
function sm(a,b,c){return hm(b,c)}function yl(a,b,c){if(30<b.size&&!b.V){var d={root:null};d.yg=sm;d.info=a;d.size=0;d.height=0;b.V=d;for(a=b.head;null!=a;a=a.e)qe(b.V,a.w).link=a}if(b.V){b=b.V;for(a=b.root;null!=a;){d=b.yg(b.info,c,a.key);if(0==d)break;a=0>d?a.left:a.right}c=a;a=null==c?null:c.link}else for(a=b.head;null!=a&&0!=hm(a.w,c);a=a.e);return a}function Al(a,b){var c={};c.w=b;c.e=null;c.value={};a.size++;null==a.head?a.head=c:a.Xa.e=c;a.Xa=c;null!=a.V&&(qe(a.V,c.w).link=c);return c}
function tm(a){var b;if(null!=a.Le)for(b=a.list,a=a.Le;null!=b;b=b.e,a=a.e)a:{var c=b,d=a.Y,e=void 0,f=void 0;if(null!=c.value){if(0==gm(c.value,d))break a;c.value=null}for(e=c.list;null!=e;e=e.a.index.e)for(f=e;null!=f;f=f.R)f.valid&&(f.valid=0,rm(f.type,f.value));c.value=sl(d)}}function um(a,b,c,d,e){var f,g=0;if(!vm(a,b.code,c))return 1;f=b.Le;b.Le=c;tm(b);e(a,d);b.Le=f;tm(b);return g}
function wm(a,b){if(null!=b.Kc){var c,d,e=null,f=null;c=b.Kc;b.Kc=c.e;for(d=c.list;null!=d;d=d.e)null==e?e=f={}:f=f.e={},null==d.code?(f.Y=b.w.Y,b.w=b.w.e):f.Y=xm(a,d.code);f.e=null;um(a,c,e,b,wm)&&(b.Ve=1);for(d=c.list;null!=d;d=d.e)e=e.e}else null==b.domain.code||ym(a,b.domain.code)?b.Zd(a,b.info):b.Ve=2}function zm(a,b,c,d,e){var f={};null==b?(e(a,d),f.Ve=0):(f.domain=b,f.Kc=b.list,f.w=c,f.info=d,f.Zd=e,f.Ve=0,wm(a,f));return f.Ve}
function Am(a,b){if(null!=b.Kc){var c,d,e;c=b.Kc;b.Kc=c.e;e=null;for(d=c.list;null!=d;d=d.e)null!=d.code&&(e=tl(e,xm(a,d.code)));if(c.code.Ta==Yj){var f,g,h,k;g=$(a,c.code.a.a.x);h=$(a,c.code.a.a.y);k=null==c.code.a.a.z?1:$(a,c.code.a.a.z);e=lm(a,g,h,k);d=tl(null,ml(0));for(f=1;f<=e&&b.Wf;f++)d.Y.Q=mm(a,g,h,k,f),um(a,c,d,b,Am)}else for(f=Bm(a,c.code).head;null!=f&&b.Wf;f=f.e){g=f.w;h=e;k=!1;for(d=c.list;null!=d;d=d.e){if(null!=d.code){if(0!=gm(g.Y,h.Y)){k=!0;break}h=h.e}g=g.e}k||um(a,c,f.w,b,Am)}b.Kc=
c}else if(null==b.domain.code||ym(a,b.domain.code))b.Wf=!b.Zd(a,b.info)}function Cm(a,b,c,d){var e={};null==b?d(a,c):(e.domain=b,e.Kc=b.list,e.Wf=1,e.info=c,e.Zd=d,Am(a,e))}function Dm(a,b,c){U(a,b+zl("[",c)+" out of domain")}function Em(a){var b=null;if(null!=a)for(a=a.list;null!=a;a=a.e)for(var c=a.list;null!=c;c=c.e)null==c.code&&(b=tl(b,sl(c.value)));return b}
function Fm(a,b,c,d){for(var e=b.Bf,f=1;null!=e;e=e.e,f++)for(var g=d.head;null!=g;g=g.e)if(!vm(a,e.code,g.w)){var h=zl("(",g.w);U(a,b.name+zl("[",c)+" contains "+h+" which not within specified set; see ("+f+")")}}function Gm(a,b,c){function d(){Fm(a,b,c,e);f=Al(b.O,Il(c));f.value.set=e}var e,f=yl(a,b.O,c);null!=f?e=f.value.set:null!=b.assign?(e=Bm(a,b.assign),d()):null!=b.xa?(e=Bm(a,b.xa),d()):U(a,"no value for "+b.name+zl("[",c));return e}
function Hm(a,b){null!=b.ga?Fm(a,b.set,b.ga.w,b.ga.value.set):b.oe=Gm(a,b.set,b.w)}
function Im(a,b){var c=b.Yc,d,e,f,g=Array(20);x("Generating "+b.name+"...");d=c.set;Cm(a,d.domain,d,Jm);for(d=c.set.O.head.value.set.head;null!=d;d=d.e){f=Il(d.w);for(e=0;e<c.set.X;e++)g[e]=null;for(e=0;null!=f;f=f.e)g[c.Z[e++]-1]=f;for(e=0;e<c.set.X;e++)g[e].e=g[e+1];0==b.q?f=null:(f=g[0],g[b.q-1].e=null);e=yl(a,b.O,f);null==e&&(e=Al(b.O,f),e.value.set=Bl(a,qh,b.X));f=g[b.q];g[c.set.X-1].e=null;jm(e.value.set,f)}b.data=1}
function Km(a,b,c){var d={};d.set=b;d.w=c;null!=b.Yc&&0==b.data&&Im(a,b);if(1==b.data)for(c=b.O.Xa,b.data=2,d.ga=b.O.head;null!=d.ga&&(zm(a,b.domain,d.ga.w,d,Hm)&&Dm(a,b.name,d.ga.w),d.ga!=c);d.ga=d.ga.e);d.ga=null;zm(a,d.set.domain,d.w,d,Hm)&&Dm(a,b.name,d.w);return d.oe}function Jm(a,b){var c=Em(b.domain);Km(a,b,c);return 0}
function Lm(a,b,c,d){var e,f;switch(b.type){case mh:d!=Math.floor(d)&&U(a,b.name+zl("[",c)+" = "+d+" not integer");break;case ah:0!=d&&1!=d&&U(a,b.name+zl("[",c)+" = "+d+" not binary")}e=b.wd;for(f=1;null!=e;e=e.e,f++){var g;g=$(a,e.code);var h=function(e){U(a,b.name+zl("[",c)+" = "+d+" not "+e+" "+g+"; see ("+f+")")};switch(e.jd){case Dj:d<g||h("<");break;case Ej:d<=g||h("<=");break;case Fj:d!=g&&h("=");break;case Gj:d>=g||h(">=");break;case Hj:d>g||h(">");break;case Ij:d==g&&h("<>")}}f=1;for(e=
b.qa;null!=e;e=e.e,f++)h=tl(null,ml(d)),vm(a,e.code,h)||U(a,b.name+zl("[",c)+" = "+d+" not in specified set; see ("+f+")")}function Mm(a,b,c){function d(d){Lm(a,b,c,d);e=Al(b.O,Il(c));return e.value.Q=d}var e=yl(a,b.O,c);return null!=e?e.value.Q:null!=b.assign?d($(a,b.assign)):null!=b.xa?d($(a,b.xa)):null!=b.Wc?(null!=b.Wc.M&&U(a,"cannot convert "+rl(b.Wc)+" to floating-point number"),d(b.Wc.Q)):U(a,"no value for "+b.name+zl("[",c))}
function Nm(a,b){null!=b.ga?Lm(a,b.S,b.ga.w,b.ga.value.Q):b.value=Mm(a,b.S,b.w)}function Om(a,b,c){var d={};d.S=b;d.w=c;if(1==b.data)for(c=b.O.Xa,b.data=2,d.ga=b.O.head;null!=d.ga&&(zm(a,b.domain,d.ga.w,d,Nm)&&Dm(a,b.name,d.ga.w),d.ga!=c);d.ga=d.ga.e);d.ga=null;zm(a,d.S.domain,d.w,d,Nm)&&Dm(a,b.name,d.w);return d.value}
function Pm(a,b,c,d){var e,f=1;for(e=b.wd;null!=e;e=e.e,f++){var g;g=xm(a,e.code);switch(e.jd){case Dj:0>gm(d,g)||(g=rl(g),U(a,b.name+zl("[",c)+" = "+rl(d)+" not < "+g));break;case Ej:0>=gm(d,g)||(g=rl(g),U(a,b.name+zl("[",c)+" = "+rl(d)+" not <= "+g));break;case Fj:0!=gm(d,g)&&(g=rl(g),U(a,b.name+zl("[",c)+" = "+rl(d)+" not = "+g));break;case Gj:0<=gm(d,g)||(g=rl(g),U(a,b.name+zl("[",c)+" = "+rl(d)+" not >= "+g));break;case Hj:0<gm(d,g)||(g=rl(g),U(a,b.name+zl("[",c)+" = "+rl(d)+" not > "+g));break;
case Ij:0==gm(d,g)&&(g=rl(g),U(a,b.name+zl("[",c)+" <> "+rl(d)+" not > "+g))}}f=1;for(e=b.qa;null!=e;e=e.e,f++)g=tl(null,sl(d)),vm(a,e.code,g)||U(a,b.name,zl("[",c)+" = "+rl(d)+" not in specified set; see ("+f+")")}function Qm(a,b,c){function d(d){Pm(a,b,c,d);e=Al(b.O,Il(c));e.value.Y=sl(d);return d}var e=yl(a,b.O,c);return null!=e?sl(e.value.Y):null!=b.assign?d(xm(a,b.assign)):null!=b.xa?d(xm(a,b.xa)):null!=b.Wc?sl(b.Wc):U(a,"no value for "+b.name+zl("[",c))}
function Rm(a,b){null!=b.ga?Pm(a,b.S,b.ga.w,b.ga.value.Y):b.value=Qm(a,b.S,b.w)}function Sm(a,b,c){var d={};d.S=b;d.w=c;if(1==b.data)for(c=b.O.Xa,b.data=2,d.ga=b.O.head;null!=d.ga&&(zm(a,b.domain,d.ga.w,d,Rm)&&Dm(a,b.name,d.ga.w),d.ga!=c);d.ga=d.ga.e);d.ga=null;zm(a,d.S.domain,d.w,d,Rm)&&Dm(a,b.name,d.w);return d.value}function Tm(a,b){var c=Em(b.domain);switch(b.type){case N:case mh:case ah:Om(a,b,c);break;case T:Sm(a,b,c)}return 0}
function Um(a,b){var c=b.t,d=b.w,e=yl(a,c.O,d);null!=e?d=e.value.t:(e=Al(c.O,Il(d)),d=e.value.t={},d.C=0,d.t=c,d.ga=e,d.P=null==c.P?0:$(a,c.P),d.W=null==c.W?0:c.W==c.P?d.P:$(a,c.W),d.ja=0,d.m=0,d.r=d.J=0);b.oe=d}function Vm(a,b,c){var d={};d.t=b;d.w=c;zm(a,d.t.domain,d.w,d,Um)&&Dm(a,b.name,d.w);return d.oe}
function Wm(a,b,c){var d=null,e=yl(a,b.O,c);if(null!=e)c=e.value.H;else{e=Al(b.O,Il(c));c=e.value.H={};c.ea=0;c.H=b;c.ga=e;c.form=Xm(a,b.code);if(null==b.P&&null==b.W)c.form=qm(a,c.form,function(a){d=a}),c.P=c.W=-d;else if(null!=b.P&&null==b.W)c.form=pm(a,1,c.form,-1,Xm(a,b.P)),c.form=qm(a,c.form,function(a){d=a}),c.P=-d,c.W=0;else if(null==b.P&&null!=b.W)c.form=pm(a,1,c.form,-1,Xm(a,b.W)),c.form=qm(a,c.form,function(a){d=a}),c.P=0,c.W=-d;else if(b.P==b.W)c.form=pm(a,1,c.form,-1,Xm(a,b.P)),c.form=
qm(a,c.form,function(a){d=a}),c.P=c.W=-d;else{var f=null,g=null;c.form=qm(a,c.form,function(a){d=a});qm(a,Xm(a,b.P),function(a){f=a});qm(a,Xm(a,b.W),function(a){g=a});c.P=Ml(a,f,d);c.W=Ml(a,g,d)}c.m=0;c.r=c.J=0}return c}function Ym(a,b){b.oe=Wm(a,b.H,b.w)}function Zm(a,b,c){var d={};d.H=b;d.w=c;zm(a,d.H.domain,d.w,d,Ym)&&Dm(a,b.name,d.w);return d.oe}function $m(a,b){var c=Em(b.domain);Zm(a,b,c);return 0}
function an(a,b){var c=$(a,b.code.a.loop.x);switch(b.code.Ta){case dk:b.value=Ll(a,b.value,c);break;case ek:b.value=Ol(a,b.value,c);break;case fk:b.value>c&&(b.value=c);break;case gk:b.value<c&&(b.value=c)}return 0}
function $(a,b){var c,d,e;b.T&&b.valid&&(b.valid=0,rm(b.type,b.value));if(b.valid)return b.value.Q;switch(b.Ta){case Fi:c=b.a.Q;break;case Ii:d=null;for(e=b.a.S.list;null!=e;e=e.e)d=tl(d,xm(a,e.x));c=Om(a,b.a.S.S,d);break;case Li:d=null;for(e=b.a.t.list;null!=e;e=e.e)d=tl(d,xm(a,e.x));e=Vm(a,b.a.t.t,d);switch(b.a.t.Ac){case Ai:c=null==e.t.P?-s:e.P;break;case Bi:c=null==e.t.W?+s:e.W;break;case Ci:c=e.m;break;case Di:c=e.r;break;case Ei:c=e.J}break;case Mi:d=null;for(e=b.a.H.list;null!=e;e=e.e)d=tl(d,
xm(a,e.x));e=Zm(a,b.a.H.H,d);switch(b.a.H.Ac){case Ai:c=null==e.H.P?-s:e.P;break;case Bi:c=null==e.H.W?+s:e.W;break;case Ci:c=e.m;break;case Di:c=e.r;break;case Ei:c=e.J}break;case Qi:c=bn(a.Gd);break;case Ri:c=dm(a.Gd)/2147483648;break;case Si:c=em(a);break;case Ti:c=Math.round(Date.now()/1E3);break;case Ui:e=xm(a,b.a.a.x);null==e.M?c=e.Q:vg(e.M,function(a){c=a})&&U(a,"cannot convert "+rl(e)+" to floating-point number");break;case Zi:c=+$(a,b.a.a.x);break;case $i:c=-$(a,b.a.a.x);break;case bj:c=
Math.abs($(a,b.a.a.x));break;case cj:c=Math.ceil($(a,b.a.a.x));break;case dj:c=Math.floor($(a,b.a.a.x));break;case ej:c=Tl(a,$(a,b.a.a.x));break;case fj:c=Ul(a,$(a,b.a.a.x));break;case gj:c=Vl(a,$(a,b.a.a.x));break;case hj:c=Wl(a,$(a,b.a.a.x));break;case ij:c=Xl(a,$(a,b.a.a.x));break;case jj:c=Yl(a,$(a,b.a.a.x));break;case kj:c=Zl($(a,b.a.a.x));break;case xj:c=$l($(a,b.a.a.x),$(a,b.a.a.y));break;case lj:c=am(a,$(a,b.a.a.x),0);break;case yj:c=am(a,$(a,b.a.a.x),$(a,b.a.a.y));break;case mj:c=bm(a,$(a,
b.a.a.x),0);break;case zj:c=bm(a,$(a,b.a.a.x),$(a,b.a.a.y));break;case pj:c=Ll(a,$(a,b.a.a.x),$(a,b.a.a.y));break;case qj:c=Ml(a,$(a,b.a.a.x),$(a,b.a.a.y));break;case rj:c=Nl(a,$(a,b.a.a.x),$(a,b.a.a.y));break;case sj:c=Ol(a,$(a,b.a.a.x),$(a,b.a.a.y));break;case tj:c=Pl(a,$(a,b.a.a.x),$(a,b.a.a.y));break;case uj:c=Ql(a,$(a,b.a.a.x),$(a,b.a.a.y));break;case vj:c=Rl($(a,b.a.a.x),$(a,b.a.a.y));break;case wj:c=Sl(a,$(a,b.a.a.x),$(a,b.a.a.y));break;case Aj:c=cm(a,$(a,b.a.a.x),$(a,b.a.a.y));break;case Bj:c=
fm(a,$(a,b.a.a.x),$(a,b.a.a.y));break;case nj:c=Bm(a,b.a.a.x).size;break;case oj:e=xm(a,b.a.a.x);d=null==e.M?String(e.Q):e.M;c=d.length;break;case Vj:e=xm(a,b.a.a.x);d=null==e.M?String(e.Q):e.M;e=xm(a,b.a.a.y);c=cn(a,d,null==e.M?String(e.Q):e.M);break;case Zj:c=ym(a,b.a.a.x)?$(a,b.a.a.y):null==b.a.a.z?0:$(a,b.a.a.z);break;case bk:c=+s;for(e=b.a.list;null!=e;e=e.e)d=$(a,e.x),c>d&&(c=d);break;case ck:c=-s;for(e=b.a.list;null!=e;e=e.e)d=$(a,e.x),c<d&&(c=d);break;case dk:e={};e.code=b;e.value=0;Cm(a,
b.a.loop.domain,e,an);c=e.value;break;case ek:e={};e.code=b;e.value=1;Cm(a,b.a.loop.domain,e,an);c=e.value;break;case fk:e={};e.code=b;e.value=+s;Cm(a,b.a.loop.domain,e,an);e.value==+s&&U(a,"min{} over empty set; result undefined");c=e.value;break;case gk:e={},e.code=b,e.value=-s,Cm(a,b.a.loop.domain,e,an),e.value==-s&&U(a,"max{} over empty set; result undefined"),c=e.value}b.valid=1;return b.value.Q=c}
function xm(a,b){var c;b.T&&b.valid&&(b.valid=0,rm(b.type,b.value));if(b.valid)return sl(b.value.Y);switch(b.Ta){case Gi:c=nl(b.a.M);break;case Hi:c=sl(b.a.index.ya.value);break;case Ji:var d;d=null;for(c=b.a.S.list;null!=c;c=c.e)d=tl(d,xm(a,c.x));c=Sm(a,b.a.S.S,d);break;case Vi:c=ml($(a,b.a.a.x));break;case Cj:d=xm(a,b.a.a.x);c=xm(a,b.a.a.y);c=nl((null==d.M?String(d.Q):d.M)+(null==c.M?String(c.Q):c.M));break;case Zj:c=ym(a,b.a.a.x)?xm(a,b.a.a.y):null==b.a.a.z?ml(0):xm(a,b.a.a.z);break;case Uj:case ak:var e;
c=xm(a,b.a.a.x);c=null==c.M?String(c.Q):c.M;b.Ta==Uj?(e=$(a,b.a.a.y),e!=Math.floor(e)&&U(a,"substr('...', "+e+"); non-integer second argument"),(1>e||e>c.length+1)&&U(a,"substr('...', "+e+"); substring out of range")):(e=$(a,b.a.a.y),d=$(a,b.a.a.z),e==Math.floor(e)&&d==Math.floor(d)||U(a,"substr('...', "+e+", "+d+"); non-integer second and/or third argument"),(1>e||0>d||e+d>c.length+1)&&U(a,"substr('...', "+e+", "+d+"); substring out of range"));c=nl(c.slice(e-1,e+d-1));break;case Xj:d=$(a,b.a.a.x),
c=xm(a,b.a.a.y),c=dn(a,d,null==c.M?String(c.Q):c.M),c=nl(c)}b.valid=1;b.value.Y=sl(c);return c}function en(a,b){var c=0;switch(b.code.Ta){case hk:b.value&=ym(a,b.code.a.loop.x);b.value||(c=1);break;case ik:b.value|=ym(a,b.code.a.loop.x),b.value&&(c=1)}return c}
function ym(a,b){var c,d;b.T&&b.valid&&(b.valid=0,rm(b.type,b.value));if(b.valid)return b.value.sg;switch(b.Ta){case Wi:c=0!=$(a,b.a.a.x);break;case aj:c=!ym(a,b.a.a.x);break;case Dj:b.a.a.x.type==N?c=$(a,b.a.a.x)<$(a,b.a.a.y):(c=xm(a,b.a.a.x),d=xm(a,b.a.a.y),c=0>gm(c,d));break;case Ej:b.a.a.x.type==N?c=$(a,b.a.a.x)<=$(a,b.a.a.y):(c=xm(a,b.a.a.x),d=xm(a,b.a.a.y),c=0>=gm(c,d));break;case Fj:b.a.a.x.type==N?c=$(a,b.a.a.x)==$(a,b.a.a.y):(c=xm(a,b.a.a.x),d=xm(a,b.a.a.y),c=0==gm(c,d));break;case Gj:b.a.a.x.type==
N?c=$(a,b.a.a.x)>=$(a,b.a.a.y):(c=xm(a,b.a.a.x),d=xm(a,b.a.a.y),c=0<=gm(c,d));break;case Hj:b.a.a.x.type==N?c=$(a,b.a.a.x)>$(a,b.a.a.y):(c=xm(a,b.a.a.x),d=xm(a,b.a.a.y),c=0<gm(c,d));break;case Ij:b.a.a.x.type==N?c=$(a,b.a.a.x)!=$(a,b.a.a.y):(c=xm(a,b.a.a.x),d=xm(a,b.a.a.y),c=0!=gm(c,d));break;case Jj:c=ym(a,b.a.a.x)&&ym(a,b.a.a.y);break;case Kj:c=ym(a,b.a.a.x)||ym(a,b.a.a.y);break;case Qj:c=fn(a,b.a.a.x);c=vm(a,b.a.a.y,c);break;case Rj:c=fn(a,b.a.a.x);c=!vm(a,b.a.a.y,c);break;case Sj:d=Bm(a,b.a.a.x);
c=1;for(d=d.head;null!=d;d=d.e)if(!vm(a,b.a.a.y,d.w)){c=0;break}break;case Tj:d=Bm(a,b.a.a.x);c=1;for(d=d.head;null!=d;d=d.e)if(vm(a,b.a.a.y,d.w)){c=0;break}break;case hk:c={};c.code=b;c.value=1;Cm(a,b.a.loop.domain,c,en);c=c.value;break;case ik:c={},c.code=b,c.value=0,Cm(a,b.a.loop.domain,c,en),c=c.value}b.valid=1;return b.value.sg=c}
function fn(a,b){var c;b.T&&b.valid&&(b.valid=0,rm(b.type,b.value));if(b.valid)return Il(b.value.w);switch(b.Ta){case Ni:c=null;for(var d=b.a.list;null!=d;d=d.e)c=tl(c,xm(a,d.x));break;case Xi:c=tl(null,xm(a,b.a.a.x))}b.valid=1;b.value.w=Il(c);return c}function gn(a,b){var c;switch(b.code.Ta){case jk:c=fn(a,b.code.a.loop.x);null==yl(a,b.value,c)&&jm(b.value,c);break;case kk:jm(b.value,Em(b.code.a.loop.domain))}return 0}
function Bm(a,b){var c,d;b.T&&b.valid&&(b.valid=0,rm(b.type,b.value));if(b.valid)return km(a,b.value.set);switch(b.Ta){case Ki:c=null;for(d=b.a.set.list;null!=d;d=d.e)c=tl(c,xm(a,d.x));c=km(a,Km(a,b.a.set.set,c));break;case Oi:c=Bl(a,qh,b.q);for(d=b.a.list;null!=d;d=d.e)ul(a,c,fn(a,d.x));break;case Lj:d=Bm(a,b.a.a.x);for(c=Bm(a,b.a.a.y).head;null!=c;c=c.e)null==yl(a,d,c.w)&&jm(d,Il(c.w));c=d;break;case Mj:var e=Bm(a,b.a.a.x);d=Bm(a,b.a.a.y);c=Bl(a,qh,e.q);for(e=e.head;null!=e;e=e.e)null==yl(a,d,e.w)&&
jm(c,Il(e.w));break;case Nj:d=Bm(a,b.a.a.x);c=Bm(a,b.a.a.y);for(var f=Bl(a,qh,d.q),e=d.head;null!=e;e=e.e)null==yl(a,c,e.w)&&jm(f,Il(e.w));for(e=c.head;null!=e;e=e.e)null==yl(a,d,e.w)&&jm(f,Il(e.w));c=f;break;case Oj:e=Bm(a,b.a.a.x);d=Bm(a,b.a.a.y);c=Bl(a,qh,e.q);for(e=e.head;null!=e;e=e.e)null!=yl(a,d,e.w)&&jm(c,Il(e.w));break;case Pj:e=Bm(a,b.a.a.x);d=Bm(a,b.a.a.y);var g,h;c=Bl(a,qh,e.q+d.q);for(e=e.head;null!=e;e=e.e)for(f=d.head;null!=f;f=f.e){g=Il(e.w);for(h=f.w;null!=h;h=h.e)g=tl(g,sl(h.Y));
jm(c,g)}break;case Yj:d=$(a,b.a.a.x);c=$(a,b.a.a.y);e=null==b.a.a.z?1:$(a,b.a.a.z);f=Bl(a,qh,1);g=lm(a,d,c,e);for(h=1;h<=g;h++)jm(f,tl(null,ml(mm(a,d,c,e,h))));c=f;break;case Zj:c=ym(a,b.a.a.x)?Bm(a,b.a.a.y):Bm(a,b.a.a.z);break;case jk:d={};d.code=b;d.value=Bl(a,qh,b.q);Cm(a,b.a.loop.domain,d,gn);c=d.value;break;case kk:d={},d.code=b,d.value=Bl(a,qh,b.q),Cm(a,b.a.loop.domain,d,gn),c=d.value}b.valid=1;b.value.set=km(a,c);return c}function hn(){}
function vm(a,b,c){var d,e,f;switch(b.Ta){case Ki:f=null;for(e=b.a.set.list;null!=e;e=e.e)f=tl(f,xm(a,e.x));b=Km(a,b.a.set.set,f);f=im(c,b.q);d=null!=yl(a,b,f);break;case Oi:d=0;f=im(c,b.q);for(e=b.a.list;null!=e&&!(c=fn(a,e.x),d=0==hm(f,c));e=e.e);break;case Lj:d=vm(a,b.a.a.x,c)||vm(a,b.a.a.y,c);break;case Mj:d=vm(a,b.a.a.x,c)&&!vm(a,b.a.a.y,c);break;case Nj:f=vm(a,b.a.a.x,c);a=vm(a,b.a.a.y,c);d=f&&!a||!f&&a;break;case Oj:d=vm(a,b.a.a.x,c)&&vm(a,b.a.a.y,c);break;case Pj:if(d=vm(a,b.a.a.x,c)){for(f=
1;f<=b.a.a.x.q;f++)c=c.e;d=vm(a,b.a.a.y,c)}break;case Yj:f=$(a,b.a.a.x);e=$(a,b.a.a.y);b=null==b.a.a.z?1:$(a,b.a.a.z);lm(a,f,e,b);if(null!=c.Y.M){d=0;break}c=c.Y.Q;if(0<b&&!(f<=c&&c<=e)||0>b&&!(e<=c&&c<=f)){d=0;break}d=mm(a,f,e,b,((c-f)/b+0.5|0)+1)==c;break;case Zj:d=ym(a,b.a.a.x)?vm(a,b.a.a.y,c):vm(a,b.a.a.z,c);break;case jk:U(a,"implementation restriction; in/within setof{} not allowed");break;case kk:f=im(c,b.q),d=0==zm(a,b.a.loop.domain,f,null,hn)}return d}
function jn(a,b){switch(b.code.Ta){case dk:var c;c=Xm(a,b.code.a.loop.x);for(null==b.value?b.value=c:b.Xa.e=c;null!=c;c=c.e)b.Xa=c}return 0}
function Xm(a,b){var c;b.T&&b.valid&&(b.valid=0,rm(b.type,b.value));if(b.valid)return om(b.value.form);switch(b.Ta){case Li:var d=null;for(c=b.a.t.list;null!=c;c=c.e)d=tl(d,xm(a,c.x));c=Vm(a,b.a.t.t,d);d={u:1};d.t=c;d.e=null;c=d;break;case Yi:c=nm($(a,b.a.a.x));break;case Zi:c=pm(a,0,nm(0),1,Xm(a,b.a.a.x));break;case $i:c=pm(a,0,nm(0),-1,Xm(a,b.a.a.x));break;case pj:c=pm(a,1,Xm(a,b.a.a.x),1,Xm(a,b.a.a.y));break;case qj:c=pm(a,1,Xm(a,b.a.a.x),-1,Xm(a,b.a.a.y));break;case sj:c=b.a.a.x.type==N?pm(a,
$(a,b.a.a.x),Xm(a,b.a.a.y),0,nm(0)):pm(a,$(a,b.a.a.y),Xm(a,b.a.a.x),0,nm(0));break;case tj:c=pm(a,Pl(a,1,$(a,b.a.a.y)),Xm(a,b.a.a.x),0,nm(0));break;case Zj:c=ym(a,b.a.a.x)?Xm(a,b.a.a.y):null==b.a.a.z?nm(0):Xm(a,b.a.a.z);break;case dk:c={};c.code=b;c.value=nm(0);c.Xa=null;Cm(a,b.a.loop.domain,c,jn);c=c.value;for(var e,f=0,d=c;null!=d;d=d.e)null==d.t?f=Ll(a,f,d.u):d.t.ja=Ll(a,d.t.ja,d.u);e=c;c=null;for(d=e;null!=d;d=e)e=d.e,null==d.t&&0!=f?(d.u=f,f=0,d.e=c,c=d):null!=d.t&&0!=d.t.ja&&(d.u=d.t.ja,d.t.ja=
0,d.e=c,c=d)}b.valid=1;b.value.form=om(c);return c}var kn=exports.mpl_tab_num_args=function(a){return a.ff},ln=exports.mpl_tab_get_arg=function(a,b){return a.a[b]};exports.mpl_tab_get_args=function(a){return a.a};
var mn=exports.mpl_tab_num_flds=function(a){return a.Wa},nn=exports.mpl_tab_get_name=function(a,b){return a.name[b]},on=exports.mpl_tab_get_type=function(a,b){return a.type[b]},pn=exports.mpl_tab_get_num=function(a,b){return a.Q[b]},qn=exports.mpl_tab_get_str=function(a,b){return a.M[b]},rn=exports.mpl_tab_set_num=function(a,b,c){a.type[b]="N";a.Q[b]=c},sn=exports.mpl_tab_set_str=function(a,b,c){a.type[b]="S";a.M[b]=c};
function tn(a,b){var c=a.Mc,d,e,f;f=0;for(d=b.v.Oc.list;null!=d;d=d.e)switch(f++,d.code.type){case N:c.type[f]="N";c.Q[f]=$(a,d.code);c.M[f][0]="\x00";break;case T:e=xm(a,d.code),null==e.M?(c.type[f]="N",c.Q[f]=e.Q,c.M[f][0]="\x00"):(c.type[f]="S",c.Q[f]=0,c.M[f]=e.M)}c=a.Mc;c.link.writeRecord(c)&&U(a,"error on writing data to table "+a.ib.v.nd.name);return 0}function un(a,b){ym(a,b.code)||U(a,"check"+zl("[",Em(b.domain))+" failed");return 0}
function vn(a,b,c){var d=c.value.set;wn(a,b.name+zl("[",c.w)+(null==d.head?" is empty":":"));for(b=d.head;null!=b;b=b.e)wn(a," "+zl("(",b.w))}function xn(a,b,c){switch(b.type){case N:case mh:case ah:wn(a,b.name+zl("[",c.w)+" = "+c.value.Q);break;case T:wn(a,b.name+zl("[",c.w)+" = "+rl(c.value.Y))}}
function yn(a,b,c,d){d==zi||d==Di?wn(a,b.name+zl("[",c.w)+".val = "+c.value.t.r):d==Ai?wn(a,b.name+zl("[",c.w)+".lb = "+(null==c.value.t.t.P?-s:c.value.t.P)):d==Bi?wn(a,b.name+zl("[",c.w)+".ub = "+(null==c.value.t.t.W?+s:c.value.t.W)):d==Ci?wn(a,b.name+zl("[",c.w)+".status = "+c.value.t.m):d==Ei&&wn(a,b.name+zl("[",c.w)+".dual = "+c.value.t.J)}
function zn(a,b,c,d){d==zi||d==Di?wn(a,b.name+zl("[",c.w)+".val = "+c.value.H.r):d==Ai?wn(a,b.name+zl("[",c.w)+".lb = "+(null==c.value.H.H.P?-s:c.value.H.P)):d==Bi?wn(a,b.name+zl("[",c.w)+".ub = "+(null==c.value.H.H.W?+s:c.value.H.W)):d==Ci?wn(a,b.name+zl("[",c.w)+".status = "+c.value.H.m):d==Ei&&wn(a,b.name+zl("[",c.w)+".dual = "+c.value.H.J)}
function An(a,b){for(var c,d=b.list;null!=d;d=d.e)if(d.type==kh)c=d.v.ya,wn(a,c.name+" = "+rl(c.value));else if(d.type==uh){var e=d.v.set;null!=e.assign?Cm(a,e.domain,e,Jm):(null!=e.Yc&&0==e.data&&Im(a,e),null!=e.O.head&&Km(a,e,e.O.head.w));null==e.O.head&&wn(a,e.name+" has empty content");for(c=e.O.head;null!=c;c=c.e)vn(a,e,c)}else if(d.type==sh)for(e=d.v.S,null!=e.assign?Cm(a,e.domain,e,Tm):null!=e.O.head&&(e.type!=T?Om(a,e,e.O.head.w):Sm(a,e,e.O.head.w)),null==e.O.head&&wn(a,e.name+" has empty content"),
c=e.O.head;null!=c;c=c.e)xn(a,e,c);else if(d.type==yh)for(e=d.v.t,null==e.O.head&&wn(a,e.name+" has empty content"),c=e.O.head;null!=c;c=c.e)yn(a,e,c,zi);else if(d.type==ch)for(e=d.v.H,null==e.O.head&&wn(a,e.name+" has empty content"),c=e.O.head;null!=c;c=c.e)zn(a,e,c,zi);else if(d.type==hh)if(e=d.v.code,e.Ta==Ii||e.Ta==Ji||e.Ta==Ki||e.Ta==Li||e.Ta==Mi){c=a;var f={value:{}},g=void 0;f.w=null;for(g=e.a.S.list||e.a.t.list;null!=g;g=g.e)f.w=tl(f.w,xm(c,g.x));switch(e.Ta){case Ii:f.value.Q=Om(c,e.a.S.S,
f.w);xn(c,e.a.S.S,f);break;case Ji:f.value.Y=Sm(c,e.a.S.S,f.w);xn(c,e.a.S.S,f);break;case Ki:f.value.set=Km(c,e.a.set.set,f.w);vn(c,e.a.set.set,f);break;case Li:f.value.t=Vm(c,e.a.t.t,f.w);yn(c,e.a.t.t,f,e.a.t.Ac);break;case Mi:f.value.H=Zm(c,e.a.H.H,f.w),zn(c,e.a.H.H,f,e.a.H.Ac)}}else switch(c=a,e.type){case N:e=$(c,e);wn(c,String(e));break;case T:e=xm(c,e);wn(c,rl(e));break;case nh:e=ym(c,e);wn(c,e?"true":"false");break;case xh:e=fn(c,e);wn(c,zl("(",e));break;case fh:e=Bm(c,e);0==e.head&&wn(c,"set is empty");
for(e=e.head;null!=e;e=e.e)wn(c," "+zl("(",e.w));break;case jh:for(f=void 0,e=Xm(c,e),null==e&&wn(c,"linear form is empty"),f=e;null!=f;f=f.e)null==f.t?wn(c," "+f.u):wn(c," "+f.u+" "+f.t.t.name+zl("[",f.t.ga.w))}return 0}function Bn(a,b){null==a.Hg?"\n"==b?(a.he(a.dd,a.le),a.dd=""):a.dd+=b:a.Hg(b)}function Cn(a,b){for(var c=0;c<b.length;c++)Bn(a,b[c])}
function Dn(a,b){var c,d,e,f,g,h=xm(a,b.zd);d=null==h.M?String(h.Q):h.M;c=b.list;for(f=0;f<d.length;f++)if("%"==d[f])if(e=f++,"%"==d[f])Bn(a,"%");else{if(null==c)break;for(;"-"==d[f]||"+"==d[f]||" "==d[f]||"#"==d[f]||"0"==d[f];)f++;for(;wa(d[f]);)f++;if("."==d[f])for(f++;wa(d[f]);)f++;if("d"==d[f]||"i"==d[f]||"e"==d[f]||"E"==d[f]||"f"==d[f]||"F"==d[f]||"g"==d[f]||"G"==d[f]){switch(c.code.type){case N:g=$(a,c.code);break;case T:h=xm(a,c.code);null!=h.M&&U(a,"cannot convert "+rl(h)+" to floating-point number");
g=h.Q;break;case nh:g=ym(a,c.code)?1:0}"d"==d[f]||"i"==d[f]?(-2147483647<=g&&2147483647>=g||U(a,"cannot convert "+g+" to integer"),Cn(a,xa(d.slice(e,f+1),Math.floor(g+0.5)|0))):Cn(a,xa(d.slice(e,f+1),g))}else if("s"==d[f]){switch(c.code.type){case N:g=String($(a,c.code));break;case nh:g=ym(a,c.code)?"T":"F";break;case T:h=xm(a,c.code),g=null==h.M?String(h.Q):h.M}Cn(a,xa(d.slice(e,f+1),g))}else U(a,"format specifier missing or invalid");c=c.e}else"\\"==d[f]?(f++,"t"==d[f]?Bn(a,"\t"):"n"==d[f]?Bn(a,
"\n"):"\x00"==d[f]?U(a,"invalid use of escape character \\ in format control string"):Bn(a,d[f])):Bn(a,d[f]);return 0}function En(a,b){for(var c=a.ib,d=b.list;null!=d;d=d.e)Fn(a,d);a.ib=c;return 0}
function Fn(a,b){a.ib=b;switch(b.type){case ch:x("Generating "+b.v.H.name+"...");var c=b.v.H;Cm(a,c.domain,c,$m);break;case wh:switch(b.v.nd.type){case lh:x("Reading "+b.v.nd.name+"...");break;case rh:x("Writing "+b.v.nd.name+"...")}var c=b.v.nd,d,e,f,g;a.Mc=f={};f.id=0;f.link=null;f.ff=0;f.a=null;f.Wa=0;f.name=null;f.type=null;f.Q=null;f.M=null;for(d=c.a;null!=d;d=d.e)f.ff++;f.a=Array(1+f.ff);for(g=1;g<=f.ff;g++)f.a[g]=null;g=0;for(d=c.a;null!=d;d=d.e)g++,e=xm(a,d.code),e=null==e.M?String(e.Q):e.M,
f.a[g]=e;switch(c.type){case lh:g=c.v.qa.set;null!=g&&(g.data&&U(a,g.name+" already provided with data"),Al(g.O,null).value.set=Bl(a,qh,g.X),g.data=1);for(e=c.v.qa.list;null!=e;e=e.e)e.S.data&&U(a,e.S.name+" already provided with data"),e.S.data=1;for(e=c.v.qa.We;null!=e;e=e.e)f.Wa++;for(e=c.v.qa.list;null!=e;e=e.e)f.Wa++;f.name=Array(1+f.Wa);f.type=Array(1+f.Wa);f.Q=new Float64Array(1+f.Wa);f.M=Array(1+f.Wa);g=0;for(e=c.v.qa.We;null!=e;e=e.e)g++,f.name[g]=e.name,f.type[g]="?",f.Q[g]=0,f.M[g]="";
for(e=c.v.qa.list;null!=e;e=e.e)g++,f.name[g]=e.name,f.type[g]="?",f.Q[g]=0,f.M[g]="";for(Gn(a,"R");;){for(g=1;g<=f.Wa;g++)f.type[g]="?";g=a;d=g.Mc;d=d.link.readRecord(d);0<d&&U(g,"error on reading data from table "+g.ib.v.nd.name);if(d)break;for(g=1;g<=f.Wa;g++)"?"==f.type[g]&&U(a,"field "+f.name[g]+" missing in input table");d=null;g=0;for(e=c.v.qa.We;null!=e;e=e.e)switch(g++,f.type[g]){case "N":d=tl(d,ml(f.Q[g]));break;case "S":d=tl(d,nl(f.M[g]))}null!=c.v.qa.set&&ul(a,c.v.qa.set.O.head.value.set,
Il(d));for(e=c.v.qa.list;null!=e;e=e.e){var h;g++;null!=yl(a,e.S.O,d)&&U(a,e.S.name+zl("[",d)+" already defined");h=Al(e.S.O,Il(d));switch(e.S.type){case N:case mh:case ah:"N"!=f.type[g]&&U(a,e.S.name+" requires numeric data");h.value.Q=f.Q[g];break;case T:switch(f.type[g]){case "N":h.value.Y=ml(f.Q[g]);break;case "S":h.value.Y=nl(f.M[g])}}}}a.Mc=null;break;case rh:for(d=c.v.Oc.list;null!=d;d=d.e)f.Wa++;f.name=Array(1+f.Wa);f.type=Array(1+f.Wa);f.Q=new Float64Array(1+f.Wa);f.M=Array(1+f.Wa);g=0;for(d=
c.v.Oc.list;null!=d;d=d.e)g++,f.name[g]=d.name,f.type[g]="?",f.Q[g]=0,f.M[g]="";Gn(a,"W");Cm(a,c.v.Oc.domain,c,tn);c=a.Mc;c.link.flush(c);a.Mc=null}break;case bh:x("Checking (line "+b.bb+")...");c=b.v.Rg;Cm(a,c.domain,c,un);break;case dh:wn(a,"Display statement at line "+b.bb);c=b.v.Sg;Cm(a,c.domain,c,An);break;case th:c=b.v.nh;null==c.Ea?a.le=null:(f=xm(a,c.Ea),a.le=null==f.M?f.Q:f.M);Cm(a,c.domain,c,Dn);break;case ih:c=b.v.Ug,Cm(a,c.domain,c,En)}}
function Hn(a){var b;for(b=a.uc;null!=b;b=b.e)switch(b.type){case uh:b.v.set.O=Bl(a,fh,b.v.set.q);break;case sh:switch(b.v.S.type){case N:case mh:case ah:b.v.S.O=Bl(a,N,b.v.S.q);break;case T:b.v.S.O=Bl(a,T,b.v.S.q)}break;case yh:b.v.t.O=Bl(a,gh,b.v.t.q);break;case ch:b.v.H.O=Bl(a,eh,b.v.H.q)}}function In(a,b,c){a.bb=0;a.Vc=0;a.l="\n";a.b=0;a.Bb=0;a.h="";a.value=0;a.Hf=Ah;a.Gf=0;a.Ff="";a.If=0;a.Te=0;a.Ue=0;a.Mf=0;a.Lf=0;a.Kf="";a.Nf=0;ha(a.Zb,0," ",zh);a.lc=0;a.cf=c;a.bf=b||"input";nk(a);Y(a)}
function Jn(a,b,c){null==c?a.he=function(a){x(a)}:(a.he=c,a.jh=b);a.dd=""}function wn(a,b){a.he(b,a.le)}function Kn(a){0<a.dd.length&&(a.he(a.dd,a.le),a.dd="")}
function U(a,b){var c;switch(a.D){case 1:case 2:c=Error(a.bf+":"+a.bb+": "+b);c.line=a.bb;c.column=a.Vc;for(var d;0<a.lc;)a.lc--,d=a.Zb[0],ga(a.Zb,0,a.Zb,1,zh-1),a.Zb[zh-1]=d;x("Context: "+a.bb+" > "+(" "==a.Zb[0]?"":"...")+a.Zb.join("").trim());break;case 3:d=null==a.ib?0:a.ib.bb;var e=null==a.ib?0:a.ib.Vc;c=Error(d+": "+b);c.line=d;c.column=e}a.D=4;throw c;}
function ok(a,b){switch(a.D){case 1:case 2:x(a.bf+":"+a.bb+": warning: "+b);break;case 3:x(a.Yf+":"+(null==a.ib?0:a.ib.bb)+": warning: "+b)}}
var Ld=exports.mpl_initialize=function(){var a={bb:0,Vc:0,l:0,b:0,Bb:0,h:"",value:0,Hf:0,Gf:0,Ff:"",If:0,Te:0,Ue:0,Mf:0,Lf:0,Kf:"",Nf:0};a.Zb=Array(zh);ha(a.Zb,0," ",zh);a.lc=0;a.nc=0;a.V={};a.uc=null;a.Pf=0;a.rg=0;a.qg=0;a.Ke=0;a.Ob=0;a.pg=null;a.Ah="";a.Bh="";a.Gd=sg();a.Of=0;a.ib=null;a.Mc=null;a.g=0;a.i=0;a.n=null;a.f=null;a.cf=null;a.bf=null;a.he=null;a.jh=null;a.Hg=null;a.le=null;a.D=0;a.Yf=null;a.xh="";return a},Nd=exports.mpl_read_model=function(a,b,c,d){function e(){x(a.bb+" line"+(1==a.bb?
"":"s")+" were read");a.cf=null;return a.D}0!=a.D&&w("mpl_read_model: invalid call sequence");null==c&&w("mpl_read_model: no input specified");a.D=1;x("Reading model section from "+b+" ...");In(a,b,c);fl(a);null==a.uc&&U(a,"empty model section not allowed");a.Yf=a.bf;Hn(a);if(rk(a,"data")){if(d)return ok(a,"data section ignored"),e();a.nc=1;Y(a);a.b!=ni&&U(a,"semicolon missing where expected");Y(a);a.D=2;x("Reading data section from "+b+" ...");Kl(a)}cl(a);return e()},Pd=exports.mpl_read_data=function(a,
b,c){1!=a.D&&2!=a.D&&w("mpl_read_data: invalid call sequence");null==c&&w("mpl_read_data: no input specified");a.D=2;x("Reading data section from "+b+" ...");a.nc=1;In(a,b,c);dl(a,"data")&&(Y(a),a.b!=ni&&U(a,"semicolon missing where expected"),Y(a));Kl(a);cl(a);x(a.bb+" line"+(1==a.bb?"":"s")+" were read");a.cf=null;return a.D},Rd=exports.mpl_generate=function(a,b,c,d){1!=a.D&&2!=a.D&&w("mpl_generate: invalid call sequence");a.D=3;a.ve=d;Jn(a,b,c);for(b=a.uc;null!=b&&(Fn(a,b),a.ib.type!=vh);b=b.e);
a.ib=b;Kn(a);for(b=a.uc;null!=b;b=b.e)if(b.type==yh)for(c=b.v.t,c=c.O.head;null!=c;c=c.e);for(b=a.uc;null!=b;b=b.e)if(b.type==ch)for(c=b.v.H,c=c.O.head;null!=c;c=c.e)for(c.value.H.ea=++a.g,d=c.value.H.form;null!=d;d=d.e)d.t.ga.value.t.C=-1;for(b=a.uc;null!=b;b=b.e)if(b.type==yh)for(c=b.v.t,c=c.O.head;null!=c;c=c.e)0!=c.value.t.C&&(c.value.t.C=++a.i);a.n=Array(1+a.g);for(d=1;d<=a.g;d++)a.n[d]=null;for(b=a.uc;null!=b;b=b.e)if(b.type==ch)for(c=b.v.H,c=c.O.head;null!=c;c=c.e)d=c.value.H.ea,a.n[d]=c.value.H;
for(d=1;d<=a.g;d++);a.f=Array(1+a.i);for(d=1;d<=a.i;d++)a.f[d]=null;for(b=a.uc;null!=b;b=b.e)if(b.type==yh)for(c=b.v.t,c=c.O.head;null!=c;c=c.e)d=c.value.t.C,0!=d&&(a.f[d]=c.value.t);for(d=1;d<=a.i;d++);x("Model has been successfully generated");return a.D},Sd=exports.mpl_get_prob_name=function(a){return a.Yf},Td=exports.mpl_get_num_rows=function(a){3!=a.D&&w("mpl_get_num_rows: invalid call sequence");return a.g},be=exports.mpl_get_num_cols=function(a){3!=a.D&&w("mpl_get_num_cols: invalid call sequence");
return a.i},Ud=exports.mpl_get_row_name=function(a,b){3!=a.D&&w("mpl_get_row_name: invalid call sequence");1<=b&&b<=a.g||w("mpl_get_row_name: i = "+b+"; row number out of range");var c=a.n[b].H.name,c=c+zl("[",a.n[b].ga.w).slice(0,255);255==c.length&&(c=c.slice(0,252)+"...");return c},ie=exports.mpl_get_row_kind=function(a,b){var c;3!=a.D&&w("mpl_get_row_kind: invalid call sequence");1<=b&&b<=a.g||w("mpl_get_row_kind: i = "+b+"; row number out of range");switch(a.n[b].H.type){case ch:c=411;break;
case ph:c=je;break;case oh:c=ke}return c},Vd=exports.mpl_get_row_bnds=function(a,b,c){var d;3!=a.D&&w("mpl_get_row_bnds: invalid call sequence");1<=b&&b<=a.g||w("mpl_get_row_bnds: i = "+b+"; row number out of range");d=a.n[b];a=null==d.H.P?-s:d.P;b=null==d.H.W?+s:d.W;a==-s&&b==+s?(d=Wd,a=b=0):b==+s?(d=Xd,b=0):a==-s?(d=Yd,a=0):d=d.H.P!=d.H.W?Zd:$d;c(a,b);return d},he=exports.mpl_get_mat_row=function(a,b,c,d){var e=0;3!=a.D&&w("mpl_get_mat_row: invalid call sequence");1<=b&&b<=a.g||w("mpl_get_mat_row: i = "+
b+"; row number out of range");for(a=a.n[b].form;null!=a;a=a.e)e++,null!=c&&(c[e]=a.t.C),null!=d&&(d[e]=a.u);return e},ae=exports.mpl_get_row_c0=function(a,b){var c;3!=a.D&&w("mpl_get_row_c0: invalid call sequence");1<=b&&b<=a.g||w("mpl_get_row_c0: i = "+b+"; row number out of range");c=a.n[b];return null==c.H.P&&null==c.H.W?-c.P:0},ce=exports.mpl_get_col_name=function(a,b){3!=a.D&&w("mpl_get_col_name: invalid call sequence");1<=b&&b<=a.i||w("mpl_get_col_name: j = "+b+"; column number out of range");
var c=a.f[b].t.name,c=c+zl("[",a.f[b].ga.w);255==c.length&&(c=c.slice(0,252)+"...");return c},de=exports.mpl_get_col_kind=function(a,b){var c;3!=a.D&&w("mpl_get_col_kind: invalid call sequence");1<=b&&b<=a.i||w("mpl_get_col_kind: j = "+b+"; column number out of range");switch(a.f[b].t.type){case N:c=421;break;case mh:c=ee;break;case ah:c=fe}return c},ge=exports.mpl_get_col_bnds=function(a,b,c){var d;3!=a.D&&w("mpl_get_col_bnds: invalid call sequence");1<=b&&b<=a.i||w("mpl_get_col_bnds: j = "+b+"; column number out of range");
d=a.f[b];a=null==d.t.P?-s:d.P;b=null==d.t.W?+s:d.W;a==-s&&b==+s?(d=Wd,a=b=0):b==+s?(d=Xd,b=0):a==-s?(d=Yd,a=0):d=d.t.P!=d.t.W?Zd:$d;c(a,b);return d},me=exports.mpl_has_solve_stmt=function(a){3!=a.D&&w("mpl_has_solve_stmt: invalid call sequence");return a.Ob},ne=exports.mpl_put_row_soln=function(a,b,c,d,e){a.n[b].m=c;a.n[b].r=d;a.n[b].J=e},oe=exports.mpl_put_col_soln=function(a,b,c,d,e){a.f[b].m=c;a.f[b].r=d;a.f[b].J=e},pe=exports.mpl_postsolve=function(a){(3!=a.D||a.Of)&&w("mpl_postsolve: invalid call sequence");
var b;a.Of=1;for(b=a.ib;null!=b;b=b.e)Fn(a,b);a.ib=null;Kn(a);x("Model has been successfully processed");return a.D},Ln="Monday Tuesday Wednesday Thursday Friday Saturday Sunday".split(" "),Mn="January February March April May June July August September October November December".split(" ");function Nn(a){for(var b="";0<a;)b+="^",a--;return b}function On(a,b,c,d,e,f){x("Input string passed to str2time:");x(b);x(Nn(c+1));x("Format string passed to str2time:\n");x(d);x(Nn(e+1));U(a,f)}
function cn(a,b,c){function d(){On(a,b,n,c,t,"time zone offset value incomplete or invalid")}function e(){On(a,b,n,c,t,"time zone offset value out of range")}function f(){b[n]!=c[t]&&On(a,b,n,c,t,"character mismatch");n++}var g,h,k,l,p,m,q,r,n,t;h=k=l=p=m=q=-1;r=2147483647;for(t=n=0;t<c.length;t++)if("%"==c[t])if(t++,"b"==c[t]||"h"==c[t]){var y;for(0<=k&&On(a,b,n,c,t,"month multiply specified");" "==b[n];)n++;for(k=1;12>=k;k++){y=Mn[k-1];var E=!1;for(g=0;2>=g;g++)if(n[g].toUpperCase()!=y[g].toUpperCase()){E=
!0;break}if(!E){n+=3;for(g=3;"\x00"!=y[g]&&b[n].toUpperCase()==y[g].toUpperCase();g++)n++;break}}12<k&&On(a,b,n,c,t,"abbreviated month name missing or invalid")}else if("d"==c[t]){for(0<=l&&On(a,b,n,c,t,"day multiply specified");" "==b[n];)n++;"0"<=b[n]&&"9">=b[n]||On(a,b,n,c,t,"day missing or invalid");l=b[n++]-0;"0"<=b[n]&&"9">=b[n]&&(l=10*l+(b[n++]-0));1<=l&&31>=l||On(a,b,n,c,t,"day out of range")}else if("H"==c[t]){for(0<=p&&On(a,b,n,c,t,"hour multiply specified");" "==b[n];)n++;"0"<=b[n]&&"9">=
b[n]||On(a,b,n,c,t,"hour missing or invalid");p=b[n++]-0;"0"<=b[n]&&"9">=b[n]&&(p=10*p+(b[n++]-0));0<=p&&23>=p||On(a,b,n,c,t,"hour out of range")}else if("m"==c[t]){for(0<=k&&On(a,b,n,c,t,"month multiply specified");" "==b[n];)n++;"0"<=b[n]&&"9">=b[n]||On(a,b,n,c,t,"month missing or invalid");k=b[n++]-0;"0"<=b[n]&&"9">=b[n]&&(k=10*k+(b[n++]-0));1<=k&&12>=k||On(a,b,n,c,t,"month out of range")}else if("M"==c[t]){for(0<=m&&On(a,b,n,c,t,"minute multiply specified");" "==b[n];)n++;"0"<=b[n]&&"9">=b[n]||
On(a,b,n,c,t,"minute missing or invalid");m=b[n++]-0;"0"<=b[n]&&"9">=b[n]&&(m=10*m+(b[n++]-0));0<=m&&59>=m||On(a,b,n,c,t,"minute out of range")}else if("S"==c[t]){for(0<=q&&On(a,b,n,c,t,"second multiply specified");" "==b[n];)n++;"0"<=b[n]&&"9">=b[n]||On(a,b,n,c,t,"second missing or invalid");q=b[n++]-0;"0"<=b[n]&&"9">=b[n]&&(q=10*q+(b[n++]-0));0<=q&&60>=q||On(a,b,n,c,t,"second out of range")}else if("y"==c[t]){for(0<=h&&On(a,b,n,c,t,"year multiply specified");" "==b[n];)n++;"0"<=b[n]&&"9">=b[n]||
On(a,b,n,c,t,"year missing or invalid");h=b[n++]-0;"0"<=b[n]&&"9">=b[n]&&(h=10*h+(b[n++]-0));h+=69<=h?1900:2E3}else if("Y"==c[t]){for(0<=h&&On(a,b,n,c,t,"year multiply specified");" "==b[n];)n++;"0"<=b[n]&&"9">=b[n]||On(a,b,n,c,t,"year missing or invalid");h=0;for(g=1;4>=g&&"0"<=b[n]&&"9">=b[n];g++)h=10*h+(b[n++]-0);1<=h&&4E3>=h||On(a,b,n,c,t,"year out of range")}else if("z"==c[t]){var C;for(2147483647!=r&&On(a,b,n,c,t,"time zone offset multiply specified");" "==b[n];)n++;if("Z"==b[n])C=p=m=0,n++;
else{"+"==b[n]?(C=1,n++):"-"==b[n]?(C=-1,n++):On(a,b,n,c,t,"time zone offset sign missing");p=0;for(g=1;2>=g;g++)"0"<=b[n]&&"9">=b[n]||d(),p=10*p+(b[n++]-0);23<p&&e();":"==b[n]&&(n++,"0"<=b[n]&&"9">=b[n]||d());m=0;if("0"<=b[n]&&"9">=b[n]){for(g=1;2>=g;g++)"0"<=b[n]&&"9">=b[n]||d(),m=10*m+(b[n++]-0);59<m&&e()}}r=C*(60*p+m)}else"%"==c[t]?f():On(a,b,n,c,t,"invalid conversion specifier");else" "!=c[t]&&f();0>h&&(h=1970);0>k&&(k=1);0>l&&(l=1);0>p&&(p=0);0>m&&(m=0);0>q&&(q=0);2147483647==r&&(r=0);g=xg(l,
k,h);return 60*(60*(24*(g-xg(1,1,1970))+p)+m)+q-60*r}function Pn(a,b,c){x("Format string passed to time2str:");x(b);x(Nn(c));U(a,"invalid conversion specifier")}function Qn(a){return(a+xg(1,1,1970))%7+1}function Rn(a){a=xg(1,1,a)-xg(1,1,1970);switch(Qn(a)){case 1:a+=0;break;case 2:a-=1;break;case 3:a-=2;break;case 4:a-=3;break;case 5:a+=3;break;case 6:a+=2;break;case 7:a+=1}Qn(a);return a}
function dn(a,b,c){var d,e=0,f=0,g=0,h,k,l,p="",m;-62135596800<=b&&64092211199>=b||U(a,"time2str("+b+",...); argument out of range");b=Math.floor(b+0.5);h=Math.abs(b)/86400;d=Math.floor(h);0>b&&(d=h==Math.floor(h)?-d:-(d+1));yg(d+xg(1,1,1970),function(a,b,c){g=a;f=b;e=c});k=b-86400*d|0;h=k/60;k%=60;b=h/60;h%=60;for(l=0;l<c.length;l++)"%"==c[l]?(l++,"a"==c[l]?m=Ln[Qn(d)-1].slice(0,3):"A"==c[l]?m=Ln[Qn(d)-1]:"b"==c[l]||"h"==c[l]?m=Mn[f-1].slice(0,3):"B"==c[l]?m=Mn[f-1]:"C"==c[l]?m=String(Math.floor(e/
100)):"d"==c[l]?m=String(g):"D"==c[l]?m=f+"/"+g+"/"+e%100:"e"==c[l]?m=String(g):"F"==c[l]?xa(m,e+"-"+f+"-"+g):"g"==c[l]?(m=d<Rn(e)?e-1:d<Rn(e+1)?e:e+1,m=String(m%100)):"G"==c[l]?(m=d<Rn(e)?e-1:d<Rn(e+1)?e:e+1,m=String(m)):"H"==c[l]?m=String(b):"I"==c[l]?m=String(0==b?12:12>=b?b:b-12):"j"==c[l]?m=String(xg(g,f,e)-xg(1,1,e)+1):"k"==c[l]?m=String(b):"l"==c[l]?m=String(0==b?12:12>=b?b:b-12):"m"==c[l]?m=String(f):"M"==c[l]?m=String(h):"p"==c[l]?m=11>=b?"AM":"PM":"P"==c[l]?m=11>=b?"am":"pm":"r"==c[l]?m=
(0==b?12:12>=b?b:b-12)+":"+h+":"+k+" "+(11>=b?"AM":"PM"):"R"==c[l]?m=b+":"+h:"S"==c[l]?m=String(k):"T"==c[l]?m=b+":"+h+":"+k:"u"==c[l]?m=String(Qn(d)):"U"==c[l]?(m=xg(1,1,e)-xg(1,1,1970),m+=7-Qn(m),m=String((d+7-m)/7)):"V"==c[l]?(m=d<Rn(e)?d-Rn(e-1):d<Rn(e+1)?d-Rn(e):d-Rn(e+1),m=String(m/7+1)):"w"==c[l]?m=String(Qn(d)%7):"W"==c[l]?(m=xg(1,1,e)-xg(1,1,1970),m+=(8-Qn(m))%7,m=String((d+7-m)/7)):"y"==c[l]?m=String(e%100):"Y"==c[l]?m=String(e):"%"==c[l]?m="%":Pn(a,c,l)):m=c[l],p+=m;return p}var Sn={};
function Gn(a,b){var c=a.Mc,d=Sn[c.a[1].toLowerCase()];d?c.link=new d(c,b,a.ve):U(a,"Invalid table driver '"+c.a[1]+"'");null==c.link&&U(a,"error on opening table "+a.ib.v.nd.name)}var Tn=exports.mpl_tab_drv_register=function(a,b){Sn[a.toLowerCase()]=b};
function Un(a,b,c){this.mode=b;this.Ea=null;this.count=0;this.l="\n";this.Hb=0;this.pb="";this.Wa=0;this.Oa=[];this.ve=c;this.ng=0;this.Ae=1;this.og=2;this.Be=3;2>kn(a)&&w("csv_driver: file name not specified\n");this.Ea=ln(a,2);if("R"==b){c?(this.data=c(a.a,b),this.cursor=0):w("csv_driver: unable to open "+this.Ea);this.Eg=0;for(Vn(this);;){Vn(this);if(this.Hb==this.Ae)break;this.Hb!=this.Be&&w(this.Ea+":"+this.count+": invalid field name\n");this.Wa++;for(b=mn(a);1<=b&&nn(a,b)!=this.pb;b--);this.Oa[this.Wa]=
b}for(b=mn(a);1<=b&&"RECNO"!=nn(a,b);b--);this.Oa[0]=b}else if("W"==b){this.data="";c=mn(a);for(b=1;b<=c;b++)this.data+=nn(a,b)+(b<c?",":"\n");this.count++}}
function Vn(a){if(-1==a.l)a.Hb=a.ng,a.pb="EOF";else if("\n"==a.l){if(a.Hb=a.Ae,a.pb="EOR",Wn(a),","==a.l&&w(a.Ea+":"+a.count+": empty field not allowed\n"),"\n"==a.l&&w(a.Ea+":"+a.count+": empty record not allowed\n"),"#"==a.l&&1==a.count)for(;"#"==a.l;){for(;"\n"!=a.l;)Wn(a);Wn(a);a.Eg++}}else if(","==a.l&&Wn(a),"'"==a.l||'"'==a.l){var b=a.l;a.pb="";a.Hb=a.Be;for(Wn(a);;){if(a.l==b&&(Wn(a),a.l!=b))if(","==a.l||"\n"==a.l)break;else w(a.Ea+":"+a.count+": invalid field");a.pb+=a.l;Wn(a)}0==a.pb.length&&
w(a.Ea+":"+a.count+": empty field not allowed")}else{a.pb="";for(a.Hb=a.og;","!=a.l&&"\n"!=a.l;)"'"!=a.l&&'"'!=a.l||w(a.Ea+":"+a.count+": invalid use of single or double quote within field"),a.pb+=a.l,Wn(a);0==a.pb.length&&w(a.Ea+":"+a.count+": empty field not allowed");vg(a.pb,function(){})&&(a.Hb=a.Be)}}function Wn(a){var b;for("\n"==a.l&&a.count++;;)if(b=a.cursor<a.data.length?a.data[a.cursor++]:-1,"\r"!=b){"\n"!=b&&ta(b)&&w(a.Ea+":"+a.count+": invalid control character "+b);break}a.l=b}
Un.prototype.readRecord=function(a){var b;0<this.Oa[0]&&rn(a,this.Oa[0],this.count-this.Eg-1);for(b=1;b<=this.Wa;b++){Vn(this);if(this.Hb==this.ng)return-1;if(this.Hb==this.Ae){var c=this.Wa-b+1;1==c?w(this.Ea+":"+this.count+": one field missing"):w(this.Ea+":"+this.count+": "+c+" fields missing")}else if(this.Hb==this.og){if(0<this.Oa[b]){var d=0;vg(this.pb,function(a){d=a});rn(a,this.Oa[b],d)}}else this.Hb==this.Be&&0<this.Oa[b]&&sn(a,this.Oa[b],this.pb)}Vn(this);this.Hb!=this.Ae&&w(this.Ea+":"+
this.count+": too many fields");return 0};Un.prototype.writeRecord=function(a){var b,c,d,e;c=mn(a);for(b=1;b<=c;b++){switch(on(a,b)){case "N":this.data+=pn(a,b);break;case "S":this.data+='"';d=qn(a,b);for(e=0;d.length>e;e++)this.data='"'==d[e]?this.data+'""':this.data+d[e];this.data+='"'}this.data+=b<c?",":"\n"}this.count++;return 0};Un.prototype.flush=function(a){this.ve(a.a,this.mode,this.data)};Tn("CSV",Un);
function Xn(a,b,c){this.mode=b;this.Ea=null;2>kn(a)&&w("json driver: file name not specified");this.Ea=ln(a,2);if("R"==b)for(this.Oa={},c?(this.data=c(a.a,b),"string"==typeof this.data&&(this.data=JSON.parse(this.data)),this.cursor=1):w("json driver: unable to open "+this.Ea),a=0,b=this.data[0];a<b.length;a++)this.Oa[b[a]]=a;else if("W"==b){this.ve=c;c=[];this.data=[c];var d=mn(a);for(b=1;b<=d;b++)c.push(nn(a,b))}}
Xn.prototype.writeRecord=function(a){var b,c=mn(a),d=[];for(b=1;b<=c;b++)switch(on(a,b)){case "N":d.push(pn(a,b));break;case "S":d.push(qn(a,b))}this.data.push(d);return 0};Xn.prototype.readRecord=function(a){var b=this.data[this.cursor++];if(null==b)return-1;for(var c=1;c<=mn(a);c++){var d=this.Oa[nn(a,c)];if(null!=d)switch(d=b[d],typeof d){case "number":rn(a,c,d);break;case "boolean":rn(a,c,Number(d));break;case "string":sn(a,c,d);break;default:w("Unexpected data type "+d+" in "+this.Ea)}}return 0};
Xn.prototype.flush=function(a){this.ve(a.a,this.mode,this.data)};Tn("JSON",Xn);function Xb(){var a={$b:0};a.wc=a.gh=a.hh=0;a.name=a.eb=null;a.ha=0;a.ee=a.de=0;a.Db=a.Pc=null;a.Kb=a.td=null;a.top=null;a.g=a.i=a.L=0;a.uf=a.Sd=null;a.da=a.ue=0;a.nf=a.xg=a.Kg=a.zg=0;a.la=null;a.Aa=null;a.ka=null;a.Pa=null;return a}function Yn(a,b,c){0==c?(b.ca=null,b.e=a.Db,null==b.e?a.Pc=b:b.e.ca=b,a.Db=b):(b.ca=a.Pc,b.e=null,null==b.ca?a.Db=b:b.ca.e=b,a.Pc=b)}
function Zn(a,b){null==b.ca?a.Db=b.e:b.ca.e=b.e;null==b.e?a.Pc=b.ca:b.e.ca=b.ca}function $n(a,b){b.ja||(b.ja=1,Zn(a,b),Yn(a,b,0))}function ao(a,b,c){0==c?(b.ca=null,b.e=a.Kb,null==b.e?a.td=b:b.e.ca=b,a.Kb=b):(b.ca=a.td,b.e=null,null==b.ca?a.Kb=b:b.ca.e=b,a.td=b)}function bo(a,b){null==b.ca?a.Kb=b.e:b.ca.e=b.e;null==b.e?a.td=b.ca:b.e.ca=b.ca}function co(a,b){b.ja||(b.ja=1,bo(a,b),ao(a,b,0))}function eo(a){var b={};b.ea=++a.ee;b.name=null;b.c=-s;b.d=+s;b.k=null;b.ja=0;Yn(a,b,1);return b}
function fo(a){var b={};b.C=++a.de;b.name=null;b.Ra=0;b.c=b.d=b.u=0;b.k=null;b.ja=0;b.qb={};b.ub={};ao(a,b,1);return b}function go(a,b,c){var d={};d.n=a;d.f=b;d.j=c;d.ua=null;d.B=a.k;d.ra=null;d.I=b.k;null!=d.B&&(d.B.ua=d);null!=d.I&&(d.I.ra=d);a.k=b.k=d}function ho(a,b){var c;c={};c.Zd=b;c.info={};c.link=a.top;a.top=c;return c.info}function io(a){for(var b;null!=a.k;)b=a.k,a.k=b.B,null==b.ra?b.f.k=b.I:b.ra.I=b.I,null!=b.I&&(b.I.ra=b.ra)}function jo(a,b){io(b);Zn(a,b)}
function ko(a,b){for(var c;null!=b.k;)c=b.k,b.k=c.I,null==c.ua?c.n.k=c.B:c.ua.B=c.B,null!=c.B&&(c.B.ua=c.ua);bo(a,b)}
function Yb(a,b,c){var d=cb,e=cb,f=b.g,g=b.i,h,k,l;a.$b=b.dir;a.$b==za?l=1:a.$b==Ea&&(l=-1);a.wc=f;a.gh=g;a.hh=b.L;d&&null!=b.name&&(a.name=b.name);d&&null!=b.eb&&(a.eb=b.eb);a.ha=l*b.ha;h=Array(1+f);for(k=1;k<=f;k++){var p=b.n[k],m;h[k]=m=eo(a);d&&null!=p.name&&(m.name=p.name);if(e){var q=p.ma;p.type==Ka?(m.c=-s,m.d=+s):p.type==Sa?(m.c=p.c*q,m.d=+s):p.type==Ta?(m.c=-s,m.d=p.d*q):p.type==I?(m.c=p.c*q,m.d=p.d*q):p.type==B&&(m.c=m.d=p.c*q)}else p.type==Ka?(m.c=-s,m.d=+s):p.type==Sa?(m.c=p.c,m.d=+s):
p.type==Ta?(m.c=-s,m.d=p.d):p.type==I?(m.c=p.c,m.d=p.d):p.type==B&&(m.c=m.d=p.c)}for(f=1;f<=g;f++)if(m=b.f[f],k=fo(a),d&&null!=m.name&&(k.name=m.name),c==Sc&&(k.Ra=Number(m.kind==Fc)),e)for(p=m.va,m.type==Ka?(k.c=-s,k.d=+s):m.type==Sa?(k.c=m.c/p,k.d=+s):m.type==Ta?(k.c=-s,k.d=m.d/p):m.type==I?(k.c=m.c/p,k.d=m.d/p):m.type==B&&(k.c=k.d=m.c/p),k.u=l*m.u*p,m=m.k;null!=m;m=m.I)go(h[m.n.ea],k,m.n.ma*m.j*p);else for(m.type==Ka?(k.c=-s,k.d=+s):m.type==Sa?(k.c=m.c,k.d=+s):m.type==Ta?(k.c=-s,k.d=m.d):m.type==
I?(k.c=m.c,k.d=m.d):m.type==B&&(k.c=k.d=m.c),k.u=l*m.u,m=m.k;null!=m;m=m.I)go(h[m.n.ea],k,m.j);a.da=c;a.ue=e}
function cc(a,b){var c,d,e,f,g,h,k;db(b);Ca(b,a.name);Da(b,a.eb);Fa(b,a.$b);a.$b==za?h=1:a.$b==Ea&&(h=-1);Xa(b,0,h*a.ha);for(c=a.Db;null!=c;c=c.e)c.ja=e=La(b,1),Pa(b,e,c.name),d=c.c==-s&&c.d==+s?Ka:c.d==+s?Sa:c.c==-s?Ta:c.c!=c.d?I:B,Va(b,e,d,c.c,c.d);g=new Int32Array(1+b.g);k=new Float64Array(1+b.g);for(c=a.Kb;null!=c;c=c.e){e=Oa(b,1);Qa(b,e,c.name);Hc(b,e,c.Ra?Fc:Ma);d=c.c==-s&&c.d==+s?Ka:c.d==+s?Sa:c.c==-s?Ta:c.c!=c.d?I:B;Wa(b,e,d,c.c,c.d);Xa(b,e,h*c.u);f=0;for(d=c.k;null!=d;d=d.I)f++,g[f]=d.n.ja,
k[f]=d.j;Za(b,e,f,g,k)}a.g=b.g;a.i=b.i;a.L=b.L;a.uf=new Int32Array(1+a.g);a.Sd=new Int32Array(1+a.i);c=a.Db;for(e=0;null!=c;c=c.e)a.uf[++e]=c.ea;c=a.Kb;for(e=0;null!=c;c=c.e)a.Sd[++e]=c.C;a.name=a.eb=null;a.ha=0;a.Db=a.Pc=null;a.Kb=a.td=null}
function Ub(a,b){var c,d,e,f;a.$b==za?d=1:a.$b==Ea&&(d=-1);a.da==Zb?(a.nf=b.na,a.xg=b.sa):a.da==le?a.Kg=b.df:a.da==Sc&&(a.zg=b.za);if(a.da==Zb){null==a.la&&(a.la=new Int8Array(1+a.ee));for(f=1;f<=a.ee;f++)a.la[f]=0;null==a.ka&&(a.ka=new Int8Array(1+a.de));for(c=1;c<=a.de;c++)a.ka[c]=0}null==a.Pa&&(a.Pa=new Float64Array(1+a.de));for(c=1;c<=a.de;c++)a.Pa[c]=s;if(a.da!=Sc)for(null==a.Aa&&(a.Aa=new Float64Array(1+a.ee)),f=1;f<=a.ee;f++)a.Aa[f]=s;if(a.da==Zb){for(f=1;f<=a.g;f++)c=b.n[f],e=a.uf[f],a.la[e]=
c.m,a.Aa[e]=d*c.J;for(c=1;c<=a.i;c++)d=b.f[c],e=a.Sd[c],a.ka[e]=d.m,a.Pa[e]=d.r}else if(a.da==le){for(f=1;f<=a.g;f++)c=b.n[f],e=a.uf[f],a.Aa[e]=d*c.mc;for(c=1;c<=a.i;c++)d=b.f[c],e=a.Sd[c],a.Pa[e]=d.dc}else if(a.da==Sc)for(c=1;c<=a.i;c++)d=b.f[c],e=a.Sd[c],a.Pa[e]=d.Sa;for(e=a.top;null!=e;e=e.link)e.Zd(a,e.info)}
function Vb(a,b){var c,d,e,f;a.$b==za?e=1:a.$b==Ea&&(e=-1);if(a.da==Zb){b.valid=0;b.na=a.nf;b.sa=a.xg;b.aa=b.ha;b.some=0;for(d=1;d<=b.g;d++)c=b.n[d],c.m=a.la[d],c.J=a.ue?e*a.Aa[d]*c.ma:e*a.Aa[d],c.m==A?c.J=0:c.m==G?c.r=c.c:c.m==Ua?c.r=c.d:c.m==Ra?c.r=0:c.m==Na&&(c.r=c.c);for(d=1;d<=b.i;d++)c=b.f[d],c.m=a.ka[d],c.r=a.ue?a.Pa[d]*c.va:a.Pa[d],c.m==A?c.J=0:c.m==G?c.r=c.c:c.m==Ua?c.r=c.d:c.m==Ra?c.r=0:c.m==Na&&(c.r=c.c),b.aa+=c.u*c.r;for(d=1;d<=b.g;d++)if(c=b.n[d],c.m==A){f=0;for(e=c.k;null!=e;e=e.B)f+=
e.j*e.f.r;c.r=f}for(d=1;d<=b.i;d++)if(c=b.f[d],c.m!=A){f=c.u;for(e=c.k;null!=e;e=e.I)f-=e.j*e.n.J;c.J=f}}else if(a.da==le){b.df=a.Kg;b.ae=b.ha;for(d=1;d<=b.g;d++)c=b.n[d],c.mc=a.ue?e*a.Aa[d]*c.ma:e*a.Aa[d];for(d=1;d<=b.i;d++)c=b.f[d],c.dc=a.ue?a.Pa[d]*c.va:a.Pa[d],b.ae+=c.u*c.dc;for(d=1;d<=b.g;d++){c=b.n[d];f=0;for(e=c.k;null!=e;e=e.B)f+=e.j*e.f.dc;c.dc=f}for(d=1;d<=b.i;d++){c=b.f[d];f=c.u;for(e=c.k;null!=e;e=e.I)f-=e.j*e.n.mc;c.mc=f}}else if(a.da==Sc){b.za=a.zg;b.ta=b.ha;for(d=1;d<=b.i;d++)c=b.f[d],
c.Sa=a.Pa[d],b.ta+=c.u*c.Sa;for(d=1;d<=b.g;d++){c=b.n[d];f=0;for(e=c.k;null!=e;e=e.B)f+=e.j*e.f.Sa;c.Sa=f}}}function lo(a,b){ho(a,function(a,b){a.da==Zb&&(a.la[b.s]=A);a.da!=Sc&&(a.Aa[b.s]=0);return 0}).s=b.ea;jo(a,b)}
function mo(a,b){var c,d;c=ho(a,function(a,b){if(a.da==Zb)if(a.ka[b.F]==A||a.ka[b.F]==G||a.ka[b.F]==Ua)a.ka[b.F]=a.ka[b.F];else return 1;a.Pa[b.F]=b.Ng+a.Pa[b.F];return 0});c.F=b.C;c.Ng=b.c;a.ha+=b.u*b.c;for(d=b.k;null!=d;d=d.I)c=d.n,c.c==c.d?c.d=c.c-=d.j*b.c:(c.c!=-s&&(c.c-=d.j*b.c),c.d!=+s&&(c.d-=d.j*b.c));b.d!=+s&&(b.d-=b.c);b.c=0}
function no(a,b){var c,d;c=ho(a,function(a,b){a.da==Zb&&(a.ka[b.F]=Na);a.Pa[b.F]=b.ph;return 0});c.F=b.C;c.ph=b.c;a.ha+=b.u*b.c;for(d=b.k;null!=d;d=d.I)c=d.n,c.c==c.d?c.d=c.c-=d.j*b.c:(c.c!=-s&&(c.c-=d.j*b.c),c.d!=+s&&(c.d-=d.j*b.c));ko(a,b)}
function oo(a,b){var c,d,e;d=1E-9+1E-12*Math.abs(b.c);b.d-b.c>d||(ho(a,function(a,b){if(a.da==Zb)if(a.la[b.s]==A)a.la[b.s]=A;else if(a.la[b.s]==Na)a.la[b.s]=0<=a.Aa[b.s]?G:Ua;else return 1;return 0}).s=b.ea,c=0.5*(b.d+b.c),e=Math.floor(c+0.5),Math.abs(c-e)<=d&&(c=e),b.c=b.d=c)}
function po(a,b){var c,d,e,f;f=1E-9+1E-12*Math.abs(b.c);if(b.d-b.c>f)return 0;c=ho(a,function(a,b){var c,d;if(a.da==Zb)if(a.ka[b.F]==A)a.ka[b.F]=A;else if(a.ka[b.F]==Na){d=b.l;for(c=b.k;null!=c;c=c.e)d-=c.j*a.Aa[c.Oa];a.ka[b.F]=0<=d?G:Ua}else return 1;return 0});c.F=b.C;c.l=b.u;c.k=null;if(a.da==Zb)for(d=b.k;null!=d;d=d.I)e={},e.Oa=d.n.ea,e.j=d.j,e.e=c.k,c.k=e;c=0.5*(b.d+b.c);d=Math.floor(c+0.5);Math.abs(c-d)<=f&&(c=d);b.c=b.d=c;return 1}
function qo(a,b){if(0.001<b.c||-0.001>b.d)return 1;b.c=-s;b.d=+s;lo(a,b);return 0}function ro(a,b){function c(){e.m=G;b.d=b.c}function d(){e.m=Ua;b.c=b.d}var e;if(0.001<b.u&&b.c==-s||-0.001>b.u&&b.d==+s)return 1;e=ho(a,function(a,b){a.da==Zb&&(a.ka[b.F]=b.m);return 0});e.F=b.C;b.c==-s&&b.d==+s?(e.m=Ra,b.c=b.d=0):b.d==+s?c():b.c==-s?d():b.c!=b.d?2.220446049250313E-16<=b.u?c():-2.220446049250313E-16>=b.u?d():Math.abs(b.c)<=Math.abs(b.d)?c():d():e.m=Na;no(a,b);return 0}
function so(a,b){var c;if(a.Ra)if(c=Math.floor(b+0.5),1E-5>=Math.abs(b-c))b=c;else return 2;if(a.c!=-s){c=a.Ra?1E-5:1E-5+1E-8*Math.abs(a.c);if(b<a.c-c)return 1;if(b<a.c+0.001*c)return a.d=a.c,0}if(a.d!=+s){c=a.Ra?1E-5:1E-5+1E-8*Math.abs(a.d);if(b>a.d+c)return 1;if(b>a.d-0.001*c)return a.c=a.d,0}a.c=a.d=b;return 0}
function to(a,b){var c,d,e;e=b.k;d=e.f;c=so(d,b.c/e.j);if(0!=c)return c;c=ho(a,function(a,b){var c,d;if(a.da==Zb){if(a.ka[b.F]!=Na)return 1;a.la[b.s]=Na;a.ka[b.F]=A}if(a.da!=Sc){d=b.l;for(c=b.k;null!=c;c=c.e)d-=c.j*a.Aa[c.Oa];a.Aa[b.s]=d/b.Da}return 0});c.s=b.ea;c.F=d.C;c.Da=e.j;c.l=d.u;c.k=null;if(a.da!=Sc)for(e=d.k;null!=e;e=e.I)e.n!=b&&(d={},d.Oa=e.n.ea,d.j=e.j,d.e=c.k,c.k=d);jo(a,b);return 0}
function uo(a,b){var c;a.Ra&&(c=Math.floor(b+0.5),b=1E-5>=Math.abs(b-c)?c:Math.ceil(b));if(a.c!=-s&&(c=a.Ra?0.001:0.001+1E-6*Math.abs(a.c),b<a.c+c))return 0;if(a.d!=+s){c=a.Ra?1E-5:1E-5+1E-8*Math.abs(a.d);if(b>a.d+c)return 4;if(b>a.d-0.001*c)return a.c=a.d,3}c=a.c==-s?2:a.Ra&&b>a.c+0.5?2:b>a.c+0.3*(1+Math.abs(a.c))?2:1;a.c=b;return c}
function vo(a,b){var c;a.Ra&&(c=Math.floor(b+0.5),b=1E-5>=Math.abs(b-c)?c:Math.floor(b));if(a.d!=+s&&(c=a.Ra?0.001:0.001+1E-6*Math.abs(a.d),b>a.d-c))return 0;if(a.c!=-s){c=a.Ra?1E-5:1E-5+1E-8*Math.abs(a.c);if(b<a.c-c)return 4;if(b<a.c+0.001*c)return a.d=a.c,3}c=a.d==+s?2:a.Ra&&b<a.d-0.5?2:b<a.d-0.3*(1+Math.abs(a.d))?2:1;a.d=b;return c}
function wo(a,b){var c,d,e,f,g,h;e=b.k;d=e.f;0<e.j?(g=b.c==-s?-s:b.c/e.j,c=b.d==+s?+s:b.d/e.j):(g=b.d==+s?-s:b.d/e.j,c=b.c==-s?+s:b.c/e.j);if(g==-s)g=0;else if(g=uo(d,g),4==g)return 4;if(c==+s)h=0;else if(3==g)h=0;else if(h=vo(d,c),4==h)return 4;if(!g&&!h)return b.c=-s,b.d=+s,lo(a,b),0;c=ho(a,function(a,b){var c,d;if(a.da==Sc)return 0;d=b.l;for(c=b.k;null!=c;c=c.e)d-=c.j*a.Aa[c.Oa];if(a.da==Zb){c=function(){b.Vf?(a.la[b.s]=0<b.Da?G:Ua,a.ka[b.F]=A,a.Aa[b.s]=d/b.Da):(a.la[b.s]=A,a.Aa[b.s]=0);return 0};
var e=function(){b.gg?(a.la[b.s]=0<b.Da?Ua:G,a.ka[b.F]=A,a.Aa[b.s]=d/b.Da):(a.la[b.s]=A,a.Aa[b.s]=0);return 0};if(a.ka[b.F]==A)a.la[b.s]=A,a.Aa[b.s]=0;else if(a.ka[b.F]==G)c();else if(a.ka[b.F]==Ua)e();else if(a.ka[b.F]==Na){if(1E-7<d&&(0<b.Da&&b.c!=-s||0>b.Da&&b.d!=+s||!b.Vf))return a.ka[b.F]=G,c();if(-1E-7>d&&(0<b.Da&&b.d!=+s||0>b.Da&&b.c!=-s||!b.gg))return a.ka[b.F]=Ua,e();if(b.c!=-s&&b.d==+s)a.la[b.s]=G;else if(b.c==-s&&b.d!=+s)a.la[b.s]=Ua;else if(b.c!=-s&&b.d!=+s)a.la[b.s]=b.Da*a.Pa[b.F]<=0.5*
(b.c+b.d)?G:Ua;else return 1;a.ka[b.F]=A;a.Aa[b.s]=d/b.Da}else return 1}a.da==le&&(a.Aa[b.s]=2.220446049250313E-16<d&&b.Vf||-2.220446049250313E-16>d&&b.gg?d/b.Da:0);return 0});c.s=b.ea;c.F=d.C;c.Da=e.j;c.l=d.u;c.c=b.c;c.d=b.d;c.Vf=g;c.gg=h;c.k=null;if(a.da!=Sc)for(d=d.k;null!=d;d=d.I)d!=e&&(f={},f.Oa=d.n.ea,f.j=d.j,f.e=c.k,c.k=f);jo(a,b);return g>=h?g:h}
function xo(a,b){var c,d,e,f;e=b.k;d=e.n;c=ho(a,function(a,b){var c,d;if(a.da==Zb){if(a.la[b.s]==A||a.la[b.s]==Ra)a.ka[b.F]=a.la[b.s];else if(a.la[b.s]==G)a.ka[b.F]=0<b.Da?Ua:G;else if(a.la[b.s]==Ua)a.ka[b.F]=0<b.Da?G:Ua;else return 1;a.la[b.s]=Na}a.da!=Sc&&(a.Aa[b.s]+=b.l/b.Da);c=b.qd;for(d=b.k;null!=d;d=d.e)c-=d.j*a.Pa[d.Oa];a.Pa[b.F]=c/b.Da;return 0});c.s=d.ea;c.F=b.C;c.Da=e.j;c.qd=d.c;c.l=b.u;c.k=null;for(e=d.k;null!=e;e=e.B)e.f!=b&&(f={},f.Oa=e.f.C,f.j=e.j,f.e=c.k,c.k=f,e.f.u-=e.j/c.Da*c.l);
a.ha+=c.qd/c.Da*c.l;0<c.Da?(d.c=b.d==+s?-s:c.qd-c.Da*b.d,d.d=b.c==-s?+s:c.qd-c.Da*b.c):(d.c=b.c==-s?-s:c.qd-c.Da*b.c,d.d=b.d==+s?+s:c.qd-c.Da*b.d);ko(a,b)}
function yo(a,b){function c(){e.m=G;f.d=f.c}function d(){e.m=Ua;f.c=f.d}var e,f,g,h,k,l;g=b.k;f=g.n;k=f.c;if(k!=-s)for(h=f.k;null!=h;h=h.B)if(h!=g)if(0<h.j){if(h.f.d==+s){k=-s;break}k-=h.j*h.f.d}else{if(h.f.c==-s){k=-s;break}k-=h.j*h.f.c}l=f.d;if(l!=+s)for(h=f.k;null!=h;h=h.B)if(h!=g)if(0<h.j){if(h.f.c==-s){l=+s;break}l-=h.j*h.f.c}else{if(h.f.d==+s){l=+s;break}l-=h.j*h.f.d}h=0<g.j?k==-s?-s:k/g.j:l==+s?-s:l/g.j;k=0<g.j?l==+s?+s:l/g.j:k==-s?+s:k/g.j;if(b.c!=-s&&(l=1E-9+1E-12*Math.abs(b.c),h<b.c-l)||
b.d!=+s&&(l=1E-9+1E-12*Math.abs(b.d),k>b.d+l))return 1;b.c=-s;b.d=+s;e=ho(a,function(a,b){if(a.da==Zb)if(a.la[b.s]==A)a.la[b.s]=A;else if(a.la[b.s]==Na)a.la[b.s]=b.m;else return 1;return 0});e.s=f.ea;e.m=-1;g=b.u/g.j;if(2.220446049250313E-16<g)if(f.c!=-s)c();else{if(1E-5<g)return 2;d()}else if(-2.220446049250313E-16>g)if(f.d!=+s)d();else{if(-1E-5>g)return 2;c()}else f.d==+s?c():f.c==-s?d():Math.abs(f.c)<=Math.abs(f.d)?c():d();return 0}
function zo(a,b,c){var d,e=null,f,g,h;d=1;for(g=b.k;null!=g;g=g.B)d<Math.abs(g.j)&&(d=Math.abs(g.j));for(g=b.k;null!=g;g=g.B)if(Math.abs(g.j)<1E-7*d)return 1;d=ho(a,function(a,b){var c,d,e,f,g;if(a.da==Sc)return 0;if(a.da==Zb){if(a.la[b.s]!=A)return 1;for(c=b.k;null!=c;c=c.e){if(a.ka[c.C]!=Na)return 1;a.ka[c.C]=c.m}}for(c=b.k;null!=c;c=c.e){e=c.l;for(d=c.k;null!=d;d=d.e)e-=d.j*a.Aa[d.Oa];c.l=e}d=null;f=0;for(c=b.k;null!=c;c=c.e)if(e=c.l,g=Math.abs(e/c.Jc),c.m==G)0>e&&f<g&&(d=c,f=g);else if(c.m==Ua)0<
e&&f<g&&(d=c,f=g);else return 1;null!=d&&(a.da==Zb&&(a.la[b.s]=b.m,a.ka[d.C]=A),a.Aa[b.s]=d.l/d.Jc);return 0});d.s=b.ea;d.m=b.c==b.d?Na:0==c?G:Ua;d.k=null;for(g=b.k;null!=g;g=g.B)if(f=g.f,a.da!=Sc&&(e={},e.C=f.C,e.m=-1,e.Jc=g.j,e.l=f.u,e.k=null,e.e=d.k,d.k=e),0==c&&0>g.j||0!=c&&0<g.j?(a.da!=Sc&&(e.m=G),f.d=f.c):(a.da!=Sc&&(e.m=Ua),f.c=f.d),a.da!=Sc)for(f=f.k;null!=f;f=f.I)f!=g&&(h={},h.Oa=f.n.ea,h.j=f.j,h.e=e.k,e.k=h);b.c=-s;b.d=+s;return 0}
function Ao(a){var b,c=0,d,e;d=0;for(b=a.k;null!=b;b=b.B)if(0<b.j){if(b.f.c==-s){d=-s;break}d+=b.j*b.f.c}else{if(b.f.d==+s){d=-s;break}d+=b.j*b.f.d}e=0;for(b=a.k;null!=b;b=b.B)if(0<b.j){if(b.f.d==+s){e=+s;break}e+=b.j*b.f.d}else{if(b.f.c==-s){e=+s;break}e+=b.j*b.f.c}if(a.c!=-s&&(b=0.001+1E-6*Math.abs(a.c),a.c-b>e)||a.d!=+s&&(b=0.001+1E-6*Math.abs(a.d),a.d+b<d))return 51;a.c!=-s&&(b=1E-9+1E-12*Math.abs(a.c),a.c-b>d&&(c=a.c+b<=e?c|1:c|2));a.d!=+s&&(b=1E-9+1E-12*Math.abs(a.d),a.d+b<e&&(c=a.d-b>=d?c|
16:c|32));return c}function Bo(a,b,c){a.da==Zb&&(a=ho(a,function(a,b){if(a.da!=Zb)return 1;a.la[b.s]=a.la[b.s]==A?A:b.m;return 0}),a.s=b.ea,a.m=b.d==+s?G:b.c==-s?Ua:b.c!=b.d?0==c?Ua:G:Na);0==c?b.c=-s:1==c&&(b.d=+s)}
function Co(a){var b,c,d,e,f,g,h,k,l,p,m;k=l=p=m=0;for(d=a.td;null!=d;d=d.ca)if(d.Ra&&d.c!=d.d&&(0!=d.c||1!=d.d))if(-1E6>d.c||1E6<d.d||4095<d.d-d.c)k++;else if(l++,0!=d.c&&mo(a,d),e=d.d|0,1!=e){g=2;for(c=4;e>=c;)g++,c+=c;p+=g;b=ho(a,function(a,b){var c,d,e=a.Pa[b.F];c=1;for(d=2;c<b.i;c++,d+=d)e+=d*a.Pa[b.C+(c-1)];a.Pa[b.F]=e;return 0});b.F=d.C;b.C=0;b.i=g;e<c-1?(c=eo(a),m++,c.c=-s,c.d=e):c=null;d.d=1;null!=c&&go(c,d,1);h=1;for(c=2;h<g;h++,c+=c)for(e=fo(a),e.Ra=1,e.c=0,e.d=1,e.u=c*d.u,0==b.C&&(b.C=
e.C),f=d.k;null!=f;f=f.I)go(f.n,e,c*f.j)}0<l&&x(l+" integer variable(s) were replaced by "+p+" binary ones");0<m&&x(m+" row(s) were added due to binarization");0<k&&x("Binarization failed for "+k+" integer variable(s)")}function Do(a,b){var c,d,e;d=null;for(c=a.k;null!=c;c=c.B)e={},e.fa=b*c.j,e.jc=c.f,e.e=d,d=e;return d}
function Eo(a,b,c){var d,e,f;for(d=a;null!=d;d=d.e);e=0;for(d=a;null!=d;d=d.e)if(1!=d.fa)if(-1==d.fa)e++;else break;if(null==d&&b==1-e)return 1;for(d=a;null!=d;d=d.e)0>d.fa&&(b-=d.fa);for(d=a;null!=d;d=d.e)if(Math.abs(d.fa)>b)return 0;e=null;for(d=a;null!=d;d=d.e)if(null==e||Math.abs(e.fa)>Math.abs(d.fa))e=d;f=null;for(d=a;null!=d;d=d.e)d!=e&&(null==f||Math.abs(f.fa)>Math.abs(d.fa))&&(f=d);if(Math.abs(e.fa)+Math.abs(f.fa)<=b+(0.001+1E-6*Math.abs(b)))return 0;b=1;for(d=a;null!=d;d=d.e)0<d.fa?d.fa=
1:(d.fa=-1,b-=1);c(b);return 2}function Fo(a,b){var c,d,e,f,g=0,h;for(f=0;1>=f;f++){if(0==f){if(b.d==+s)continue;e=Do(b,1);h=+b.d}else{if(b.c==-s)continue;e=Do(b,-1);h=-b.c}c=Eo(e,h,function(a){h=a});if(1==f&&1==c||2==c){g++;if(b.c==-s||b.d==+s)c=null;else for(c=eo(a),0==f?(c.c=b.c,c.d=+s):(c.c=-s,c.d=b.d),d=b.k;null!=d;d=d.B)go(c,d.f,d.j);io(b);b.c=-s;for(b.d=h;null!=e;e=e.e)go(b,e.jc,e.fa);null!=c&&(b=c)}}return g}
function Go(a,b,c){var d,e;for(d=a;null!=d;d=d.e);e=0;for(d=a;null!=d;d=d.e)if(1!=d.fa)if(-1==d.fa)e++;else break;if(null==d&&b==1-e)return 1;for(d=a;null!=d;d=d.e)0>d.fa&&(b-=d.fa);if(0.001>b)return 0;e=1E-9+1E-12*Math.abs(b);for(d=a;null!=d;d=d.e)if(Math.abs(d.fa)<b-e)return 0;b=1;for(d=a;null!=d;d=d.e)0<d.fa?d.fa=1:(d.fa=-1,b-=1);c(b);return 2}
function Ho(a,b){var c,d,e,f,g=0,h;for(f=0;1>=f;f++){if(0==f){if(b.c==-s)continue;e=Do(b,1);h=+b.c}else{if(b.d==+s)continue;e=Do(b,-1);h=-b.d}c=Go(e,h,function(a){h=a});if(1==f&&1==c||2==c){g++;if(b.c==-s||b.d==+s)c=null;else for(c=eo(a),0==f?(c.c=-s,c.d=b.d):(c.c=b.c,c.d=+s),d=b.k;null!=d;d=d.B)go(c,d.f,d.j);io(b);b.c=h;for(b.d=+s;null!=e;e=e.e)go(b,e.jc,e.fa);null!=c&&(b=c)}}return g}
function Io(a,b,c){var d,e=0,f,g;f=0;for(d=a;null!=d;d=d.e)if(0<d.fa){if(d.jc.c==-s)return e;f+=d.fa*d.jc.c}else{if(d.jc.d==+s)return e;f+=d.fa*d.jc.d}for(d=a;null!=d;d=d.e)d.jc.Ra&&0==d.jc.c&&1==d.jc.d&&(0<d.fa?(a=f,b-d.fa<a&&a<b&&(g=b-a,0.001<=g&&d.fa-g>=0.01*(1+d.fa)&&(d.fa=g,e++))):(a=f-d.fa,b<a&&a<b-d.fa&&(g=d.fa+(a-b),-0.001>=g&&g-d.fa>=0.01*(1-d.fa)&&(d.fa=g,f+=a-b,b=a,e++))));c(b);return e}
function Jo(a,b){var c,d,e,f,g=Array(2),h;for(f=g[0]=g[1]=0;1>=f;f++){if(0==f){if(b.c==-s)continue;e=Do(b,1);h=+b.c}else{if(b.d==+s)continue;e=Do(b,-1);h=-b.d}g[f]=Io(e,h,function(a){h=a});if(0<g[f]){if(b.c==-s||b.d==+s)c=null;else for(c=eo(a),0==f?(c.c=-s,c.d=b.d):(c.c=b.c,c.d=+s),d=b.k;null!=d;d=d.B)go(c,d.f,d.j);io(b);b.c=h;b.d=+s;for(d=e;null!=d;d=d.e)go(b,d.jc,d.fa);null!=c&&(b=c)}}return g[0]+g[1]}
function Ko(a,b,c){function d(){for(f=b.k;null!=f;f=g){e=f.f;g=f.B;for(h=e.k;null!=h;h=h.I)$n(a,h.n);no(a,e)}lo(a,b);return 0}var e,f,g,h,k;if(null==b.k){k=qo(a,b);if(0==k)return 0;if(1==k)return ac}if(null==b.k.B)if(e=b.k.f,b.c==b.d){k=to(a,b);if(0==k){for(f=e.k;null!=f;f=f.I)$n(a,f.n);no(a,e);return 0}if(1==k||2==k)return ac}else{k=wo(a,b);if(0<=k&&3>=k){co(a,e);if(2<=k)for(f=e.k;null!=f;f=f.I)$n(a,f.n);3==k&&no(a,e);return 0}if(4==k)return ac}k=Ao(b);if(51==k)return ac;if(0==(k&15))b.c!=-s&&Bo(a,
b,0);else if(1!=(k&15)&&2==(k&15)&&0==zo(a,b,0))return d();if(0==(k&240))b.d!=+s&&Bo(a,b,1);else if(16!=(k&240)&&32==(k&240)&&0==zo(a,b,1))return d();if(b.c==-s&&b.d==+s){for(f=b.k;null!=f;f=f.B)co(a,f.f);lo(a,b);return 0}return a.da==Sc&&c&&0>Lo(a,b,1)?ac:0}
function Lo(a,b,c){var d,e,f,g,h,k=0,l;h=!1;e=1;for(d=b.k;null!=d;d=d.B)d.f.qb.qb=-s,d.f.ub.ub=+s,e<Math.abs(d.j)&&(e=Math.abs(d.j));g=1E-6*e;if(b.c!=-s){e=null;for(d=b.k;null!=d;d=d.B)if(0<d.j&&d.f.d==+s||0>d.j&&d.f.c==-s)if(null==e)e=d;else{h=!0;break}if(!h){h=b.c;for(d=b.k;null!=d;d=d.B)d!=e&&(h=0<d.j?h-d.j*d.f.d:h-d.j*d.f.c);if(null==e)for(d=b.k;null!=d;d=d.B)d.j>=+g?d.f.qb.qb=d.f.d+h/d.j:d.j<=-g&&(d.f.ub.ub=d.f.c+h/d.j);else e.j>=+g?e.f.qb.qb=h/e.j:e.j<=-g&&(e.f.ub.ub=h/e.j)}}h=!1;if(b.d!=+s){e=
null;for(d=b.k;null!=d;d=d.B)if(0<d.j&&d.f.c==-s||0>d.j&&d.f.d==+s)if(null==e)e=d;else{h=!0;break}if(!h){h=b.d;for(d=b.k;null!=d;d=d.B)d!=e&&(h=0<d.j?h-d.j*d.f.c:h-d.j*d.f.d);if(null==e)for(d=b.k;null!=d;d=d.B)d.j>=+g?d.f.ub.ub=d.f.c+h/d.j:d.j<=-g&&(d.f.qb.qb=d.f.d+h/d.j);else e.j>=+g?e.f.ub.ub=h/e.j:e.j<=-g&&(e.f.qb.qb=h/e.j)}}for(e=b.k;null!=e;)for(d=e.f,e=e.B,g=0;1>=g;g++){f=d.c;l=d.d;if(0==g){if(d.qb.qb==-s)continue;h=uo(d,d.qb.qb)}else{if(d.ub.ub==+s)continue;h=vo(d,d.ub.ub)}if(0==h||1==h)d.c=
f,d.d=l;else if(2==h||3==h){k++;if(c)for(f=d.k;null!=f;f=f.I)f.n!=b&&$n(a,f.n);if(3==h){no(a,d);break}}else if(4==h)return-1}return k}function Mo(a,b){var c,d,e;if(null==b.k){e=ro(a,b);if(0==e)return 0;if(1==e)return bc}if(null==b.k.I){c=b.k.n;var f=function(){xo(a,b);if(c.c==-s&&c.d==+s){for(d=c.k;null!=d;d=d.B)co(a,d.f);lo(a,c)}else $n(a,c);return 0};if(c.c==c.d){if(!b.Ra)return f()}else if(!b.Ra){e=yo(a,b);if(0==e)return f();if(1!=e&&2==e)return bc}}return 0}
function $b(a,b){var c,d,e;for(c=a.Db;null!=c;c=d)d=c.e,c.c==-s&&c.d==+s&&lo(a,c);for(c=a.Db;null!=c;c=d)d=c.e,c.c!=-s&&c.d!=+s&&c.c<c.d&&oo(a,c);for(c=a.Kb;null!=c;c=d)d=c.e,c.c==c.d&&no(a,c);for(c=a.Kb;null!=c;c=d)d=c.e,c.c!=-s&&c.d!=+s&&c.c<c.d&&(e=po(a,c),0!=e&&1==e&&no(a,c));for(c=a.Db;null!=c;c=c.e)c.ja=1;for(c=a.Kb;null!=c;c=c.e)c.ja=1;for(d=1;d;){for(d=0;;){c=a.Db;if(null==c||!c.ja)break;d=a;e=c;e.ja&&(e.ja=0,Zn(d,e),Yn(d,e,1));c=Ko(a,c,b);if(0!=c)return c;d=1}for(;;){c=a.Kb;if(null==c||!c.ja)break;
d=a;e=c;e.ja&&(e.ja=0,bo(d,e),ao(d,e,1));c=Mo(a,c);if(0!=c)return c;d=1}}if(a.da==Sc&&!b)for(c=a.Db;null!=c;c=c.e)if(0>Lo(a,c,0))return c=ac;return 0}
function Tc(a,b){var c,d,e,f,g;c=$b(a,1);if(0!=c)return c;b.sd&&Co(a);g=0;for(c=a.Pc;null!=c;c=d)if(d=c.ca,(c.c!=-s||c.d!=+s)&&c.c!=c.d&&null!=c.k&&null!=c.k.B){for(f=c.k;null!=f&&(e=f.f,e.Ra&&0==e.c&&1==e.d);f=f.B);null==f&&(g+=Fo(a,c))}0<g&&x(g+" hidden packing inequaliti(es) were detected");g=0;for(c=a.Pc;null!=c;c=d)if(d=c.ca,(c.c!=-s||c.d!=+s)&&c.c!=c.d&&null!=c.k&&null!=c.k.B&&null!=c.k.B.B){for(f=c.k;null!=f&&(e=f.f,e.Ra&&0==e.c&&1==e.d);f=f.B);null==f&&(g+=Ho(a,c))}0<g&&x(g+" hidden covering inequaliti(es) were detected");
g=0;for(c=a.Pc;null!=c;c=d)d=c.ca,c.c!=c.d&&(g+=Jo(a,c));0<g&&x(g+" constraint coefficient(s) were reduced");return 0}function No(a){var b,c;b=1;for(c=32;55>=c;b++,c++)a.nb[b]=a.nb[b]-a.nb[c]&2147483647;for(c=1;55>=b;b++,c++)a.nb[b]=a.nb[b]-a.nb[c]&2147483647;a.Qf=54;return a.nb[55]}function sg(){var a={},b;a.nb=Array(56);a.nb[0]=-1;for(b=1;55>=b;b++)a.nb[b]=0;a.Qf=0;Md(a,1);return a}
function Md(a,b){var c,d,e=1;b=d=b-0&2147483647;a.nb[55]=d;for(c=21;c;c=(c+21)%55)a.nb[c]=e,e=d-e&2147483647,b=b&1?1073741824+(b>>1):b>>1,e=e-b&2147483647,d=a.nb[c];No(a);No(a);No(a);No(a);No(a)}function dm(a){return 0<=a.nb[a.Qf]?a.nb[a.Qf--]:No(a)}function bn(a){var b;do b=dm(a);while(2147483648<=b);return b%16777216}function tg(a){a=dm(a)/2147483647;return-0.3*(1-a)+0.7*a}var De=1,Fe=2,We=1,Se=2,Ce=0,Ue=1E-10;function Te(a,b,c){return(b-1)*a.K+c-b*(b-1)/2}
function Oo(a,b,c){var d;0==b?(b=1,d=0):Math.abs(a)<=Math.abs(b)?(a=-a/b,d=1/Math.sqrt(1+a*a),b=d*a):(a=-b/a,b=1/Math.sqrt(1+a*a),d=b*a);c(b,d)}
function Ve(a,b,c){for(var d=a.i,e=a.Nb,f=a.v,g,h,k,l,p,m;b<d;b++)l=Te(a,b,b),h=(b-1)*a.K+1,p=(d-1)*a.K+1,Math.abs(f[l])<Ue&&Math.abs(c[b])<Ue&&(f[l]=c[b]=0),0!=c[b]&&Oo(f[l],c[b],function(a,r){g=b;for(k=l;g<=d;g++,k++){var n=f[k],t=c[g];f[k]=a*n-r*t;c[g]=r*n+a*t}g=1;k=h;for(m=p;g<=d;g++,k++,m++)n=e[k],t=e[m],e[k]=a*n-r*t,e[m]=r*n+a*t});Math.abs(c[d])<Ue&&(c[d]=0);f[Te(a,d,d)]=c[d]}
Ce&&(Le=function(a,b){var c=a.i,d=a.Nb,e=a.v,f=a.s,g=a.l,h,k,l,p,m=0;for(h=1;h<=c;h++)for(k=1;k<=c;k++){p=0;for(l=1;l<=c;l++)p+=d[(h-1)*a.K+l]*g[(l-1)*a.K+k];l=f[k];l=h<=l?e[Te(a,h,l)]:0;p=Math.abs(p-l)/(1+Math.abs(l));m<p&&(m=p)}1E-8<m&&x(b+": dmax = "+m+"; relative error too large")});
function Ke(a,b,c,d){a.pa<a.i&&w("scf_solve_it: singular matrix");if(b){b=a.i;var e=a.Nb,f=a.v,g=a.s,h=a.ig,k,l,p;for(k=1;k<=b;k++)h[k]=c[g[k]+d];for(k=1;k<=b;k++)for(l=Te(a,k,k),p=h[k]/=f[l],g=k+1,l++;g<=b;g++,l++)h[g]-=f[l]*p;for(g=1;g<=b;g++)c[g+d]=0;for(k=1;k<=b;k++)for(p=h[k],g=1,l=(k-1)*a.K+1;g<=b;g++,l++)c[g+d]+=e[l]*p}else{b=a.i;e=a.Nb;f=a.v;h=a.s;k=a.ig;for(var m,g=1;g<=b;g++){m=0;l=1;for(p=(g-1)*a.K+1;l<=b;l++,p++)m+=e[p]*c[l+d];k[g]=m}for(g=b;1<=g;g--){m=k[g];l=b;for(p=Te(a,g,b);l>g;l--,
p--)m-=f[p]*k[l];k[g]=m/f[p]}for(g=1;g<=b;g++)c[h[g]+d]=k[g]}}
var gc=exports.glp_scale_prob=function(a,b){function c(a,b){var c,d,e;d=1;for(c=a.n[b].k;null!=c;c=c.B)if(e=Math.abs(c.j),e=e*c.n.ma*c.f.va,null==c.ua||d>e)d=e;return d}function d(a,b){var c,d,e;d=1;for(c=a.n[b].k;null!=c;c=c.B)if(e=Math.abs(c.j),e=e*c.n.ma*c.f.va,null==c.ua||d<e)d=e;return d}function e(a,b){var c,d,e;d=1;for(c=a.f[b].k;null!=c;c=c.I)if(e=Math.abs(c.j),e=e*c.n.ma*c.f.va,null==c.ra||d>e)d=e;return d}function f(a,b){var c,d,e;d=1;for(c=a.f[b].k;null!=c;c=c.I)if(e=Math.abs(c.j),e=e*
c.n.ma*c.f.va,null==c.ra||d<e)d=e;return d}function g(a){var b,d,e;for(b=d=1;b<=a.g;b++)if(e=c(a,b),1==b||d>e)d=e;return d}function h(a){var b,c,e;for(b=c=1;b<=a.g;b++)if(e=d(a,b),1==b||c<e)c=e;return c}function k(a,b){var c,e,g;for(e=0;1>=e;e++)if(e==b)for(c=1;c<=a.g;c++)g=d(a,c),zb(a,c,Cb(a,c)/g);else for(c=1;c<=a.i;c++)g=f(a,c),Ab(a,c,Db(a,c)/g)}function l(a){var b,e,f;for(b=e=1;b<=a.g;b++)if(f=d(a,b)/c(a,b),1==b||e<f)e=f;return e}function p(a){var b,c,d;for(b=c=1;b<=a.i;b++)if(d=f(a,b)/e(a,b),
1==b||c<d)c=d;return c}function m(a){var b,k,m=0,y;k=l(a)>p(a);for(b=1;15>=b;b++){y=m;m=h(a)/g(a);if(1<b&&m>0.9*y)break;y=a;for(var E=k,C=void 0,D=C=void 0,H=void 0,D=0;1>=D;D++)if(D==E)for(C=1;C<=y.g;C++)H=c(y,C)*d(y,C),zb(y,C,Cb(y,C)/Math.sqrt(H));else for(C=1;C<=y.i;C++)H=e(y,C)*f(y,C),Ab(y,C,Db(y,C)/Math.sqrt(H))}}b&~(Uc|Vc|Wc|Xc|hc)&&w("glp_scale_prob: flags = "+b+"; invalid scaling options");b&hc&&(b=Uc|Vc|Xc);(function(a,b){function c(a,b,d,e){return a+": min|aij| = "+b+" max|aij| = "+d+" ratio = "+
e+""}var d,e;x("Scaling...");Eb(a);d=g(a);e=h(a);x(c(" A",d,e,e/d));if(0.1<=d&&10>=e&&(x("Problem data seem to be well scaled"),b&Xc))return;b&Uc&&(m(a),d=g(a),e=h(a),x(c("GM",d,e,e/d)));b&Vc&&(k(a,l(a)>p(a)),d=g(a),e=h(a),x(c("EQ",d,e,e/d)));if(b&Wc){for(d=1;d<=a.g;d++)zb(a,d,ug(Cb(a,d)));for(d=1;d<=a.i;d++)Ab(a,d,ug(Db(a,d)));d=g(a);e=h(a);x(c("2N",d,e,e/d))}})(a,b)};
function Pb(a,b){function c(a,b,c,d){var e=a.g,f=a.Ca,g=a.Ba,h=a.Ia;a=a.head[b];if(a<=e)e=1,c[1]=a,d[1]=1;else for(b=f[a-e],e=f[a-e+1]-b,ga(c,1,g,b,e),ga(d,1,h,b,e),c=1;c<=e;c++)d[c]=-d[c];return e}function d(a){var b=od(a.U,a.g,c,a);a.valid=0==b;return b}function e(a,b,c){var d=a.g,e;if(c<=d){var f=Array(2);e=Array(2);f[1]=c;e[1]=1;b=Ne(a.U,b,1,f,0,e)}else{var g=a.Ca,f=a.Ba,h=a.Ia;e=a.jb;var k;k=g[c-d];c=g[c-d+1];g=0;for(d=k;d<c;d++)e[++g]=-h[d];b=Ne(a.U,b,g,f,k-1,e)}a.valid=0==b;return b}function f(a,
b,c){var d=a.g,e=a.jb,f=a.jb,g=a.g,h=a.Ca,k=a.Ba,l=a.Ia,m=a.head,n,p,q;ga(f,1,b,1,g);for(b=1;b<=g;b++)if(q=c[b],0!=q)if(n=m[b],n<=g)f[n]-=q;else for(p=h[n-g],n=h[n-g+1];p<n;p++)f[k[p]]+=l[p]*q;wd(a.U,e);for(a=1;a<=d;a++)c[a]+=e[a]}function g(a,b,c){var d=a.g,e=a.jb,f=a.jb,g=a.g,h=a.Ca,k=a.Ba,l=a.Ia,m=a.head,n,p,q,K;for(n=1;n<=g;n++){p=m[n];K=b[n];if(p<=g)K-=c[p];else for(q=h[p-g],p=h[p-g+1];q<p;q++)K+=l[q]*c[k[q]];f[n]=K}yd(a.U,e);for(a=1;a<=d;a++)c[a]+=e[a]}function h(a,b,c){var d=a.g,e=a.De,f=a.Kd,
g=a.Ce,h=a.Ee,k;if(c<=d)k=e[c]+f[c]++,g[k]=b,h[k]=1;else{k=a.Ca;var l=a.Ba;a=a.Ia;var m;m=k[c-d];c=k[c-d+1];for(d=m;d<c;d++)k=l[d],k=e[k]+f[k]++,g[k]=b,h[k]=-a[d]}}function k(a,b,c){var d=a.g,e=a.De,f=a.Kd,g=a.Ce,h=a.Ee,k;if(c<=d){for(d=k=e[c];g[d]!=b;d++);k+=--f[c];g[d]=g[k];h[d]=h[k]}else{k=a.Ca;a=a.Ba;var l,m;m=k[c-d];for(c=k[c-d+1];m<c;m++){l=a[m];for(d=k=e[l];g[d]!=b;d++);k+=--f[l];g[d]=g[k];h[d]=h[k]}}}function l(a,b){var c=a.c,d=a.d,e=a.m,f,g;f=a.head[a.g+b];switch(e[b]){case G:g=c[f];break;
case Ua:g=d[f];break;case Ra:g=0;break;case Na:g=c[f]}return g}function p(a,b){var c=a.g,d=a.i,e=a.Ca,g=a.Ba,h=a.Ia,k=a.head,m=a.Gc,n,p,q,K;for(n=1;n<=c;n++)m[n]=0;for(n=1;n<=d;n++)if(p=k[c+n],K=l(a,n),0!=K)if(p<=c)m[p]-=K;else for(q=e[p-c],p=e[p-c+1];q<p;q++)m[g[q]]+=K*h[q];ga(b,1,m,1,c);wd(a.U,b);f(a,m,b)}function m(a){var b=a.i,c=a.Qa,d=a.Hc,e;e=a.g;var f=a.u,h=a.head,k=a.Gc,l;for(l=1;l<=e;l++)k[l]=f[h[l]];ga(d,1,k,1,e);yd(a.U,d);g(a,k,d);for(e=1;e<=b;e++){f=a.g;l=a.u;k=h=void 0;h=a.head[f+e];
k=l[h];if(h<=f)k-=d[h];else{l=a.Ca;for(var m=a.Ba,n=a.Ia,p=void 0,q=void 0,p=void 0,p=l[h-f],q=l[h-f+1];p<q;p++)k+=n[p]*d[m[p]]}c[e]=k}}function q(a){var b=a.g,c=a.i,d=a.head,e=a.hd,f=a.gamma,g;a.Rb=1E3;ha(e,1,0,b+c);for(a=1;a<=c;a++)g=d[b+a],e[g]=1,f[a]=1}function r(a,b){var c=a.i,d=a.m,e=a.Qa,f=a.gamma,g,h,k,l;l=h=0;for(g=1;g<=c;g++){k=e[g];switch(d[g]){case G:if(k>=-b)continue;break;case Ua:if(k<=+b)continue;break;case Ra:if(-b<=k&&k<=+b)continue;break;case Na:continue}k=k*k/f[g];l<k&&(h=g,l=k)}a.F=
h}function n(a){var b=a.g,c=a.yb,d=a.Ua,e=a.Ua,f,g;g=a.head[b+a.F];for(f=1;f<=b;f++)e[f]=0;if(g<=b)e[g]=-1;else{var h=a.Ca;f=a.Ba;var k=a.Ia,l;l=h[g-b];for(g=h[g-b+1];l<g;l++)e[f[l]]=k[l]}wd(a.U,d);e=0;for(f=1;f<=b;f++)0!=d[f]&&(c[++e]=f);a.Tb=e}function t(a){var b=a.g,c=a.yb,d=a.Ua,e=a.Hc,g,h;h=a.head[b+a.F];for(g=1;g<=b;g++)e[g]=0;if(h<=b)e[h]=-1;else{var k=a.Ca;g=a.Ba;var l=a.Ia,m;m=k[h-b];for(h=k[h-b+1];m<h;m++)e[g[m]]=l[m]}f(a,e,d);e=0;for(g=1;g<=b;g++)0!=d[g]&&(c[++e]=g);a.Tb=e}function y(a,
b){var c=a.Tb,d=a.yb,e=a.Ua,f,g,h;g=0;for(f=1;f<=c;f++)h=Math.abs(e[d[f]]),g<h&&(g=h);a.rh=g;h=b*(1+0.01*g);for(g=0;g<c;)f=d[c],Math.abs(e[f])<h?c--:(g++,d[c]=d[g],d[g]=f);a.sh=g}function E(a,b){var c=a.g,d=a.type,e=a.c,f=a.d,g=a.u,h=a.head,k=a.D,l=a.Ha,m=a.F,n=a.yb,p=a.Ua,q=a.sh,K,r,v,u,t,y,oa,z,C;oa=0<a.Qa[m]?-1:1;K=h[c+m];d[K]==I?(m=-1,r=0,C=f[K]-e[K],t=1):(r=m=0,C=s,t=0);for(v=1;v<=q;v++){c=n[v];K=h[c];u=oa*p[c];if(0<u)if(1==k&&0>g[K])y=b*(1+L*Math.abs(e[K])),z=(e[K]+y-l[c])/u,K=G;else if(1==
k&&0<g[K])continue;else if(d[K]==Ta||d[K]==I||d[K]==B)y=b*(1+L*Math.abs(f[K])),z=(f[K]+y-l[c])/u,K=Ua;else continue;else if(1==k&&0<g[K])y=b*(1+L*Math.abs(f[K])),z=(f[K]-y-l[c])/u,K=Ua;else if(1==k&&0>g[K])continue;else if(d[K]==Sa||d[K]==I||d[K]==B)y=b*(1+L*Math.abs(e[K])),z=(e[K]-y-l[c])/u,K=G;else continue;0>z&&(z=0);if(C>z||C==z&&t<Math.abs(u))m=c,r=K,C=z,t=Math.abs(u)}if(!(0==b||0>=m||0==C))for(y=C,r=m=0,C=s,t=0,v=1;v<=q;v++){c=n[v];K=h[c];u=oa*p[c];if(0<u)if(1==k&&0>g[K])z=(e[K]-l[c])/u,K=G;
else if(1==k&&0<g[K])continue;else if(d[K]==Ta||d[K]==I||d[K]==B)z=(f[K]-l[c])/u,K=Ua;else continue;else if(1==k&&0<g[K])z=(f[K]-l[c])/u,K=Ua;else if(1==k&&0>g[K])continue;else if(d[K]==Sa||d[K]==I||d[K]==B)z=(e[K]-l[c])/u,K=G;else continue;0>z&&(z=0);z<=y&&t<Math.abs(u)&&(m=c,r=K,C=z,t=Math.abs(u))}a.s=m;a.nf=0<m&&d[h[m]]==B?Na:r;a.th=oa*C}function C(a,b){var c=a.g,d=a.s,e;for(e=1;e<=c;e++)b[e]=0;b[d]=1;yd(a.U,b)}function D(a,b){var c=a.g,d=a.s,e=a.Hc,f;for(f=1;f<=c;f++)e[f]=0;e[d]=1;g(a,e,b)}function H(a,
b){var c=a.g,d=a.i,e=a.De,f=a.Kd,g=a.Ce,h=a.Ee,k=a.Vb,l=a.mb,m,n,p,q;for(m=1;m<=d;m++)l[m]=0;for(m=1;m<=c;m++)if(q=b[m],0!=q)for(n=e[m],p=n+f[m];n<p;n++)l[g[n]]-=q*h[n];c=0;for(m=1;m<=d;m++)0!=l[m]&&(k[++c]=m);a.Bc=c}function R(a){var b=a.Ha,c=a.F,d=a.Tb,e=a.yb,f=a.Ua,g=a.s,h=a.th;0<g&&(b[g]=l(a,c)+h);if(0!=h)for(c=1;c<=d;c++)a=e[c],a!=g&&(b[a]+=f[a]*h)}function V(a){var b=a.u,c=a.head,d=a.Tb,e=a.yb,f=a.Ua,g,h;h=b[c[a.g+a.F]];for(g=1;g<=d;g++)a=e[g],h+=b[c[a]]*f[a];return h}function O(a){var b=a.Qa,
c=a.F,d=a.Bc,e=a.Vb;a=a.mb;var f,g,h;h=b[c]/=a[c];for(g=1;g<=d;g++)f=e[g],f!=c&&(b[f]-=a[f]*h)}function Q(a){var b=a.g,c=a.type,d=a.Ca,e=a.Ba,f=a.Ia,g=a.head,h=a.hd,k=a.gamma,l=a.F,m=a.Tb,n=a.yb,p=a.Ua,q=a.s,K=a.Bc,r=a.Vb,v=a.mb,u=a.Hc,t,y,oa,z,C,D;a.Rb--;z=C=h[g[b+l]]?1:0;for(t=1;t<=b;t++)u[t]=0;for(y=1;y<=m;y++)t=n[y],h[g[t]]?(u[t]=t=p[t],z+=t*t):u[t]=0;yd(a.U,u);m=v[l];for(y=1;y<=K;y++)if(a=r[y],a!=l){t=v[a]/m;n=g[b+a];if(n<=b)D=u[n];else for(D=0,oa=d[n-b],p=d[n-b+1];oa<p;oa++)D-=f[oa]*u[e[oa]];
p=k[a]+t*t*z+2*t*D;t=(h[n]?1:0)+C*t*t;k[a]=p>=t?p:t;2.220446049250313E-16>k[a]&&(k[a]=2.220446049250313E-16)}c[g[q]]==B?k[l]=1:(k[l]=z/(m*m),2.220446049250313E-16>k[l]&&(k[l]=2.220446049250313E-16))}function F(a){var b=a.g,c=a.head,d=a.m,e=a.F,f=a.s;a=a.nf;var g;if(0>f)switch(d[e]){case G:d[e]=Ua;break;case Ua:d[e]=G}else g=c[f],c[f]=c[b+e],c[b+e]=g,d[e]=a}function W(a,b){var c=a.g,d=a.i,e=a.type,f=a.c,g=a.d,h=a.u,k=a.head,l=a.Ha,m,n=0,p;b*=0.9;for(m=1;m<=c+d;m++)h[m]=0;for(d=1;d<=c;d++){m=k[d];if(e[m]==
Sa||e[m]==I||e[m]==B)p=b*(1+L*Math.abs(f[m])),l[d]<f[m]-p&&(h[m]=-1,n++);if(e[m]==Ta||e[m]==I||e[m]==B)p=b*(1+L*Math.abs(g[m])),l[d]>g[m]+p&&(h[m]=1,n++)}return n}function X(a){var b=a.g,c=a.i,d=a.u,e=a.eb;a=a.$a;var f;for(f=1;f<=b;f++)d[f]=0;for(f=1;f<=c;f++)d[b+f]=a*e[f]}function ca(a,b){var c=a.g,d=a.type,e=a.c,f=a.d,g=a.u,h=a.head,k=a.D,l=a.Ha,m,n,p;for(m=1;m<=c;m++)if(n=h[m],1==k&&0>g[n]){if(p=b*(1+L*Math.abs(e[n])),l[m]>e[n]+p)return 1}else if(1==k&&0<g[n]){if(p=b*(1+L*Math.abs(f[n])),l[m]<
f[n]-p)return 1}else{if(d[n]==Sa||d[n]==I||d[n]==B)if(p=b*(1+L*Math.abs(e[n])),l[m]<e[n]-p)return 1;if(d[n]==Ta||d[n]==I||d[n]==B)if(p=b*(1+L*Math.abs(f[n])),l[m]>f[n]+p)return 1}return 0}function ka(a,b){var c=a.g,d=a.c,e=a.d,f=a.u,g=a.head,h=a.Ha,k,l,m;for(k=1;k<=c;k++)if(l=g[k],0>f[l]){if(m=b*(1+L*Math.abs(d[l])),h[k]<d[l]-m)return 1}else if(0<f[l]&&(m=b*(1+L*Math.abs(e[l])),h[k]>e[l]+m))return 1;return 0}function P(a){var b=a.g,c=a.i,d=a.eb,e=a.head,f=a.Ha,g,h,k;k=d[0];for(g=1;g<=b;g++)h=e[g],
h>b&&(k+=d[h-b]*f[g]);for(f=1;f<=c;f++)h=e[b+f],h>b&&(k+=d[h-b]*l(a,f));return k}function u(a,b,c){var d=a.g,e=a.type,f=a.c,g=a.d,h=a.D,k=a.head,l=a.Ha,m,n;if(!(b.o<fc||0<b.fb&&1E3*la(a.hc)<b.fb||a.$==a.be||!c&&0!=a.$%b.bc)){m=n=0;for(b=1;b<=d;b++)c=k[b],(e[c]==Sa||e[c]==I||e[c]==B)&&l[b]<f[c]&&(n+=f[c]-l[b]),(e[c]==Ta||e[c]==I||e[c]==B)&&l[b]>g[c]&&(n+=l[b]-g[c]),e[c]==B&&m++;x((1==h?" ":"*")+a.$+": obj = "+P(a)+" infeas = "+n+" ("+m+")");a.be=a.$}}function z(a,b,c,d,e){var f=a.g,g=a.i,h=a.$a,k=
a.head,l=a.m,m=a.Ha,n=a.Qa;b.valid=1;a.valid=0;b.U=a.U;a.U=null;ga(b.head,1,k,1,f);b.na=c;b.sa=d;b.aa=P(a);b.$=a.$;b.some=e;for(a=1;a<=f;a++)c=k[a],c<=f?(c=b.n[c],c.m=A,c.bind=a,c.r=m[a]/c.ma):(c=b.f[c-f],c.m=A,c.bind=a,c.r=m[a]*c.va),c.J=0;for(m=1;m<=g;m++)if(c=k[f+m],c<=f){c=b.n[c];c.m=l[m];c.bind=0;switch(l[m]){case G:c.r=c.c;break;case Ua:c.r=c.d;break;case Ra:c.r=0;break;case Na:c.r=c.c}c.J=n[m]*c.ma/h}else{c=b.f[c-f];c.m=l[m];c.bind=0;switch(l[m]){case G:c.r=c.c;break;case Ua:c.r=c.d;break;
case Ra:c.r=0;break;case Na:c.r=c.c}c.J=n[m]/c.va/h}}var L=0.1,v,S=2,M=0,ba=0,J=0,ea,fa,sa;v=function(a){var b=a.g,c=a.i;a=a.L;var d={};d.g=b;d.i=c;d.type=new Int8Array(1+b+c);d.c=new Float64Array(1+b+c);d.d=new Float64Array(1+b+c);d.u=new Float64Array(1+b+c);d.eb=new Float64Array(1+c);d.Ca=new Int32Array(1+c+1);d.Ba=new Int32Array(1+a);d.Ia=new Float64Array(1+a);d.head=new Int32Array(1+b+c);d.m=new Int8Array(1+c);d.De=new Int32Array(1+b+1);d.Kd=new Int32Array(1+b);d.Ce=null;d.Ee=null;d.Ha=new Float64Array(1+
b);d.Qa=new Float64Array(1+c);d.hd=new Int8Array(1+b+c);d.gamma=new Float64Array(1+c);d.yb=new Int32Array(1+b);d.Ua=new Float64Array(1+b);d.Vb=new Int32Array(1+c);d.mb=new Float64Array(1+c);d.jb=new Float64Array(1+b);d.Gc=new Float64Array(1+b);d.Hc=new Float64Array(1+b);d.jg=new Float64Array(1+b);return d}(a);(function(a,b){var c=a.g,d=a.i,e=a.type,f=a.c,g=a.d,k=a.u,l=a.eb,m=a.Ca,n=a.Ba,p=a.Ia,q=a.head,K=a.m,r=a.hd,v=a.gamma,t,u;for(t=1;t<=c;t++)u=b.n[t],e[t]=u.type,f[t]=u.c*u.ma,g[t]=u.d*u.ma,k[t]=
0;for(t=1;t<=d;t++)u=b.f[t],e[c+t]=u.type,f[c+t]=u.c/u.va,g[c+t]=u.d/u.va,k[c+t]=u.u*u.va;l[0]=b.ha;ga(l,1,k,c+1,d);e=0;for(t=1;t<=d;t++)e<Math.abs(l[t])&&(e=Math.abs(l[t]));0==e&&(e=1);switch(b.dir){case za:a.$a=1/e;break;case Ea:a.$a=-1/e}1>Math.abs(a.$a)&&(a.$a*=1E3);for(t=l=1;t<=d;t++)for(m[t]=l,e=b.f[t].k;null!=e;e=e.I)n[l]=e.n.ea,p[l]=e.n.ma*e.j*e.f.va,l++;m[d+1]=l;ga(q,1,b.head,1,c);m=0;for(t=1;t<=c;t++)u=b.n[t],u.m!=A&&(m++,q[c+m]=t,K[m]=u.m);for(t=1;t<=d;t++)u=b.f[t],u.m!=A&&(m++,q[c+m]=
c+t,K[m]=u.m);a.valid=1;b.valid=0;a.U=b.U;b.U=null;q=a.g;K=a.i;m=a.Ca;n=a.Ba;p=a.De;t=a.Kd;for(l=1;l<=q;l++)t[l]=1;for(l=1;l<=K;l++)for(f=m[l],e=m[l+1];f<e;f++)t[n[f]]++;for(l=p[1]=1;l<=q;l++)t[l]>K&&(t[l]=K),p[l+1]=p[l]+t[l];a.Ce=new Int32Array(p[q+1]);a.Ee=new Float64Array(p[q+1]);q=a.g;K=a.i;m=a.head;n=a.m;ha(a.Kd,1,0,q);for(p=1;p<=K;p++)n[p]!=Na&&(t=m[q+p],h(a,p,t));a.D=0;a.hc=ja();a.Sf=a.$=b.$;a.be=-1;a.Rb=0;ha(r,1,0,c+d);for(t=1;t<=d;t++)v[t]=1})(v,a);for(b.o>=mc&&x("Objective scale factor = "+
v.$a+"");;){if(0==S){sa=d(v);if(0!=sa)return b.o>=Lb&&(x("Error: unable to factorize the basis matrix ("+sa+")"),x("Sorry, basis recovery procedure not implemented yet")),a.U=v.U,v.U=null,a.na=a.sa=Aa,a.aa=0,a.$=v.$,a.some=0,sa=Sb;S=v.valid=1;M=ba=0}if(0==M&&(p(v,v.Ha),M=1,0==v.D&&(0<W(v,b.Gb)?v.D=1:(X(v),v.D=2),ba=0,u(v,b,1)),ca(v,b.Gb))){b.o>=Lb&&x("Warning: numerical instability (primal simplex, phase "+(1==v.D?"I":"II")+")");S=v.D=0;J=5;continue}1!=v.D||ka(v,b.Gb)||(v.D=2,X(v),ba=0,u(v,b,1));
0==ba&&(m(v),ba=1);switch(b.fd){case oc:0==v.Rb&&q(v)}if(2147483647>b.oc&&v.$-v.Sf>=b.oc){if(1!=M||2==v.D&&1!=ba){1!=M&&(M=0);2==v.D&&1!=ba&&(ba=0);continue}u(v,b,1);b.o>=Wb&&x("ITERATION LIMIT EXCEEDED; SEARCH TERMINATED");switch(v.D){case 1:ea=Ad;X(v);m(v);break;case 2:ea=dc}r(v,b.tb);fa=0==v.F?dc:Ad;z(v,a,ea,fa,0);return sa=rg}if(2147483647>b.sb&&1E3*la(v.hc)>=b.sb){if(1!=M||2==v.D&&1!=ba){1!=M&&(M=0);2==v.D&&1!=ba&&(ba=0);continue}u(v,b,1);b.o>=Wb&&x("TIME LIMIT EXCEEDED; SEARCH TERMINATED");
switch(v.D){case 1:ea=Ad;X(v);m(v);break;case 2:ea=dc}r(v,b.tb);fa=0==v.F?dc:Ad;z(v,a,ea,fa,0);return sa=Qc}u(v,b,0);r(v,b.tb);if(0==v.F){if(1!=M||1!=ba){1!=M&&(M=0);1!=ba&&(ba=0);continue}u(v,b,1);switch(v.D){case 1:b.o>=Wb&&x("PROBLEM HAS NO FEASIBLE SOLUTION");ea=jc;X(v);m(v);r(v,b.tb);fa=0==v.F?dc:Ad;break;case 2:b.o>=Wb&&x("OPTIMAL SOLUTION FOUND"),ea=fa=dc}z(v,a,ea,fa,0);return sa=0}n(v);J&&t(v);y(v,b.xe);var K=v.Qa[v.F],oa=V(v);if(Math.abs(K-oa)>1E-5*(1+Math.abs(oa))||!(0>K&&0>oa||0<K&&0<oa))if(b.o>=
mc&&x("d1 = "+K+"; d2 = "+oa+""),1!=ba||!J){1!=ba&&(ba=0);J=5;continue}v.Qa[v.F]=0<K?0<oa?oa:2.220446049250313E-16:0>oa?oa:-2.220446049250313E-16;switch(b.ne){case pc:E(v,0);break;case qc:E(v,0.3*b.Gb)}if(0==v.s){if(1!=M||1!=ba||!J){1!=M&&(M=0);1!=ba&&(ba=0);J=1;continue}u(v,b,1);switch(v.D){case 1:b.o>=Lb&&x("Error: unable to choose basic variable on phase I");a.U=v.U;v.U=null;a.na=a.sa=Aa;a.aa=0;a.$=v.$;a.some=0;sa=Sb;break;case 2:b.o>=Wb&&x("PROBLEM HAS UNBOUNDED SOLUTION"),z(v,a,dc,jc,v.head[v.g+
v.F]),sa=0}return sa}if(0<v.s&&(K=v.Ua[v.s],oa=1E-5*(1+0.01*v.rh),Math.abs(K)<oa&&(b.o>=mc&&x("piv = "+K+"; eps = "+oa+""),!J))){J=5;continue}0<v.s&&(K=v.jg,C(v,K),J&&D(v,K),H(v,K));if(0<v.s&&(K=v.Ua[v.s],oa=v.mb[v.F],Math.abs(K-oa)>1E-8*(1+Math.abs(K))||!(0<K&&0<oa||0>K&&0>oa))){b.o>=mc&&x("piv1 = "+K+"; piv2 = "+oa+"");if(1!=S||!J){1!=S&&(S=0);J=5;continue}0==v.mb[v.F]&&(v.Bc++,v.Vb[v.Bc]=v.F);v.mb[v.F]=K}R(v);M=2;0<v.s&&(O(v),ba=2,1==v.D&&(K=v.head[v.s],v.Qa[v.F]-=v.u[K],v.u[K]=0));if(0<v.s)switch(b.fd){case oc:0<
v.Rb&&Q(v)}0<v.s&&(sa=e(v,v.s,v.head[v.g+v.F]),S=0==sa?2:v.valid=0);0<v.s&&(k(v,v.F,v.head[v.g+v.F]),v.type[v.head[v.s]]!=B&&h(v,v.F,v.head[v.s]));F(v);v.$++;0<J&&J--}}
function Rb(a,b){function c(a,b,c,d){var e=a.g,f=a.Ca,g=a.Ba,h=a.Ia;a=a.head[b];if(a<=e)e=1,c[1]=a,d[1]=1;else for(b=f[a-e],e=f[a-e+1]-b,ga(c,1,g,b,e),ga(d,1,h,b,e),c=1;c<=e;c++)d[c]=-d[c];return e}function d(a){var b=od(a.U,a.g,c,a);a.valid=0==b;return b}function e(a,b,c){var d=a.g,e;if(c<=d){var f=Array(2);e=Array(2);f[1]=c;e[1]=1;b=Ne(a.U,b,1,f,0,e)}else{var g=a.Ca,f=a.Ba,h=a.Ia;e=a.jb;var k;k=g[c-d];c=g[c-d+1];g=0;for(d=k;d<c;d++)e[++g]=-h[d];b=Ne(a.U,b,g,f,k-1,e)}a.valid=0==b;return b}function f(a,
b,c){var d=a.g,e=a.jb,f=a.jb,g=a.g,h=a.Ca,k=a.Ba,l=a.Ia,m=a.head,n,p,q;ga(f,1,b,1,g);for(b=1;b<=g;b++)if(q=c[b],0!=q)if(n=m[b],n<=g)f[n]-=q;else for(p=h[n-g],n=h[n-g+1];p<n;p++)f[k[p]]+=l[p]*q;wd(a.U,e);for(a=1;a<=d;a++)c[a]+=e[a]}function g(a,b,c){var d=a.g,e=a.jb,f=a.jb,g=a.g,h=a.Ca,k=a.Ba,l=a.Ia,m=a.head,n,p,q,r;for(n=1;n<=g;n++){p=m[n];r=b[n];if(p<=g)r-=c[p];else for(q=h[p-g],p=h[p-g+1];q<p;q++)r+=l[q]*c[k[q]];f[n]=r}yd(a.U,e);for(a=1;a<=d;a++)c[a]+=e[a]}function h(a,b){var c=a.c,d=a.d,e=a.m,
f,g;f=a.head[a.g+b];switch(e[b]){case G:g=c[f];break;case Ua:g=d[f];break;case Ra:g=0;break;case Na:g=c[f]}return g}function k(a,b){var c=a.g,d=a.i,e=a.Ca,g=a.Ba,k=a.Ia,l=a.head,m=a.Gc,n,p,q,r;for(n=1;n<=c;n++)m[n]=0;for(n=1;n<=d;n++)if(p=l[c+n],r=h(a,n),0!=r)if(p<=c)m[p]-=r;else for(q=e[p-c],p=e[p-c+1];q<p;q++)m[g[q]]+=r*k[q];ga(b,1,m,1,c);wd(a.U,b);f(a,m,b)}function l(a){var b=a.i,c=a.Qa,d=a.Hc,e;e=a.g;var f=a.u,h=a.head,k=a.Gc,l;for(l=1;l<=e;l++)k[l]=f[h[l]];ga(d,1,k,1,e);yd(a.U,d);g(a,k,d);for(e=
1;e<=b;e++){f=a.g;l=a.u;k=h=void 0;h=a.head[f+e];k=l[h];if(h<=f)k-=d[h];else{l=a.Ca;for(var m=a.Ba,n=a.Ia,p=void 0,q=void 0,p=void 0,p=l[h-f],q=l[h-f+1];p<q;p++)k+=n[p]*d[m[p]]}c[e]=k}}function p(a){var b=a.g,c=a.i,d=a.head,e=a.hd,f=a.gamma;a.Rb=1E3;ha(e,1,0,b+c);for(a=1;a<=b;a++)c=d[a],e[c]=1,f[a]=1}function m(a,b){var c=a.g,d=a.type,e=a.c,f=a.d,g=a.head,h=a.Ha,k=a.gamma,l,m,n,p,q,r,t;q=p=n=0;for(l=1;l<=c;l++){m=g[l];t=0;if(d[m]==Sa||d[m]==I||d[m]==B)r=b*(1+P*Math.abs(e[m])),h[l]<e[m]-r&&(t=e[m]-
h[l]);if(d[m]==Ta||d[m]==I||d[m]==B)r=b*(1+P*Math.abs(f[m])),h[l]>f[m]+r&&(t=f[m]-h[l]);0!=t&&(m=k[l],2.220446049250313E-16>m&&(m=2.220446049250313E-16),m=t*t/m,q<m&&(n=l,p=t,q=m))}a.s=n;a.Se=p}function q(a,b){var c=a.g,d=a.s,e;for(e=1;e<=c;e++)b[e]=0;b[d]=1;yd(a.U,ea)}function r(a,b){var c=a.g,d=a.s,e=a.Hc,f;for(f=1;f<=c;f++)e[f]=0;e[d]=1;g(a,e,b)}function n(a,b){var c=a.g,d,e;e=0;for(d=1;d<=c;d++)0!=b[d]&&e++;if(0.2<=e/c){c=a.g;d=a.i;e=a.Ca;var f=a.Ba,g=a.Ia,h=a.head,k=a.m,l=a.Vb,m=a.mb,n,p,q,r,
t;r=0;for(n=1;n<=d;n++)if(k[n]==Na)m[n]=0;else{p=h[c+n];if(p<=c)t=-b[p];else for(q=e[p-c],p=e[p-c+1],t=0;q<p;q++)t+=b[f[q]]*g[q];0!=t&&(l[++r]=n);m[n]=t}a.Bc=r}else{f=a.g;c=a.i;g=a.lg;h=a.kg;k=a.mg;l=a.bind;m=a.m;d=a.Vb;e=a.mb;for(r=1;r<=c;r++)e[r]=0;for(n=1;n<=f;n++)if(p=b[n],0!=p)for(r=l[n]-f,1<=r&&m[r]!=Na&&(e[r]-=p),r=g[n],q=g[n+1],t=r;t<q;t++)r=l[f+h[t]]-f,1<=r&&m[r]!=Na&&(e[r]+=p*k[t]);f=0;for(r=1;r<=c;r++)0!=e[r]&&(d[++f]=r);a.Bc=f}}function t(a,b){var c=a.Bc,d=a.Vb,e=a.mb,f,g,h;g=0;for(f=
1;f<=c;f++)h=Math.abs(e[d[f]]),g<h&&(g=h);a.uh=g;h=b*(1+0.01*g);for(g=0;g<c;)f=d[c],Math.abs(e[f])<h?c--:(g++,d[c]=d[g],d[g]=f);a.vh=g}function y(a,b){var c=a.m,d=a.Qa,e=a.Vb,f=a.mb,g=a.vh,h,k,l,m,n,p,q,r,t;p=0<a.Se?1:-1;l=0;r=s;n=0;for(k=1;k<=g;k++){h=e[k];m=p*f[h];if(0<m)if(c[h]==G||c[h]==Ra)q=(d[h]+b)/m;else continue;else if(c[h]==Ua||c[h]==Ra)q=(d[h]-b)/m;else continue;0>q&&(q=0);if(r>q||r==q&&n<Math.abs(m))l=h,r=q,n=Math.abs(m)}if(0!=b&&0!=l&&0!=r)for(t=r,l=0,r=s,n=0,k=1;k<=g;k++){h=e[k];m=p*
f[h];if(0<m)if(c[h]==G||c[h]==Ra)q=d[h]/m;else continue;else if(c[h]==Ua||c[h]==Ra)q=d[h]/m;else continue;0>q&&(q=0);q<=t&&n<Math.abs(m)&&(l=h,r=q,n=Math.abs(m))}a.F=l;a.bh=p*r}function E(a){var b=a.g,c=a.yb,d=a.Ua,e=a.Ua,f,g;g=a.head[b+a.F];for(f=1;f<=b;f++)e[f]=0;if(g<=b)e[g]=-1;else{var h=a.Ca;f=a.Ba;var k=a.Ia,l;l=h[g-b];for(g=h[g-b+1];l<g;l++)e[f[l]]=k[l]}wd(a.U,d);e=0;for(f=1;f<=b;f++)0!=d[f]&&(c[++e]=f);a.Tb=e}function C(a){var b=a.g,c=a.yb,d=a.Ua,e=a.Hc,g,h;h=a.head[b+a.F];for(g=1;g<=b;g++)e[g]=
0;if(h<=b)e[h]=-1;else{var k=a.Ca;g=a.Ba;var l=a.Ia,m;m=k[h-b];for(h=k[h-b+1];m<h;m++)e[g[m]]=l[m]}f(a,e,d);e=0;for(g=1;g<=b;g++)0!=d[g]&&(c[++e]=g);a.Tb=e}function D(a){var b=a.Qa,c=a.Bc,d=a.Vb,e=a.mb,f=a.F;a=a.bh;var g,h;b[f]=a;if(0!=a)for(h=1;h<=c;h++)g=d[h],g!=f&&(b[g]-=e[g]*a)}function H(a){var b=a.Ha,c=a.s,d=a.F,e=a.Tb,f=a.yb,g=a.Ua,k;k=a.Se/g[c];b[c]=h(a,d)+k;if(0!=k)for(d=1;d<=e;d++)a=f[d],a!=c&&(b[a]+=g[a]*k)}function R(a){var b=a.g,c=a.type,d=a.head,e=a.hd,f=a.gamma,g=a.s,h=a.Bc,k=a.Vb,
l=a.mb,m=a.F,n=a.Tb,p=a.yb,q=a.Ua,r=a.Hc,t,u,v,y,z,C;a.Rb--;z=C=e[d[g]]?1:0;for(t=1;t<=b;t++)r[t]=0;for(y=1;y<=h;y++)if(u=k[y],v=d[b+u],e[v])if(u=l[u],z+=u*u,v<=b)r[v]+=u;else{var D=a.Ca;t=a.Ba;var F=a.Ia,E;E=D[v-b];for(v=D[v-b+1];E<v;E++)r[t[E]]-=u*F[E]}wd(a.U,r);a=q[g];for(y=1;y<=n;y++)t=p[y],v=d[t],t!=g&&c[d[t]]!=Ka&&(u=q[t]/a,h=f[t]+u*u*z+2*u*r[t],u=(e[v]?1:0)+C*u*u,f[t]=h>=u?h:u,2.220446049250313E-16>f[t]&&(f[t]=2.220446049250313E-16));c[d[b+m]]==Ka?f[g]=1:(f[g]=z/(a*a),2.220446049250313E-16>
f[g]&&(f[g]=2.220446049250313E-16));v=d[g];if(c[v]==B&&e[v])for(e[v]=0,y=1;y<=n;y++){t=p[y];if(t==g){if(c[d[b+m]]==Ka)continue;u=1/q[g]}else{if(c[d[t]]==Ka)continue;u=q[t]/q[g]}f[t]-=u*u;2.220446049250313E-16>f[t]&&(f[t]=2.220446049250313E-16)}}function V(a){var b=a.g,c=a.type,d=a.head,e=a.bind,f=a.m,g=a.s,h=a.Se;a=a.F;var k;k=d[g];d[g]=d[b+a];d[b+a]=k;e[d[g]]=g;e[d[b+a]]=b+a;f[a]=c[k]==B?Na:0<h?G:Ua}function O(a,b){var c=a.g,d=a.i,e=a.ac,f=a.head,g=a.Qa,h,k;for(h=1;h<=d;h++)if(k=f[c+h],g[h]<-b&&
(e[k]==Sa||e[k]==Ka)||g[h]>+b&&(e[k]==Ta||e[k]==Ka))return 1;return 0}function Q(a){var b=a.g,c=a.i,d=a.type,e=a.c,f=a.d,g=a.ac,h=a.head,k=a.m;a=a.Qa;var l;for(l=1;l<=b+c;l++)switch(g[l]){case Ka:d[l]=I;e[l]=-1E3;f[l]=1E3;break;case Sa:d[l]=I;e[l]=0;f[l]=1;break;case Ta:d[l]=I;e[l]=-1;f[l]=0;break;case I:case B:d[l]=B,e[l]=f[l]=0}for(e=1;e<=c;e++)l=h[b+e],k[e]=d[l]==B?Na:0<=a[e]?G:Ua}function F(a){var b=a.g,c=a.i,d=a.type,e=a.c,f=a.d,g=a.bd,h=a.cd,k=a.head,l=a.m,m=a.Qa;ga(d,1,a.ac,1,b+c);ga(e,1,g,
1,b+c);ga(f,1,h,1,b+c);for(a=1;a<=c;a++)switch(g=k[b+a],d[g]){case Ka:l[a]=Ra;break;case Sa:l[a]=G;break;case Ta:l[a]=Ua;break;case I:l[a]=2.220446049250313E-16<=m[a]?G:-2.220446049250313E-16>=m[a]?Ua:Math.abs(e[g])<=Math.abs(f[g])?G:Ua;break;case B:l[a]=Na}}function W(a,b){var c=a.i,d=a.m,e=a.Qa,f;for(f=1;f<=c;f++)if(e[f]<-b&&(d[f]==G||d[f]==Ra)||e[f]>+b&&(d[f]==Ua||d[f]==Ra))return 1;return 0}function X(a){var b=a.g,c=a.i,d=a.eb,e=a.head,f=a.Ha,g,k,l;l=d[0];for(g=1;g<=b;g++)k=e[g],k>b&&(l+=d[k-
b]*f[g]);for(f=1;f<=c;f++)k=e[b+f],k>b&&(l+=d[k-b]*h(a,f));return l}function ca(a,b,c){var d=a.g,e=a.i,f=a.u,g=a.ac,k=a.head,l=a.m,m=a.D,n=a.Ha,p=a.Qa;if(!(b.o<fc||0<b.fb&&1E3*la(a.hc)<b.fb||a.$==a.be||!c&&0!=a.$%b.bc)){b=0;if(1==m){for(l=1;l<=d;l++)b-=f[k[l]]*n[l];for(n=1;n<=e;n++)b-=f[k[d+n]]*h(a,n)}else for(n=1;n<=e;n++)0>p[n]&&(l[n]==G||l[n]==Ra)&&(b-=p[n]),0<p[n]&&(l[n]==Ua||l[n]==Ra)&&(b+=p[n]);e=0;for(l=1;l<=d;l++)g[k[l]]==B&&e++;1==a.D?x(" "+a.$+": infeas = "+b+" ("+e+")"):x("|"+a.$+": obj = "+
X(a)+" infeas = "+b+" ("+e+")");a.be=a.$}}function ka(a,b,c,d,e){var f=a.g,g=a.i,h=a.$a,k=a.head,l=a.m,m=a.Ha,n=a.Qa;b.valid=1;a.valid=0;b.U=a.U;a.U=null;ga(b.head,1,k,1,f);b.na=c;b.sa=d;b.aa=X(a);b.$=a.$;b.some=e;for(a=1;a<=f;a++)c=k[a],c<=f?(c=b.n[c],c.m=A,c.bind=a,c.r=m[a]/c.ma):(c=b.f[c-f],c.m=A,c.bind=a,c.r=m[a]*c.va),c.J=0;for(m=1;m<=g;m++)if(c=k[f+m],c<=f){c=b.n[c];c.m=l[m];c.bind=0;switch(l[m]){case G:c.r=c.c;break;case Ua:c.r=c.d;break;case Ra:c.r=0;break;case Na:c.r=c.c}c.J=n[m]*c.ma/h}else{c=
b.f[c-f];c.m=l[m];c.bind=0;switch(l[m]){case G:c.r=c.c;break;case Ua:c.r=c.d;break;case Ra:c.r=0;break;case Na:c.r=c.c}c.J=n[m]/c.va/h}}var P=0.1,u,z=2,L=0,v=0,S=0,M,ba,J;u=function(a){var b=a.g,c=a.i;a=a.L;var d={};d.g=b;d.i=c;d.type=new Int8Array(1+b+c);d.c=new Float64Array(1+b+c);d.d=new Float64Array(1+b+c);d.u=new Float64Array(1+b+c);d.ac=new Int8Array(1+b+c);d.bd=new Float64Array(1+b+c);d.cd=new Float64Array(1+b+c);d.eb=new Float64Array(1+c);d.Ca=new Int32Array(1+c+1);d.Ba=new Int32Array(1+a);
d.Ia=new Float64Array(1+a);d.lg=new Int32Array(1+b+1);d.kg=new Int32Array(1+a);d.mg=new Float64Array(1+a);d.head=new Int32Array(1+b+c);d.bind=new Int32Array(1+b+c);d.m=new Int8Array(1+c);d.Ha=new Float64Array(1+b);d.Qa=new Float64Array(1+c);d.hd=new Int8Array(1+b+c);d.gamma=new Float64Array(1+b);d.Vb=new Int32Array(1+c);d.mb=new Float64Array(1+c);d.yb=new Int32Array(1+b);d.Ua=new Float64Array(1+b);d.jb=new Float64Array(1+b);d.Gc=new Float64Array(1+b);d.Hc=new Float64Array(1+b);d.jg=new Float64Array(1+
b);return d}(a);(function(a,b){var c=a.g,d=a.i,e=a.type,f=a.c,g=a.d,h=a.u,k=a.ac,l=a.bd,m=a.cd,n=a.eb,p=a.Ca,q=a.Ba,r=a.Ia,t=a.lg,u=a.kg,v=a.mg,y=a.head,z=a.bind,C=a.m,D=a.hd,F=a.gamma,E,H;for(E=1;E<=c;E++)H=b.n[E],e[E]=H.type,f[E]=H.c*H.ma,g[E]=H.d*H.ma,h[E]=0;for(E=1;E<=d;E++)H=b.f[E],e[c+E]=H.type,f[c+E]=H.c/H.va,g[c+E]=H.d/H.va,h[c+E]=H.u*H.va;ga(k,1,e,1,c+d);ga(l,1,f,1,c+d);ga(m,1,g,1,c+d);n[0]=b.ha;ga(n,1,h,c+1,d);e=0;for(E=1;E<=d;E++)e<Math.abs(n[E])&&(e=Math.abs(n[E]));0==e&&(e=1);switch(b.dir){case za:a.$a=
1/e;break;case Ea:a.$a=-1/e}1>Math.abs(a.$a)&&(a.$a*=1E3);for(E=1;E<=d;E++)h[c+E]*=a.$a;for(E=h=1;E<=d;E++)for(p[E]=h,n=b.f[E].k;null!=n;n=n.I)q[h]=n.n.ea,r[h]=n.n.ma*n.j*n.f.va,h++;p[d+1]=h;for(E=h=1;E<=c;E++)for(t[E]=h,n=b.n[E].k;null!=n;n=n.B)u[h]=n.f.C,v[h]=n.n.ma*n.j*n.f.va,h++;t[c+1]=h;ga(y,1,b.head,1,c);p=0;for(E=1;E<=c;E++)H=b.n[E],H.m!=A&&(p++,y[c+p]=E,C[p]=H.m);for(E=1;E<=d;E++)H=b.f[E],H.m!=A&&(p++,y[c+p]=c+E,C[p]=H.m);for(p=1;p<=c+d;p++)z[y[p]]=p;a.valid=1;b.valid=0;a.U=b.U;b.U=null;a.D=
0;a.hc=ja();a.Sf=a.$=b.$;a.be=-1;a.Rb=0;ha(D,1,0,c+d);for(E=1;E<=c;E++)F[E]=1})(u,a);for(b.o>=mc&&x("Objective scale factor = "+u.$a+"");;){if(0==z){J=d(u);if(0!=J)return b.o>=Lb&&(x("Error: unable to factorize the basis matrix ("+J+")"),x("Sorry, basis recovery procedure not implemented yet")),a.U=u.U,u.U=null,a.na=a.sa=Aa,a.aa=0,a.$=u.$,a.some=0,J=Sb;z=u.valid=1;L=v=0}if(0==v&&(l(u),v=1,0==u.D&&(0!=O(u,0.9*b.tb)?(u.D=1,Q(u)):(u.D=2,F(u)),L=u.Rb=0),0!=W(u,b.tb))){b.o>=Lb&&x("Warning: numerical instability (dual simplex, phase "+
(1==u.D?"I":"II")+")");if(b.cb==Qb)return ka(u,a,Aa,Aa,0),J=Sb;z=u.D=0;S=5;continue}1==u.D&&0==O(u,b.tb)&&(ca(u,b,1),u.D=2,1!=v&&(l(u),v=1),F(u),L=u.Rb=0);0==L&&(k(u,u.Ha),2==u.D&&(u.Ha[0]=X(u)),L=1);switch(b.fd){case oc:0==u.Rb&&p(u)}if(2==u.D&&0>u.$a&&b.hf>-s&&u.Ha[0]<=b.hf){if(1!=L||1!=v){1!=L&&(L=0);1!=v&&(v=0);continue}ca(u,b,1);b.o>=Wb&&x("OBJECTIVE LOWER LIMIT REACHED; SEARCH TERMINATED");ka(u,a,Ad,dc,0);return J=Vf}if(2==u.D&&0<u.$a&&b.jf<+s&&u.Ha[0]>=b.jf){if(1!=L||1!=v){1!=L&&(L=0);1!=v&&
(v=0);continue}ca(u,b,1);b.o>=Wb&&x("OBJECTIVE UPPER LIMIT REACHED; SEARCH TERMINATED");ka(u,a,Ad,dc,0);return J=Wf}if(2147483647>b.oc&&u.$-u.Sf>=b.oc){if(2==u.D&&1!=L||1!=v){2==u.D&&1!=L&&(L=0);1!=v&&(v=0);continue}ca(u,b,1);b.o>=Wb&&x("ITERATION LIMIT EXCEEDED; SEARCH TERMINATED");switch(u.D){case 1:ba=Ad;F(u);k(u,u.Ha);break;case 2:ba=dc}ka(u,a,Ad,ba,0);return J=rg}if(2147483647>b.sb&&1E3*la(u.hc)>=b.sb){if(2==u.D&&1!=L||1!=v){2==u.D&&1!=L&&(L=0);1!=v&&(v=0);continue}ca(u,b,1);b.o>=Wb&&x("TIME LIMIT EXCEEDED; SEARCH TERMINATED");
switch(u.D){case 1:ba=Ad;F(u);k(u,u.Ha);break;case 2:ba=dc}ka(u,a,Ad,ba,0);return J=Qc}ca(u,b,0);m(u,b.Gb);if(0==u.s){if(1!=L||1!=v){1!=L&&(L=0);1!=v&&(v=0);continue}ca(u,b,1);switch(u.D){case 1:b.o>=Wb&&x("PROBLEM HAS NO DUAL FEASIBLE SOLUTION");F(u);k(u,u.Ha);M=Ad;ba=jc;break;case 2:b.o>=Wb&&x("OPTIMAL SOLUTION FOUND"),M=ba=dc}ka(u,a,M,ba,0);return J=0}var ea=u.jg;q(u,ea);S&&r(u,ea);n(u,ea);t(u,b.Gb);switch(b.ne){case pc:y(u,0);break;case qc:y(u,0.3*b.tb)}if(0==u.F){if(1!=L||1!=v||!S){1!=L&&(L=
0);1!=v&&(v=0);S=1;continue}ca(u,b,1);switch(u.D){case 1:b.o>=Lb&&x("Error: unable to choose basic variable on phase I");a.U=u.U;u.U=null;a.na=a.sa=Aa;a.aa=0;a.$=u.$;a.some=0;J=Sb;break;case 2:b.o>=Wb&&x("PROBLEM HAS NO FEASIBLE SOLUTION"),ka(u,a,jc,dc,u.head[u.s]),J=0}return J}var fa=u.mb[u.F],sa=1E-5*(1+0.01*u.uh);if(Math.abs(fa)<sa&&(b.o>=mc&&x("piv = "+fa+"; eps = "+sa+""),!S)){S=5;continue}E(u);S&&C(u);fa=u.Ua[u.s];sa=u.mb[u.F];if(Math.abs(fa-sa)>1E-8*(1+Math.abs(fa))||!(0<fa&&0<sa||0>fa&&0>
sa)){b.o>=mc&&x("piv1 = "+fa+"; piv2 = "+sa+"");if(1!=z||!S){1!=z&&(z=0);S=5;continue}0==u.Ua[u.s]&&(u.Tb++,u.yb[u.Tb]=u.s);u.Ua[u.s]=sa}H(u);2==u.D&&(u.Ha[0]+=u.Qa[u.F]/u.$a*(u.Se/u.Ua[u.s]));L=2;D(u);v=2;switch(b.fd){case oc:0<u.Rb&&R(u)}J=e(u,u.s,u.head[u.g+u.F]);z=0==J?2:u.valid=0;V(u);u.$++;0<S&&S--}};
}(typeof exports === 'object' && exports || this));
/**
* Number of combinations of k items among n
* @param{number}
* @param{number}
* @return{number}
*/
function nchoosek(n,k) {
if ( k > n || k < 0 || n < 0)
return 0;
var i;
var res = 1;
for ( i=n-k+1; i <= n; i++)
res *= i;
for (i=2; i <= k; i++)
res /= i;
return res;
}
//////////////////////////////////////////////
// Multivariate Gaussian random vectors
//////////////////////////////////////////////
function mvnrnd(mu, Sigma, N) {
if ( arguments.length < 3 )
var N = 1;
var X = randn(N,mu.length);
if ( issymmetric(Sigma) )
var L = chol(Sigma);
else
var L = Sigma; // L directly provided instead of Sigma
return add(mul(ones(N),transpose(mu)), mul(X, transpose(L) ));
}
//////////////////////////////////////////////
// Generic class for Distributions
/////////////////////////////////////////////
function Distribution (distrib, arg1, arg2 ) {
if ( arguments.length < 1 ) {
error("Error in new Distribution(name): name is undefined.");
return undefined;
}
if (typeof(distrib) == "string")
distrib = eval(distrib);
this.type = "Distribution:" + distrib.name;
this.distribution = distrib.name;
// Functions that depend on the distrib:
this.construct = distrib.prototype.construct;
this.estimate = distrib.prototype.estimate;
this.sample = distrib.prototype.sample;
this.pdf = distrib.prototype.pdf;
if( distrib.prototype.pmf )
this.pmf = distrib.prototype.pmf;
if( distrib.prototype.logpdf )
this.logpdf = distrib.prototype.logpdf;
else
this.logpdf = function ( x ) { return log(this.pdf(x)); };
// this.cdf = distrib.prototype.cdf;
// Initialization depending on distrib
this.construct(arg1, arg2);
}
Distribution.prototype.construct = function ( params ) {
// Read params and create the required fields for a specific algorithm
}
Distribution.prototype.pdf = function ( x ) {
// return value of PDF at x
}
Distribution.prototype.sample = function ( N ) {
// Return N samples
}
Distribution.prototype.estimate = function ( X ) {
// Estimate dsitribution from the N-by-d matrix X
// !! this function should also update this.mean and this.variance
}
Distribution.prototype.info = function () {
// Print information about the distribution
var str = "{<br>";
var i;
var Functions = new Array();
for ( i in this) {
switch ( type( this[i] ) ) {
case "string":
case "boolean":
case "number":
str += i + ": " + this[i] + "<br>";
break;
case "vector":
str += i + ": " + printVector(this[i]) + "<br>";
break;
case "matrix":
str += i + ": matrix of size " + this[i].m + "-by-" + this[i].n + "<br>";
break;
case "function":
Functions.push( i );
break;
default:
str += i + ": " + typeof(this[i]) + "<br>";
break;
}
}
str += "<i>Functions: " + Functions.join(", ") + "</i><br>";
str += "}";
return str;
}
///////////////////////////////
/// Uniform
///////////////////////////////
function Uniform ( params ) {
var that = new Distribution ( Uniform, params ) ;
return that;
}
Uniform.prototype.construct = function ( a, b ) {
// Read params and create the required fields for a Uniform distribution
if ( typeof(a) == "undefined" ) {
// default to continuous uniform in [-1,1];
this.isDiscrete = false;
this.a = -1;
this.b = 1;
this.dimension = 1;
this.px = 0.5;
this.mean = 0;
this.variance = 1/3;
this.std = Math.sqrt(this.variance);
}
else {
if ( typeof(b) == "undefined" ) {
this.isDiscrete = true;
if ( typeof(a) == "number")
this.values = range(a);
else
this.values = a;
this.dimension = 1;
this.mean = ( min(this.values) + max(this.values) ) / 2;
this.variance = (this.values.length * this.values.length - 1 ) / 12;
this.std = Math.sqrt(this.variance);
}
else {
this.isDiscrete = false;
this.a = a;
this.b = b;
this.dimension = size(a,1);
this.px = 1 / prod(sub(b,a));
this.mean = mul(0.5, add(a, b));
var b_a = sub(b,a);
this.variance = entrywisediv( entrywisemul(b_a,b_a), 12);
this.std = sqrt(this.variance);
}
}
}
Uniform.prototype.pdf = function ( x ) {
// return value of PDF at x
const tx = type(x);
var p = undefined;
if (this.isDiscrete) {
var pdfscalar = function ( s, values ) {
return ( values.indexOf(s) < 0 ) ? 0 : (1/values.length) ;
};
if ( tx == "number" ) {
p = pdfscalar(x, this.values);
}
else if ( tx == "vector" ) {
p = zeros(x.length);
for ( var i=0; i < x.length; i++)
p[i] = pdfscalar(x[i], this.values);
}
else if ( tx == "matrix" ) {
p = zeros(x.m, x.n);
for ( var i=0; i < x.m*x.n; i++)
p.val[i] = pdfscalar(x.val[i], this.values);
}
}
else {
var pdfscalar = function ( s , l, u, px) {
return ( s >= l && s <= u ) ? px : 0;
};
if ( tx == "number" ) {
if ( this.dimension == 1 )
p = pdfscalar(x, this.a, this.b, this.px);
}
else if ( tx == "vector" ) {
if ( this.dimension == 1 ) {
p = zeros(x.length);
for ( var i=0; i < x.length; i++)
p[i] = pdfscalar(x[i], this.a, this.b, this.px);
}
else if ( this.dimension == x.length ) {
p = pdfscalar(x[0], this.a[0], this.b[0], this.px);
var k = 1;
while ( k < x.length && p != 0 ) {
p *= pdfscalar(x[k], this.a[k], this.b[k], this.px);
k++;
}
}
}
else if ( tx == "matrix" ) {
if ( this.dimension == 1 ) {
p = zeros(x.m, x.n);
for ( var i=0; i < x.m*x.n; i++)
p.val[i] = pdfscalar(x.val[i], this.a, this.b, this.px);
}
else if ( this.dimension == x.n ) {
p = zeros(x.m);
for ( var i=0; i < x.m; i++) {
p[i] = pdfscalar(x.val[i*x.n], this.a[0], this.b[0], this.px);
var k = 1;
while ( k < x.n && p[i] != 0 ) {
p[i] *= pdfscalar(x.val[i*x.n+k], this.a[k], this.b[k], this.px);
k++;
}
}
}
}
}
return p;
}
Uniform.prototype.sample = function ( N ) {
// Return N samples
if ( typeof(N) == "undefined" )
var N = 1;
if ( this.isDiscrete ) {
var s = zeros(N);
for(var i=0; i < N; i++) {
var r = Math.random();
var k = 1;
var n = this.values.length;
while ( r > k / n )
k++;
s[i] = this.values[k-1];
}
if ( N == 1)
return s[0];
else
return s;
}
else {
if ( this.dimension == 1 )
return add(entrywisemul(this.b-this.a, rand(N)), this.a);
else {
return add(entrywisemul(outerprod(ones(N), sub(this.b,this.a)), rand(N, this.dimension)), outerprod(ones(N),this.a) );
}
}
}
Uniform.prototype.estimate = function ( X ) {
// Estimate dsitribution from the N-by-d matrix X
const tX = type(X);
// Detect if X contains discrete or continuous values
if ( tX == "matrix" )
var x = X.val;
else
var x = X;
var i = 0;
while ( i < x.length && Math.round(x[i]) == x[i] )
i++;
if ( i < x.length )
this.isDiscrete = false;
else
this.isDiscrete = true;
// Estimate
if ( this.isDiscrete) {
for ( i = 0; i < x.length; i++ ) {
var xi = Math.round(x[i]);
if ( this.values.indexOf(xi) < 0 )
this.values.push(xi);
}
this.dimension = 1;
this.mean = ( min(this.values) + max(this.values) ) / 2;
this.variance = (this.values.length * this.values.length - 1 ) / 12;
this.std = Math.sqrt(this.variance);
}
else {
if ( tX == "matrix" ) {
this.a = min(X,1).val;
this.b = max(X).val;
this.dimension = this.a.length;
}
else {
this.a = minVector(X);
this.b = maxVector(X);
this.dimension = 1;
}
this.mean = mul(0.5, add(this.a, this.b));
var b_a = sub(this.b,this.a);
this.variance = entrywisediv( entrywisemul(b_a,b_a), 12);
this.std = sqrt(this.variance);
this.px = 1 / prod(sub(this.b,this.a));
}
return this;
}
///////////////////////////////
/// Gaussian
/// (with independent components in multiple dimension)
///////////////////////////////
function Gaussian ( params ) {
var that = new Distribution ( Gaussian, params ) ;
return that;
}
Gaussian.prototype.construct = function ( mean, variance ) {
// Read params and create the required fields for a specific algorithm
if ( typeof(mean) == "undefined" )
var mu = 1;
else if ( type(mean) == "matrix")
var mu = mean.val;
else
var mu = mean;
var dim = size(mu,1) ;
if ( typeof(variance) == "undefined") {
if ( dim == 1)
var variance = 1;
else
var variance = ones(dim);
}
this.mean = mu;
this.variance = variance;
this.std = sqrt(this.variance);
this.dimension = dim;
}
Gaussian.prototype.pdf = function ( x ) {
// return value of PDF at x
if ( this.dimension == 1 ) {
if ( typeof(x) == "number") {
var diff = x - this.mean;
return Math.exp(-diff*diff / (2*this.variance)) / (this.std * Math.sqrt(2*Math.PI) );
}
else {
var diff = sub(x, this.mean);
return entrywisediv ( exp( entrywisediv(entrywisemul( diff, diff), -2* this.variance) ), this.std * Math.sqrt(2*Math.PI) ) ;
}
}
else {
if ( type(x) == "vector") {
if (x.length != this.dimension ) {
error ( "Error in Gaussian.pdf(x): x.length = " + x.length + " != " + this.dimension + " = Gaussian.dimension.");
return undefined;
}
var diff = subVectors(x, this.mean );
var u = -0.5 * dot( diff, divVectors(diff, this.variance) );
return Math.exp(u) / ( Math.pow(2*Math.PI, 0.5*this.dimension) * Math.sqrt(prodVector(this.variance)) );
}
else {
if (x.n != this.dimension ) {
error ( "Error in Gaussian.pdf(X): X.n = " + x.n + " != " + this.dimension + " = Gaussian.dimension.");
return undefined;
}
var p = zeros(x.m);
var denominator = Math.pow(2*Math.PI, 0.5*this.dimension) * Math.sqrt(prodVector(this.variance)) ;
for ( var i=0; i < x.m; i++) {
var diff = subVectors(x.row(i), this.mean );
var u = -0.5 * dot( diff, divVectors(diff, this.variance) );
p[i] = Math.exp(u) / denominator;
}
return p;
}
}
}
Gaussian.prototype.sample = function ( N ) {
// Return N samples
if ( typeof(N) == "undefined")
var N = 1;
if ( N == 1 )
var X = add(entrywisemul(this.std, randn(this.dimension)), this.mean);
else {
var N1 = ones(N);
var X = add(entrywisemul(outerprod(N1, this.std), randn(N,this.dimension)), outerprod(N1,this.mean));
}
return X;
}
Gaussian.prototype.estimate = function ( X ) {
// Estimate dsitribution from the N-by-d matrix X
if ( type ( X ) == "matrix" ) {
this.mean = mean(X,1).val;
this.variance = variance(X,1).val;
this.std = undefined;
this.dimension = X.n;
}
else {
this.mean = mean(X);
this.variance = variance(X);
this.std = Math.sqrt(this.variance);
this.dimension = 1;
}
return this;
}
///////////////////////////////
/// Gaussian
/// (with independent components in multiple dimension)
///////////////////////////////
function mvGaussian ( params ) {
var that = new Distribution ( mvGaussian, params ) ;
return that;
}
mvGaussian.prototype.construct = function ( mean, covariance ) {
// Read params and create the required fields for a specific algorithm
if ( typeof(mean) == "undefined" )
var mu = 1;
else if ( type(mean) == "matrix")
var mu = mean.val;
else
var mu = mean;
var dim = size(mu,1) ;
if ( typeof(covariance) == "undefined") {
if ( dim == 1)
var covariance = 1;
else
var covariance = eye(dim);
}
this.mean = mu;
this.variance = covariance;
this.dimension = dim;
this.L = chol(this.variance);
if ( typeof(this.L) == "undefined" )
error("Error in new Distribution (mvGaussian, mu, Sigma): Sigma is not positive definite");
this.det = det(this.variance);
}
mvGaussian.prototype.pdf = function ( x ) {
// return value of PDF at x
if ( this.dimension == 1 ) {
if ( typeof(x) == "number") {
var diff = x - this.mean;
return Math.exp(-diff*diff / (2*this.variance)) / (Math.sqrt(2*this.variance*Math.PI) );
}
else {
var diff = sub(x, this.mean);
return entrywisediv ( exp( entrywisediv(entrywisemul( diff, diff), -2* this.variance) ), Math.sqrt(2*this.variance*Math.PI) ) ;
}
}
else {
if ( type(x) == "vector") {
if (x.length != this.dimension ) {
error ( "Error in mvGaussian.pdf(x): x.length = " + x.length + " != " + this.dimension + " = mvGaussian.dimension.");
return undefined;
}
var diff = subVectors(x, this.mean );
var u = -0.5 * dot( diff, cholsolve(this.L, diff) );
return Math.exp(u) / Math.sqrt( Math.pow(2*Math.PI, this.dimension) * this.det ) ;
}
else {
if (x.n != this.dimension ) {
error ( "Error in Gaussian.pdf(X): X.n = " + x.n + " != " + this.dimension + " = Gaussian.dimension.");
return undefined;
}
var p = zeros(x.m);
var denominator = Math.sqrt( Math.pow(2*Math.PI, this.dimension) * this.det ) ;
for ( var i=0; i < x.m; i++) {
var diff = subVectors(x.row(i), this.mean );
var u = -0.5 * dot( diff, cholsolve(this.L, diff) );
p[i] = Math.exp(u) / denominator;
}
return p;
}
}
}
mvGaussian.prototype.sample = function ( N ) {
// Return N samples
if ( typeof(N) == "undefined")
var N = 1;
var X = add(mul(randn(N,this.dimension), transpose(this.L)), outerprod(ones(N),this.mean));
if ( N == 1)
return X.val;
else
return X;
}
mvGaussian.prototype.estimate = function ( X ) {
// Estimate dsitribution from the N-by-d matrix X
if ( type ( X ) == "matrix" ) {
this.mean = mean(X,1).val;
this.variance = cov(X);
this.dimension = X.n;
this.L = chol(this.variance);
if ( typeof(this.L) == "undefined" )
error("Error in mvGaussian.estimate(X): covariance estimate is not positive definite");
this.det = det(this.variance);
return this;
}
else {
error("mvGaussian.estimate( X ) needs a matrix X");
}
}
///////////////////////////////
/// Bernoulli
///////////////////////////////
function Bernoulli ( params ) {
var that = new Distribution ( Bernoulli, params ) ;
return that;
}
Bernoulli.prototype.construct = function ( mean ) {
// Read params and create the required fields for a specific algorithm
if ( typeof(mean) == "undefined" )
var mean = 0.5;
var dim = size(mean,1);
this.mean = mean;
this.variance = entrywisemul(mean, sub(1, mean)) ;
this.std = sqrt(this.variance);
this.dimension = dim;
}
Bernoulli.prototype.pdf = Bernoulli.prototype.pmf = function ( x ) {
// return value of PDF at x
const tx = type(x);
var pdfscalar = function ( s, mu ) {
if ( s == 1 )
return mu;
else if ( s == 0)
return (1-mu);
else
return 0;
};
if ( this.dimension == 1 ) {
if ( tx == "number" ) {
return pdfscalar(x, this.mean);
}
else if ( tx == "vector") {
var p = zeros(x.length);
for(var i = 0; i < x.length ; i++){
p[i] = pdfscalar(x[i], this.mean);
}
return p;
}
else if ( tx == "matrix") {
var P = zeros(x.m, x.n);
var mn = x.m*x.n;
for(var k = 0; k < mn ; k++){
P.val[k] = pdfscalar(x.val[k], this.mean);
}
return P;
}
}
else {
switch( tx ) {
case "vector":
var p = pdfscalar(x[0], this.mean[0]);
for (var k = 1; k < this.dimension; k++)
p *= pdfscalar(x[k], this.mean[k]);
break;
case "spvector":
var p = 1;
for (var j=0; j < x.ind[0] ; j++)
p *= (1-this.mean[j]);
for (var k =0; k < x.val.length - 1; k++) {
p *= this.mean[x.ind[k]];
for (var j=x.ind[k]+1; j < x.ind[k+1] ; j++)
p *= (1-this.mean[j]);
}
p *= this.mean[x.ind[k]];
for (var j=x.ind[k]+1; j < this.dimension ; j++)
p *= (1-this.mean[j]);
break;
case "matrix":
var p = zeros(x.m);
for (var i=0; i < x.m; i++) {
p[i] = pdfscalar(x.val[i*x.n], this.mean[0]);
for (var k = 1; k < x.n; k++)
p[i] *= pdfscalar(x.val[i*x.n + k], this.mean[k]);
}
break;
case "spmatrix":
var p = ones(x.m);
for (var i=0; i < x.m; i++) {
var xr = x.row(i); // could be faster without this...
for (var j=0; j < xr.ind[0] ; j++)
p[i] *= (1-this.mean[j]);
for (var k =0; k < xr.val.length - 1; k++) {
p[i] *= this.mean[xr.ind[k]];
for (var j=xr.ind[k]+1; j < xr.ind[k+1] ; j++)
p[i] *= (1-this.mean[j]);
}
p[i] *= this.mean[xr.ind[k]];
for (var j=xr.ind[k]+1; j < this.dimension ; j++)
p[i] *= (1-this.mean[j]);
}
break;
default:
var p = undefined;
break;
}
return p;
}
}
Bernoulli.prototype.logpdf = Bernoulli.prototype.logpmf = function ( x ) {
// return value of logPDF at x
const tx = type(x);
var logpdfscalar = function ( s, mu ) {
if ( s == 1 )
return Math.log(mu);
else if ( s == 0)
return Math.log(1-mu);
else
return -Infinity;
};
if ( this.dimension == 1 ) {
if ( tx == "number" ) {
return logpdfscalar(x, this.mean);
}
else if ( tx == "vector") {
var p = zeros(x.length);
for(var i = 0; i < x.length ; i++){
p[i] = logpdfscalar(x[i], this.mean);
}
return p;
}
else if ( tx == "matrix") {
var P = zeros(x.m, x.n);
var mn = x.m*x.n;
for(var k = 0; k < mn ; k++){
P.val[k] = logpdfscalar(x.val[k], this.mean);
}
return P;
}
}
else {
switch( tx ) {
case "vector":
var p = 0;
for (var k = 0; k < this.dimension; k++)
p += logpdfscalar(x[k], this.mean[k]);
break;
case "spvector":
var p = 0;
for (var j=0; j < x.ind[0] ; j++)
p += Math.log(1-this.mean[j]);
for (var k =0; k < x.val.length - 1; k++) {
p += Math.log(this.mean[x.ind[k]]);
for (var j=x.ind[k]+1; j < x.ind[k+1] ; j++)
p += Math.log(1-this.mean[j]);
}
p += Math.log(this.mean[x.ind[k]]);
for (var j=x.ind[k]+1; j < this.dimension ; j++)
p += Math.log(1-this.mean[j]);
break;
case "matrix":
var p = zeros(x.m);
for (var i=0; i < x.m; i++) {
for (var k = 0; k < x.n; k++)
p[i] += logpdfscalar(x.val[i*x.n + k], this.mean[k]);
}
break;
case "spmatrix":
var p = zeros(x.m);
for (var i=0; i < x.m; i++) {
var xr = x.row(i); // could be faster without this...
for (var j=0; j < xr.ind[0] ; j++)
p[i] += Math.log(1-this.mean[j]);
for (var k =0; k < xr.val.length - 1; k++) {
p[i] += Math.log(this.mean[xr.ind[k]]);
for (var j=xr.ind[k]+1; j < xr.ind[k+1] ; j++)
p[i] += Math.log(1-this.mean[j]);
}
p[i] += Math.log(this.mean[xr.ind[k]]);
for (var j=xr.ind[k]+1; j < this.dimension ; j++)
p[i] += Math.log(1-this.mean[j]);
}
break;
default:
var p = undefined;
break;
}
return p;
}
}
Bernoulli.prototype.sample = function ( N ) {
// Return N samples
if ( typeof(N) == "undefined" || N == 1 ) {
return isLower(rand(this.dimension) , this.mean);
}
else {
return isLower(rand(N, this.dimension) , outerprod(ones(N), this.mean) );
}
}
Bernoulli.prototype.estimate = function ( X ) {
// Estimate dsitribution from the N-by-d matrix X
switch ( type ( X ) ) {
case "matrix":
case "spmatrix":
this.mean = mean(X,1).val;
this.variance = entrywisemul(this.mean, sub(1, this.mean)) ;
this.std = sqrt(this.variance);
this.dimension = X.n;
break;
case "vector":
case "spvector":
this.dimension = 1;
this.mean = mean(X) ;
this.variance = this.mean * (1-this.mean);
this.std = Math.sqrt(this.variance);
break;
default:
error("Error in Bernoulli.estimate( X ): X must be a (sp)matrix or (sp)vector.");
break;
}
return this;
}
///////////////////////////////
/// Poisson
///////////////////////////////
function Poisson ( params ) {
var that = new Distribution ( Poisson, params ) ;
return that;
}
Poisson.prototype.construct = function ( mean ) {
// Read params and create the required fields for a specific algorithm
if ( typeof(mean) == "undefined" )
var mean = 5;
var dim = size(mean,1);
this.mean = mean;
this.variance = this.mean;
this.std = sqrt(this.variance);
this.dimension = dim;
}
Poisson.prototype.pdf = Poisson.prototype.pmf = function ( x ) {
// return value of PDF at x
const tx = type(x);
var pdfscalar = function ( s, lambda ) {
if ( s < 0 || Math.round(s) != s )
return 0;
else if ( s == 0)
return 1;
else {
var u = lambda;
for ( var k = 2; k <= s; k++ )
u *= lambda / k;
return Math.exp(-lambda) * u;
}
};
if ( this.dimension == 1 ) {
if ( tx == "number" ) {
return pdfscalar(x, this.mean);
}
else if ( tx == "vector") {
var p = zeros(x.length);
for(var i = 0; i < x.length ; i++){
p[i] = pdfscalar(x[i], this.mean);
}
return p;
}
else if ( tx == "matrix") {
var P = zeros(x.m, x.n);
var mn = x.m*x.n;
for(var k = 0; k < mn ; k++){
P.val[k] = pdfscalar(x.val[k], this.mean);
}
return p;
}
}
else {
if ( tx == "vector" ) {
var p = pdfscalar(x[0], this.mean[0]);
for (var k =0; k < this.dimension; k++)
p *= pdfscalar(x[k], this.mean[k]);
return p;
}
else if ( tx == "matrix") {
var p = zeros(x.m);
for (var i=0; i < x.m; i++) {
p[i] = pdfscalar(x.val[i*x.n], this.mean[0]);
for (var k =0; k < x.n; k++)
p[i] *= pdfscalar(x.val[i*x.n + k], this.mean[k]);
}
return p;
}
}
}
Poisson.prototype.sample = function ( N ) {
// Return N samples
var samplescalar = function (lambda) {
var x = Math.random();
var n = 0;
const exp_lambda = Math.exp(-lambda);
while (x > exp_lambda) {
x *= Math.random();
n++;
}
return n;
};
if ( typeof(N) == "undefined" || N == 1 ) {
if ( this.dimension == 1 )
return samplescalar(this.mean);
else {
var s = zeros(this.dimension);
for ( k=0; k < this.dimension; k++)
s[k] = samplescalar(this.mean[k]);
return s;
}
}
else {
if ( this.dimension == 1 ) {
var S = zeros(N);
for ( var i=0; i < N; i++)
S[i] = samplescalar(this.mean);
return S;
}
else {
var S = zeros(N, this.dimension);
for ( var i=0; i < N; i++) {
for ( k=0; k < this.dimension; k++)
S[i*this.dimension + k] = samplescalar(this.mean[k]);
}
return S;
}
}
}
Poisson.prototype.estimate = function ( X ) {
// Estimate dsitribution from the N-by-d matrix X
if ( type ( X ) == "matrix" ) {
this.mean = mean(X,1).val;
this.variance = this.mean;
this.std = sqrt(this.variance);
this.dimension = X.n;
}
else { // X is a vector samples
this.dimension = 1;
this.mean = mean(X) ;
this.variance = this.mean;
this.std = Math.sqrt(this.variance);
}
return this;
}
const Complex_I = new Complex(0, 1);
/**
* @constructor
* @struct
*/
function Complex(a, b, polar) {
/** @const */ this.type = "Complex";
if ( typeof(a) == "undefined") {
this.re = 0.0;
this.im = 0.0;
}
else if ( a instanceof Complex ) {
this.re = a.re;
this.im = a.im;
}
else if ( typeof(a) == "number" && !polar ) {
this.re = a;
this.im = b;
}
else {
this.re = a * Math.cos(b);
this.im = a * Math.sin(b);
}
}
Complex.prototype.toString = function () {
return this.re + (this.im >= 0 ? " + " : " - ") + Math.abs(this.im) + "i";
}
Complex.prototype.info = function () {
return this.re + (this.im >= 0 ? " + " : " - ") + Math.abs(this.im) + "i";
}
/**
* @param {Complex}
* @param {Complex}
* @return {Complex}
*/
function addComplex(a,b) {
var z = new Complex(a);
z.re += b.re;
z.im += b.im;
return z;
}
/**
* @param {Complex}
* @param {number}
* @return {Complex}
*/
function addComplexReal(a,b) {
var z = new Complex(a);
z.re += b;
return z;
}
/**
* @param {Complex}
* @param {Complex}
* @return {Complex}
*/
function subComplex(a,b) {
var z = new Complex(a);
z.re -= b.re;
z.im -= b.im;
return z;
}
/**
* @param {Complex}
* @return {Complex}
*/
function minusComplex(a) {
return new Complex(-a.re, -a.im);
}
function mulComplex(a,b) {
return new Complex(a.re*b.re - a.im*b.im, a.im * b.re + a.re*b.im);
}
function mulComplexReal(a,b) {
return new Complex(a.re*b, a.im * b);
}
function divComplex(a,b) {
var denom = b.re*b.re + b.im*b.im;
return new Complex( (a.re*b.re + a.im*b.im) / denom, (a.im * b.re - a.re*b.im) / denom );
}
function conj(z) {
if (z instanceof Complex)
return new Complex(z.re, -z.im);
else if (z instanceof ComplexVector) {
var r = new ComplexVector(z);
for (var i=0; i < z.length; i++)
r.im[i] = -r.im[i];
return r;
}
else if (z instanceof ComplexMatrix) {
var r = new ComplexMatrix(z);
for (var i=0; i < z.length; i++)
r.im[i] = -r.im[i];
return r;
}
else
return new Complex(z); // for a real
}
function modulus(z) {
if ( z instanceof Complex )
return Math.sqrt(z.re*z.re + z.im*z.im);
else if (z instanceof ComplexVector)
return sqrt(addVectors( entrywisemulVector(z.re, z.re), entrywisemulVector(z.im, z.im) ));
else if (z instanceof ComplexVector)
return new Matrix(z.m, z.n, sqrt(addVectors( entrywisemulVector(z.re, z.re), entrywisemulVector(z.im, z.im) ) , true));
}
var absComplex = modulus;
function expComplex(z) {
return new Complex(Math.exp(z.re), z.im, true);
}
/**
* @constructor
* @struct
*/
function ComplexVector(a, b, dontcopy) {
/** @const */ this.type = "ComplexVector";
if ( arguments.length == 0 ) {
// dummy call, probably in renewObject
// while loading data from a file
}
else if ( a instanceof ComplexVector) {
/** @const */ this.length = a.length;
this.re = vectorCopy(a.re);
this.im = vectorCopy(a.im);
}
else if (typeof(a) == "number") {
/** @const */ this.length = a;
this.re = new Float64Array(a);
this.im = new Float64Array(a);
}
else if ( a instanceof Float64Array && b instanceof Float64Array ) {
/** @const */ this.length = a.length;
if ( typeof(dontcopy) == "undefined" || !dontcopy ){
this.re = vectorCopy(a);
this.im = vectorCopy(b);
}
else {
this.re = a;
this.im = b;
}
}
else {
error("Bad arguments to new ComplexVector()");
}
}
/**
* @constructor
* @struct
*/
function ComplexMatrix(a, b, values, valuesimag) {
/** @const */ this.type = "ComplexMatrix";
if ( arguments.length == 0 ) {
// dummy call, probably in renewObject
// while loading data from a file
}
else if ( a instanceof ComplexMatrix) {
/** @const */ this.length = a.length;
/** @const */ this.m = a.m;
/** @const */ this.n = a.n;
/** @const */ this.size = [a.m, a.n];
this.re = vectorCopy(a.re);
this.im = vectorCopy(a.im);
}
else if (typeof(a) == "number" && typeof(b) == "number") {
/** @const */ this.length = a;
/** @const */ this.m = a;
/** @const */ this.n = b;
/** @const */ this.size = [a, b];
if ( typeof(values) == "undefined") {
this.re = new Float64Array(a*b);
this.im = new Float64Array(a*b);
}
else if ( values instanceof ComplexVector ) {
this.re = vectorCopy(values.re);
this.im = vectorCopy(values.im);
}
else if ( values instanceof Float64Array && typeof(valuesimag) != "undefined" && valuesimag instanceof Float64Array) {
this.re = values;
this.im = valuesimag; // !! no copy!
}
}
else if ( a instanceof Matrix && b instanceof Matrix) {
/** @const */ this.length = a.length;
/** @const */ this.m = a.m;
/** @const */ this.n = a.n;
/** @const */ this.size = [a.m, a.n];
this.re = vectorCopy(a.val);
this.im = vectorCopy(b.val);
}
else
error("Bad arguments to new ComplexMatrix()");
}
ComplexVector.prototype.toString = function () {
return "[" + this.type + " of size " + this.length + "]";
}
ComplexMatrix.prototype.toString = function () {
return "[" + this.type + " of size " + this.m + " x " + this.n + "]";
}
ComplexVector.prototype.get = function (i) {
return new Complex(this.re[i], this.im[i]);
}
ComplexMatrix.prototype.get = function (i,j) {
return new Complex(this.re[i*this.n + j], this.im[i*this.n + j]);
}
ComplexVector.prototype.set = function (i, z) {
if ( typeof(z) == "number" ) {
this.re[i] = z;
this.im[i] = 0;
}
else {
this.re[i] = z.re;
this.im[i] = z.im;
}
}
ComplexMatrix.prototype.set = function (i, j, z) {
if ( typeof(z) == "number" ) {
this.re[i*this.n + j] = z;
this.im[i*this.n + j] = 0;
}
else {
this.re[i*this.n + j] = z.re;
this.im[i*this.n + j] = z.im;
}
}
ComplexVector.prototype.getSubVector = function (rowsrange) {
const n = rowsrange.length;
var res = new ComplexVector( n );
for (var i = 0; i< n; i++) {
res.re[i] = this.re[rowsrange[i]];
res.im[i] = this.im[rowsrange[i]];
}
return res;
}
ComplexVector.prototype.setVectorScalar = function (rowsrange, B) {
var i;
for (i = 0; i< rowsrange.length; i++)
A.set ( rowsrange[i], B);
}
ComplexVector.prototype.setVectorVector = function (rowsrange, B) {
var i;
for (i = 0; i< rowsrange.length; i++)
A.set(rowsrange[i], B[i]);
}
function real(z) {
if (z instanceof Complex)
return z.re;
else if (z instanceof ComplexVector)
return vectorCopy(z.re);
else if (z instanceof ComplexMatrix)
return new Matrix(z.m, z.n, z.re);
else
return copy(z);
}
function imag(z) {
if (z instanceof Complex)
return z.im;
else if (z instanceof ComplexVector)
return vectorCopy(z.im);
else if (z instanceof ComplexMatrix)
return new Matrix(z.m, z.n, z.im);
else
return 0;
}
/**
* @param {MatrixComplex}
*/
function transposeComplexMatrix ( A ) {
// Hermitian transpose = conjugate transpose
const m = A.m;
const n = A.n;
if ( m > 1 ) {
var i;
var j;
var res = new ComplexMatrix( n,m);
var Aj = 0;
for ( j=0; j< m;j++) {
var ri = 0;
for ( i=0; i < n ; i++) {
res.re[ri + j] = A.re[Aj + i];
res.im[ri + j] = -A.im[Aj + i];
ri += m;
}
Aj += n;
}
return res;
}
else {
return new ComplexVector(A.re,minusVector(A.im));
}
}
/**
* @param {MatrixComplex}
*/
ComplexMatrix.prototype.transpose = function ( ) {
// simple Transpose without conjugate
const m = A.m;
const n = A.n;
if ( m > 1 ) {
var i;
var j;
var res = new ComplexMatrix( n,m);
var Aj = 0;
for ( j=0; j< m;j++) {
var ri = 0;
for ( i=0; i < n ; i++) {
res.re[ri + j] = A.re[Aj + i];
res.im[ri + j] = A.im[Aj + i];
ri += m;
}
Aj += n;
}
return res;
}
else {
return new ComplexVector(A.re,A.im);
}
}
/**
* @param {ComplexVector}
* @param {ComplexVector}
* @return {ComplexVector}
*/
function addComplexVectors(a, b) {
var z = new ComplexVector(a);
const n = a.length;
for ( var i=0; i< n; i++) {
z.re[i] += b.re[i];
z.im[i] += b.im[i];
}
return z;
}
/**
* @param {ComplexVector}
* @param {ComplexVector}
* @return {ComplexVector}
*/
function subComplexVectors(a, b) {
var z = new ComplexVector(a);
const n = a.length;
for ( var i=0; i< n; i++) {
z.re[i] -= b.re[i];
z.im[i] -= b.im[i];
}
return z;
}
/**
* @param {ComplexMatrix}
* @param {ComplexMatrix}
* @return {ComplexMatrix}
*/
function addComplexMatrices(a, b) {
var z = new ComplexMatrix(a);
const mn = a.m * a.n;
for ( var i=0; i< mn; i++) {
z.re[i] += b.re[i];
z.im[i] += b.im[i];
}
return z;
}
/**
* @param {ComplexMatrix}
* @param {ComplexMatrix}
* @return {ComplexMatrix}
*/
function subComplexMatrices(a, b) {
var z = new ComplexMatrix(a);
const mn = a.m * a.n;
for ( var i=0; i< mn; i++) {
z.re[i] -= b.re[i];
z.im[i] -= b.im[i];
}
return z;
}
/**
* @param {ComplexVector}
* @param {Float64Array}
* @return {ComplexVector}
*/
function addComplexVectorVector(a, b) {
var z = new ComplexVector(a);
const n = a.length;
for ( var i=0; i< n; i++) {
z.re[i] += b[i];
}
return z;
}
/**
* @param {ComplexVector}
* @param {Float64Array}
* @return {ComplexVector}
*/
function subComplexVectorVector(a, b) {
var z = new ComplexVector(a);
const n = a.length;
for ( var i=0; i< n; i++) {
z.re[i] -= b[i];
}
return z;
}
/**
* @param {ComplexMatrix}
* @param {Matrix}
* @return {ComplexMatrix}
*/
function addComplexMatrixMatrix(a, b) {
var z = new ComplexMatrix(a);
const n = a.m * a.n;
for ( var i=0; i< n; i++) {
z.re[i] += b.val[i];
}
return z;
}
/**
* @param {ComplexMatrix}
* @param {Matrix}
* @return {ComplexMatrix}
*/
function subComplexMatrixMatrix(a, b) {
var z = new ComplexMatrix(a);
const n = a.m * a.n;
for ( var i=0; i< n; i++) {
z.re[i] -= b.val[i];
}
return z;
}
/**
* @param {number}
* @param {ComplexVector}
* @return {ComplexVector}
*/
function addScalarComplexVector(a, b) {
var z = new ComplexVector(b);
const n = b.length;
for ( var i=0; i< n; i++) {
z.re[i] += a;
}
return z;
}
/**
* @param {number}
* @param {ComplexVector}
* @return {ComplexVector}
*/
function subScalarComplexVector(a, b) {
var z = minusComplexVector(b);
const n = b.length;
for ( var i=0; i< n; i++) {
z.re[i] += a;
}
return z;
}
/**
* @param {number}
* @param {ComplexMatrix}
* @return {ComplexMatrix}
*/
function addScalarComplexMatrix(a, b) {
var z = new ComplexMatrix(b);
const n = b.m * b.n;
for ( var i=0; i< n; i++) {
z.re[i] += a;
}
return z;
}
/**
* @param {ComplexVector}
* @param {ComplexVector}
* @return {ComplexVector}
*/
function entrywisemulComplexVectors(a, b) {
const n = a.length;
var z = new ComplexVector(n);
for ( var i=0; i< n; i++) {
z.re[i] = a.re[i] * b.re[i] - a.im[i] * b.im[i];
z.im[i] = a.im[i] * b.re[i] + a.re[i] * b.im[i];
}
return z;
}
/**
* @param {ComplexVector}
* @param {ComplexVector}
* @return {ComplexVector}
*/
function entrywisedivComplexVectors(a, b) {
const n = a.length;
var z = new ComplexVector(n);
for ( var i=0; i< n; i++) {
var bre = b.re[i];
var bim = b.im[i];
var denom = bre*bre + bim*bim;
z.re[i] = (a.re[i]*bre + a.im[i]*bim) / denom;
z.im[i] = (a.im[i]*bre - a.re[i]*bim) / denom;
}
return z;
}
/**
* @param {ComplexMatrix}
* @param {ComplexMatrix}
* @return {ComplexMatrix}
*/
function entrywisemulComplexMatrices(a, b) {
const n = a.m * a.n;
var z = new ComplexMatrix(a.m, a.n);
for ( var i=0; i< n; i++) {
z.re[i] = a.re[i] * b.re[i] - a.im[i] * b.im[i];
z.im[i] = a.im[i] * b.re[i] + a.re[i] * b.im[i];
}
return z;
}
/**
* @param {ComplexMatrix}
* @param {ComplexMatrix}
* @return {ComplexMatrix}
*/
function entrywisedivComplexMatrices(a, b) {
const n = a.m * a.n;
var z = new ComplexMatrix(a.m, a.n);
for ( var i=0; i< n; i++) {
var bre = b.re[i];
var bim = b.im[i];
var denom = bre*bre + bim*bim;
z.re[i] = (a.re[i]*bre + a.im[i]*bim) / denom;
z.im[i] = (a.im[i]*bre - a.re[i]*bim) / denom;
}
return z;
}
/**
* @param {ComplexVector}
* @param {Float64Array}
* @return {ComplexVector}
*/
function entrywisemulComplexVectorVector(a, b) {
const n = a.length;
var z = new ComplexVector(n);
for ( var i=0; i< n; i++) {
z.re[i] = a.re[i] * b[i];
z.im[i] = a.im[i] * b[i];
}
return z;
}
/**
* @param {ComplexMatrix}
* @param {Matrix}
* @return {ComplexMatrix}
*/
function entrywisemulComplexMatrixMatrix(a, b) {
const n = a.m * a.n;
var z = new ComplexMatrix(a.m, a.n);
for ( var i=0; i< n; i++) {
z.re[i] = a.re[i] * b.val[i];
z.im[i] = a.im[i] * b.val[i];
}
return z;
}
/**
* @param {ComplexVector}
* @return {ComplexVector}
*/
function minusComplexVector(a) {
const n = a.length;
var z = new ComplexVector(n);
for ( var i=0; i< n; i++) {
z.re[i] = -a.re[i];
z.im[i] = -a.im[i];
}
return z;
}
/**
* @param {ComplexMatrix}
* @return {ComplexMatrix}
*/
function minusComplexMatrix(a) {
var z = new ComplexMatrix(a.m, a.n);
const n = a.m * a.n;
for ( var i=0; i< n; i++) {
z.re[i] = -a.re[i];
z.im[i] = -a.im[i];
}
return z;
}
/**
* @param {ComplexVector}
* @return {number}
*/
function sumComplexVector(a) {
var z = new Complex();
const n = a.length;
for ( var i=0; i< n; i++) {
z.re += a.re[i];
z.im += a.im[i];
}
return z;
}
/**
* @param {ComplexMatrix}
* @return {number}
*/
function sumComplexMatrix(a) {
var z = new Complex();
const n = a.m * a.n;
for ( var i=0; i< n; i++) {
z.re += a.re[i];
z.im += a.im[i];
}
return z;
}
/**
* @param {ComplexVector}
* @return {number}
*/
function norm1ComplexVector(a) {
var r = 0.0;
const n = a.length;
for ( var i=0; i< n; i++) {
r += Math.sqrt(a.re[i] * a.re[i] + a.im[i]*a.im[i]);
}
return r;
}
/**
* @param {ComplexVector}
* @return {number}
*/
function norm2ComplexVector(a) {
var r = 0.0;
const n = a.length;
for ( var i=0; i< n; i++) {
r += a.re[i] * a.re[i] + a.im[i]*a.im[i];
}
return Math.sqrt(r);
}
/**
* @param {ComplexMatrix}
* @return {number}
*/
function normFroComplexMatrix(a) {
var r = 0.0;
const n = a.m * a.n;
for ( var i=0; i< n; i++) {
r += a.re[i] * a.re[i] + a.im[i]*a.im[i];
}
return Math.sqrt(r);
}
/**
* @param {ComplexVector}
* @param {ComplexVector}
* @return {Complex}
*/
function dotComplexVectors(a, b) {
// = b^H a = conj(b)^T a
var z = new Complex();
const n = a.length;
for ( var i=0; i< n; i++) {
z.re += a.re[i] * b.re[i] + a.im[i] * b.im[i];
z.im += a.im[i] * b.re[i] - a.re[i] * b.im[i]
}
return z;
}
/**
* @param {ComplexVector}
* @param {Float64Array}
* @return {Complex}
*/
function dotComplexVectorVector(a, b) {
// = b^T a
var z = new Complex();
const n = a.length;
for ( var i=0; i< n; i++) {
z.re += a.re[i] * b[i];
z.im += a.im[i] * b[i];
}
return z;
}
/**
* @param {number}
* @param {ComplexVector}
* @return {ComplexVector}
*/
function mulScalarComplexVector(a, b) {
var re = mulScalarVector(a, b.re);
var im = mulScalarVector(a, b.im);
return new ComplexVector(re,im, true);
}
/**
* @param {Complex}
* @param {ComplexVector}
* @return {ComplexVector}
*/
function mulComplexComplexVector(a, b) {
const n = b.length;
var z = new ComplexVector(n);
var are = a.re;
var aim = a.im;
for ( var i=0; i< n; i++) {
z.re[i] = are * b.re[i] - aim * b.im[i];
z.im[i] = aim * b.re[i] + are * b.im[i];
}
return z;
}
/**
* @param {Complex}
* @param {Float64Array}
* @return {ComplexVector}
*/
function mulComplexVector(a, b) {
const n = b.length;
var z = new ComplexVector(n);
var are = a.re;
var aim = a.im;
for ( var i=0; i< n; i++) {
z.re[i] = are * b[i];
z.im[i] = aim * b[i];
}
return z;
}
/**
* @param {number}
* @param {ComplexMatrix}
* @return {ComplexMatrix}
*/
function mulScalarComplexMatrix(a, b) {
var re = mulScalarVector(a, b.re);
var im = mulScalarVector(a, b.im);
return new ComplexMatrix(b.m, b.n, re, im);
}
/**
* @param {Complex}
* @param {ComplexMatrix}
* @return {ComplexMatrix}
*/
function mulComplexComplexMatrix(a, b) {
const n = b.m*b.n;
var z = new ComplexMatrix(b.m,b.n);
var are = a.re;
var aim = a.im;
for ( var i=0; i< n; i++) {
z.re[i] = are * b.re[i] - aim * b.im[i];
z.im[i] = aim * b.re[i] + are * b.im[i];
}
return z;
}
/**
* @param {Complex}
* @param {Matrix}
* @return {ComplexMatrix}
*/
function mulComplexMatrix(a, b) {
const n = b.m * b.n;
var z = new ComplexMatrix(b.m, b.n);
var are = a.re;
var aim = a.im;
for ( var i=0; i< n; i++) {
z.re[i] = are * b.val[i];
z.im[i] = aim * b.val[i];
}
return z;
}
/**
* @param {ComplexMatrix}
* @param {Float64Array}
* @return {ComplexVector}
*/
function mulComplexMatrixVector(a, b) {
const m = a.m;
const n = a.n;
var z = new ComplexVector(m);
var ai = 0;
for ( var i=0; i< m; i++) {
for ( j=0; j < n ; j++) {
z.re[i] += a.re[ai+j] * b[j];
z.im[i] += a.im[ai+j] * b[j];
}
ai += n;
}
return z;
}
/**
* @param {ComplexMatrix}
* @param {ComplexVector}
* @return {ComplexVector}
*/
function mulComplexMatrixComplexVector(a, b) {
const m = a.m;
const n = a.n;
var z = new ComplexVector(m);
var ai = 0;
for ( var i=0; i< m; i++) {
for ( j=0; j < n ; j++) {
z.re[i] += a.re[ai+j] * b.re[j] - a.im[ai+j] * b.im[j];
z.im[i] += a.im[ai+j] * b.re[j] + a.re[ai+j] * b.im[j];
}
ai += n;
}
return z;
}
/**
* @param {ComplexMatrix}
* @param {ComplexMatrix}
* @return {ComplexMatrix}
*/
function mulComplexMatrices(A, B) {
const m = A.length;
const n = B.n;
const n2 = B.length;
var Are = A.re;
var Aim = A.im;
var Bre = B.re;
var Bim = B.im;
var Cre = new Float64Array(m*n);
var Cim = new Float64Array(m*n);
var aik;
var Aik = 0;
var Ci = 0;
for (var i=0;i < m ; i++) {
var bj = 0;
for (var k=0; k < n2; k++ ) {
aikre = Are[Aik];
aikim = Aim[Aik];
for (var j =0; j < n; j++) {
Cre[Ci + j] += aikre * Bre[bj] - aikim * Bim[bj];
Cim[Ci + j] += aikre * Bim[bj] + aikim * Bre[bj];
bj++;
}
Aik++;
}
Ci += n;
}
return new ComplexMatrix(m,n,Cre, Cim);
}
/**
* @param {ComplexMatrix}
* @param {Matrix}
* @return {ComplexMatrix}
*/
function mulComplexMatrixMatrix(A, B) {
const m = A.m;
const n = B.n;
const n2 = B.m;
var Are = A.re;
var Aim = A.im;
var Bre = B.val;
var Cre = new Float64Array(m*n);
var Cim = new Float64Array(m*n);
var aik;
var Aik = 0;
var Ci = 0;
for (var i=0;i < m ; i++) {
var bj = 0;
for (var k=0; k < n2; k++ ) {
aikre = Are[Aik];
aikim = Aim[Aik];
for (var j =0; j < n; j++) {
Cre[Ci + j] += aikre * Bre[bj];
Cim[Ci + j] += aikim * Bre[bj];
bj++;
}
Aik++;
}
Ci += n;
}
return new ComplexMatrix(m,n,Cre, Cim);
}
/**
* @param {Float64Array|ComplexVector}
* @return {ComplexVector}
*/
function fft(x) {
const n = x.length;
const s = Math.log2(n);
const m = n/2;
if ( s % 1 != 0 ) {
error("fft(x) only implemented for x.length = 2^m. Use dft(x) instead.");
return undefined;
}
var X = new ComplexVector(x,zeros(n));
// bit reversal:
var j = 0;
for (var i = 0; i < n-1 ; i++) {
if (i < j) {
// swap(X[i], X[j])
var Xi = X.re[i];
X.re[i] = X.re[j];
X.re[j] = Xi;
Xi = X.im[i];
X.im[i] = X.im[j];
X.im[j] = Xi;
}
var k = m;
while (k <= j) {
j -= k;
k /= 2;
}
j += k;
}
// FFT:
var l2 = 1;
var c = new Complex(-1,0);
var u = new Complex();
for (var l = 0; l < s; l++) {
var l1 = l2;
l2 *= 2;
u.re = 1;
u.im = 0;
for (var j = 0; j < l1; j++) {
for (var i = j; i < n; i += l2) {
var i1 = i + l1;
//var t1 = mulComplex(u, X.get(i1) );
var t1re = u.re * X.re[i1] - u.im * X.im[i1]; // t1 = u * X[i1]
var t1im = u.im * X.re[i1] + u.re * X.im[i1];
X.re[i1] = X.re[i] - t1re;
X.im[i1] = X.im[i] - t1im;
X.re[i] += t1re;
X.im[i] += t1im;
}
u = mulComplex(u, c);
}
c.im = -Math.sqrt((1.0 - c.re) / 2.0);
c.re = Math.sqrt((1.0 + c.re) / 2.0);
}
return X;
}
/**
* @param {ComplexVector}
* @return {ComplexVector|Float64Array}
*/
function ifft(x) {
const n = x.length;
const s = Math.log2(n);
const m = n/2;
if ( s % 1 != 0 ) {
error("ifft(x) only implemented for x.length = 2^m. Use idft(x) instead.");
return undefined;
}
var X = new ComplexVector(x,zeros(n));
// bit reversal:
var j = 0;
for (var i = 0; i < n-1 ; i++) {
if (i < j) {
// swap(X[i], X[j])
var Xi = X.re[i];
X.re[i] = X.re[j];
X.re[j] = Xi;
Xi = X.im[i];
X.im[i] = X.im[j];
X.im[j] = Xi;
}
var k = m;
while (k <= j) {
j -= k;
k /= 2;
}
j += k;
}
// iFFT:
var l2 = 1;
var c = new Complex(-1,0);
var u = new Complex();
for (var l = 0; l < s; l++) {
var l1 = l2;
l2 *= 2;
u.re = 1;
u.im = 0;
for (var j = 0; j < l1; j++) {
for (var i = j; i < n; i += l2) {
var i1 = i + l1;
//var t1 = mulComplex(u, X.get(i1) );
var t1re = u.re * X.re[i1] - u.im * X.im[i1]; // t1 = u * X[i1]
var t1im = u.im * X.re[i1] + u.re * X.im[i1];
X.re[i1] = X.re[i] - t1re;
X.im[i1] = X.im[i] - t1im;
X.re[i] += t1re;
X.im[i] += t1im;
}
u = mulComplex(u, c);
}
c.im = Math.sqrt((1.0 - c.re) / 2.0);
c.re = Math.sqrt((1.0 + c.re) / 2.0);
}
var isComplex = false;
for(var i=0; i < n; i++) {
X.re[i] /= n;
X.im[i] /= n;
if ( Math.abs(X.im[i]) > 1e-6 )
isComplex = true;
}
if (isComplex)
return X;
else
return X.re;
}
function dft(x) {
// DFT of a real signal
if ( typeof(x) == "number")
return new Complex(x, 0);
const n = x.length;
if ( n == 1)
return new Complex(x[0], 0);
else if ( Math.log2(n) % 1 == 0 )
return fft(x);
else {
var X = new ComplexVector(n);
var thet = 0.0;
for ( var i=0; i < n; i++) {
var theta = 0.0;
for ( var t=0; t < n; t++) {
// theta = -2 pi i * t / n;
X.re[i] += x[t] * Math.cos(theta);
X.im[i] += x[t] * Math.sin(theta);
theta += thet;
}
thet -= 2*Math.PI / n;
}
return X;
}
}
function idft(X) {
// Only recovers real part
/*
importScripts("src/experimental/complex.js")
t = 0:512
x = sin(t)
X = dft(x)
plot(modulus(X))
s = idft(X)
plot(s)
*/
if ( !(X instanceof ComplexVector) ) {
if ( X instanceof Complex)
return X.re;
else if (typeof(X) == "number")
return X;
else if ( X instanceof Float64Array)
return idft(new ComplexVector(X, zeros(X.length), true));
else
return undefined;
}
const n = X.length;
if ( n == 1)
return X.re[0];
else if ( Math.log2(n) % 1 == 0 )
return ifft(X);
else {
var x = new Float64Array(n);
var thet = 0.0;
for ( var t=0; t < n; t++) {
var theta = 0.0;
var re = 0.0;
//var im = 0.0;
for ( var i=0; i < n; i++) {
// theta = 2 pi i * t / n;
re += X.re[i] * Math.cos(theta) - X.im[i] * Math.sin(theta);
// im += X[i].im * Math.sin(theta) + X[i].re * Math.cos(theta); // not used for real signals
theta += thet;
}
x[t] = re / n;
thet += 2*Math.PI / n;
}
return x;
}
}
function spectrum(x) {
if ( x instanceof Float64Array ) {
return absComplex(dft(x));
}
else
return undefined;
}
/*
Library for plotting functions
You need to include
<canvas id="plotcanvas" width="600" height="300" style="border: 1px solid black;">> </canvas>
Usage:
setScalePlot ( minX, maxX, Nsamples, scaleY) // scaleY is a factor of scaleX
plot( f [, color_index ] )
To clear the plot:
clearPlot();
*/
//////////////////////////////
// Cross-browsers compatibility:
/*
Chrome : turn off hardware acceleration to get mousemove events!
*/
/* Array.fill :
if (!Array.prototype.fill) {
Array.prototype.fill = function(value) {
if (this == null) {
throw new TypeError("this is null or not defined");
}
if ( typeof( value ) == "object")
throw new TypeError("Array.fill:: the value is not valid => only simple values allowed");
var O = Object(this);
for ( var i= 0; i < this.length; i++) {
O[i] = eval(value);
}
return O;
}
}
*/
////////////////////////////
// class Diagram
//
// functions take lengths in % of width and height
/////////////////////////////
function Diagram(canvasId) {
if(typeof(canvasId) === 'undefined' )
canvasId = "diagram";
this.canvasId = canvasId;
this.shapes = new Array();
this.selectedShape = -1; // for mousemove
this.selectedShapes = new Array(); // for user
this.mousexprev = -1;
this.mouseyprev = -1;
////// Cross browser support ////
var ctx = document.getElementById(this.canvasId).getContext("2d");
if ( !ctx.setLineDash ) {
ctx.setLineDash = function () {};
}
}
Diagram.prototype.rect = function (x,y,w, h, color, txt, txtcolor, opacity ) {
if(typeof(opacity) === 'undefined')
var opacity = 0.6;
if(typeof(txtcolor) === 'undefined')
var txtcolor = 0;
if(typeof(txt) === 'undefined')
var txt = "";
if(typeof(color) === 'undefined')
var color = 1;
this.shapes.push( ["rect", x, y, w, h, color, txt, txtcolor, opacity ] ) ;
this.redraw();
}
Diagram.prototype.circle = function (x,y,w, h, color, txt, txtcolor, opacity ) {
if(typeof(opacity) === 'undefined')
var opacity = 0.6;
if(typeof(txtcolor) === 'undefined')
var txtcolor = 0;
if(typeof(txt) === 'undefined')
var txt = "";
if(typeof(color) === 'undefined')
var color = 1;
this.shapes.push( ["circle", x, y, w, h, color, txt, txtcolor, opacity ] ) ;
this.redraw();
}
Diagram.prototype.image = function (x,y,w, h, imagename , txt, txtcolor, opacity) {
if(typeof(opacity) === 'undefined')
var opacity = 0.6;
if(typeof(txtcolor) === 'undefined')
var txtcolor = 0;
if(typeof(txt) === 'undefined')
var txt = "";
var t = this;
var imageIndex = this.shapes.length;
var image = new Image() ;
image.src = imagename;
image.onload = function() {
t.shapes[imageIndex][9] = true;
t.redraw();
}
this.shapes.push( ["image", x,y,w,h,image, txt, txtcolor, opacity, false ] );
}
Diagram.prototype.redraw = function () {
var canvas = document.getElementById(this.canvasId);
var ctx = canvas.getContext("2d");
ctx.clearRect(0,0,canvas.width, canvas.height);
var n;
var shape;
var x;
var y;
var w;
var h;
var color;
var txt;
var txtcolor;
var opacity;
var res;
// Draw shapes
for ( n = 0; n < this.shapes.length; n++) {
shape = this.shapes[n][0];
x = this.shapes[n][1];
y = this.shapes[n][2];
w = this.shapes[n][3];
h = this.shapes[n][4];
color = this.shapes[n][5];
txt = this.shapes[n][6];
txtcolor = this.shapes[n][7];
opacity = this.shapes[n][8];
if ( shape == "rect" ) {
setcolortransparent(ctx, color, opacity);
var cornerSize = 15;
ctx.beginPath();
ctx.moveTo ( x * canvas.width , y * canvas.height + cornerSize);
ctx.quadraticCurveTo( x * canvas.width, y * canvas.height, x * canvas.width + cornerSize, y * canvas.height );
// quadraticCurve = bezier curve ( control poitn, destination)
ctx.lineTo ( (x+w) * canvas.width - cornerSize, y * canvas.height);
ctx.quadraticCurveTo( (x+w) * canvas.width , y * canvas.height, (x+w) * canvas.width, y * canvas.height + cornerSize);
ctx.lineTo ( (x+w) * canvas.width , (y+h) * canvas.height - cornerSize);
ctx.quadraticCurveTo( (x+w) * canvas.width, (y+h) * canvas.height, (x+w) * canvas.width - cornerSize, (y+h) * canvas.height );
ctx.lineTo ( x * canvas.width + cornerSize , (y+h) * canvas.height);
ctx.quadraticCurveTo( x * canvas.width, (y+h) * canvas.height, x * canvas.width , (y+h) * canvas.height - cornerSize );
ctx.closePath();
ctx.fill();
//ctx.fillRect( x * canvas.width, y * canvas.height, w * canvas.width, h * canvas.height ) ;
// deal with selection
if ( n == this.selectedShape || this.selectedShapes.indexOf( n ) >= 0 ) {
setcolortransparent(ctx, 5, 0.3);
ctx.fillRect( (x-0.005) * canvas.width, (y-0.005) * canvas.height, (w+0.01) * canvas.width, (h+0.01) * canvas.height ) ;
}
}
else if ( shape == "circle" ) {
setcolortransparent(ctx, color, opacity);
ctx.beginPath();
ctx.moveTo ( (x+w/2) * canvas.width , y * canvas.height);
ctx.quadraticCurveTo( (x+w) * canvas.width, y * canvas.height, (x+w) * canvas.width, (y+h/2) * canvas.height );
ctx.quadraticCurveTo( (x+w) * canvas.width, (y+h) * canvas.height, (x+w/2) * canvas.width, (y+h) * canvas.height );
ctx.quadraticCurveTo( x * canvas.width, (y+h) * canvas.height, x * canvas.width, (y+h/2) * canvas.height );
ctx.quadraticCurveTo( x * canvas.width, y * canvas.height, (x+w/2) * canvas.width, y * canvas.height );
ctx.fill();
// deal with selection
if ( n == this.selectedShape || this.selectedShapes.indexOf( n ) >= 0 ) {
setcolortransparent(ctx, 5, 0.3);
ctx.fillRect( (x-0.005) * canvas.width, (y-0.005) * canvas.height, (w+0.01) * canvas.width, (h+0.01) * canvas.height ) ;
}
}
else if ( shape == "point" ) {
setcolortransparent(ctx, color, opacity);
ctx.beginPath();
ctx.arc(x * canvas.width , y * canvas.height , w * canvas.width, 0, 2 * Math.PI , true);
ctx.closePath();
ctx.fill();
// deal with selection
if ( n == this.selectedShape || this.selectedShapes.indexOf( n ) >= 0 ) {
setcolortransparent(ctx, 5, 0.3);
ctx.fillRect( (x-0.005) * canvas.width, (y-0.005) * canvas.height, (w+0.01) * canvas.width, (h+0.01) * canvas.height ) ;
}
}
else if ( shape == "label" ) {
setcolortransparent(ctx, color, opacity);
var lbl = document.getElementById(this.shapes[n][9]);
lbl.style.left = x * canvas.width;
lbl.style.top = y * canvas.height;
lbl.style.visibility = "visible";
}
else if ( shape == "arrow" ) {
setcolortransparent(ctx, color, opacity);
var arrowSize = 15;
ctx.save();
ctx.translate(x * canvas.width , y * canvas.height);
ctx.rotate(Math.PI * (this.shapes[n][9] / 180) );
ctx.beginPath();
ctx.moveTo ( 0,0);
ctx.lineTo ( (w) * canvas.width,0);
ctx.lineTo ( (w) * canvas.width, 0 - arrowSize*0.3);
ctx.lineTo ( (w) * canvas.width + arrowSize, ( h/2) * canvas.height);
ctx.lineTo ( (w) * canvas.width, (h) * canvas.height + arrowSize*0.3);
ctx.lineTo ( (w) * canvas.width , (h) * canvas.height);
ctx.lineTo ( 0 , (h) * canvas.height);
ctx.closePath();
ctx.fill();
ctx.restore();
}
else if ( shape == "image" ) {
if ( this.shapes[n][9] ) {
// iamge is ready
ctx.drawImage(this.shapes[n][5], x*canvas.width, y*canvas.height, w * canvas.width, h * canvas.height);
// deal with selection
if ( n == this.selectedShape || this.selectedShapes.indexOf( n ) >= 0 ) {
setcolortransparent(ctx, 3, 0.3);
ctx.fillRect( (x-0.005) * canvas.width, (y-0.005) * canvas.height, (w+0.01) * canvas.width, (h+0.01) * canvas.height ) ;
}
}
}
if( txt != "" ) {
var words = txt.split("*");
ctx.textAlign = "center"; // center of text appear at x position
var txtsize = Math.floor(50 * w) ;
ctx.font = txtsize + "pt sans-serif";
setcolor(ctx, txtcolor);
if ( words.length == 1 ) {
ctx.fillText( txt, (x + w/2) * canvas.width , (y + h/2) * canvas.height ) ;
}
else {
for (var i = 0; i< words.length; i++) {
ctx.fillText( words[i], (x + w/2) * canvas.width , (y + h/2 ) * canvas.height - (words.length/2 - i - 0.5)* (1.5 * txtsize)) ;
}
}
}
}
}
Diagram.prototype.mouseselect = function (event) {
var canvas= document.getElementById(this.canvasId);
var rect = canvas.getBoundingClientRect();
var x = event.clientX - rect.left; // mouse coordinates relative to plot
var y = event.clientY - rect.top;
if ( Math.abs(x - this.mousexprev) >= 1 || Math.abs(y - this.mouseyprev) >= 1 ) {
this.mousexprev = x;
this.mouseyprev = y;
// Find shape... starting from last one added which is on top of others...
var i = this.shapes.length - 1;
while ( i >= 0 && this.isInShape(x,y,this.shapes[i] ) == false )
i--;
if ( i >= 0 ) {
if ( i != this.selectedShape ) {
// new hit on shape i
this.selectedShape = i;
this.redraw();
this.onSelect();
}
}
else if ( this.selectedShape >= 0 ) {
this.onDeselect();
this.selectedShape = -1;
this.redraw();
}
}
}
Diagram.prototype.isInShape = function (x, y, shape) {
var canvas = document.getElementById(this.canvasId);
if(shape[0] == "rect") {
if ( x > shape[1] * canvas.width && x < ( shape[1] + shape[3] ) * canvas.width && y > shape[2] * canvas.height && y < (shape[2]+shape[4]) * canvas.height)
return true;
else
return false;
}
else if ( shape[0] == "circle" ) {
if ( x > shape[1] * canvas.width && x < ( shape[1] + shape[3] ) * canvas.width && y > shape[2] * canvas.height && y < (shape[2]+shape[4]) * canvas.height)
return true;
else
return false;
}
else if ( shape[0] == "arrow" ) {
return false;
}
else
return false;
}
Diagram.prototype.onSelect = function () {
// empty selection event handler
}
Diagram.prototype.onDeselect = function () {
// empty selection event handler
}
Diagram.prototype.select = function ( n ) {
if ( typeof(n) == "number" ) {
if ( this.selectedShapes.indexOf( n ) < 0 ) {
this.selectedShapes.push ( n );
this.redraw();
}
}
else {
for ( var i=0; i < n.length; i++ ) {
if ( this.selectedShapes.indexOf( n[i] ) < 0 ) {
this.selectedShapes.push ( n[i] );
}
}
this.redraw();
}
}
Diagram.prototype.deselect = function ( n ) {
if ( typeof(n) == "number" ) {
var idx = this.selectedShapes.indexOf( n );
if ( idx >= 0 ) {
this.selectedShapes.splice ( idx , 1 );
this.redraw();
}
}
else {
var idx;
for ( var i=0; i < n.length; i++ ) {
idx = this.selectedShapes.indexOf( n[i] );
if ( idx >= 0 ) {
this.selectedShapes.splice ( idx , 1 );
}
}
this.redraw();
}
}
Diagram.prototype.selectall = function ( n ) {
for( var i = 0; i < this.shapes.length; i++)
this.selectedShapes.push( i);
this.redraw();
}
Diagram.prototype.deselectall = function ( ) {
while (this.selectedShapes.length > 0)
this.selectedShapes.pop();
this.redraw();
}
////////////////////////////
// Define Object class "Plot" to be assigned to a canvas
/////////////////////////////
function Plot(canvasId) {
if(typeof(canvasId) === 'undefined' )
canvasId = "plotcanvas";
this.canvasId = canvasId;
this.minX = 0;
this.maxX = 10;
this.Nsamples = 1000;
this.scaleX = 1;
this.scaleY = 1;
this.minY = 0;
this.maxY = 1.5;
this.fcts = new Array();
this.lines= new Array();
this.areas= new Array();
this.points= new Array();
this.paths= new Array();
this.legend = "topright";
var canvas = document.getElementById(this.canvasId);
this.buffer = document.createElement('canvas');
this.buffer.width = canvas.width;
this.buffer.height = canvas.height;
this.viewX = 0;
this.viewY = 0;
////// Cross browser support ////
//var ctx = document.getElementById(this.canvasId).getContext("2d");
var ctx = this.buffer.getContext("2d");
if ( !ctx.setLineDash ) {
ctx.setLineDash = function () {};
}
}
Plot.prototype.addPoint = function(x,y,color_idx,radius, opacity) {
if(typeof(color_idx) === 'undefined')
color_idx = 0;
if(typeof(radius) === 'undefined')
radius = 5;
if(typeof(opacity) === 'undefined')
opacity = 1.1;
this.points.push([x,y,color_idx,radius,opacity] );
}
Plot.prototype.plotAxis = function() {
//var canvas = document.getElementById(this.canvasId);
var canvas = this.buffer;
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
ctx.fillStyle="white";
ctx.fillRect (0,0 , canvas.width, canvas.height);
ctx.strokeStyle = "black";
if (this.minY < 0 && this.maxY > 0) {
// X-axis
var y0 = canvas.height - (-this.minY * this.scaleY);
ctx.beginPath();
ctx.moveTo(0, y0);
ctx.lineTo(canvas.width, y0 );
ctx.closePath();
ctx.stroke();
// ticks
var tickspace = Math.ceil( (this.maxX - this.minX) / 10);
for (var x = -tickspace; x>this.minX; x -= tickspace ) {
var xx = (x - this.minX) * this.scaleX ;
ctx.beginPath();
ctx.moveTo(xx,y0 - 5 );
ctx.lineTo(xx, y0 + 5 );
ctx.stroke();
}
for (var x = tickspace; x < this.maxX ; x+=tickspace ) {
var xx = (x - this.minX) * this.scaleX ;
ctx.beginPath();
ctx.moveTo(xx,y0 - 5 );
ctx.lineTo(xx, y0 + 5 );
ctx.stroke();
}
}
if (this.minX < 0 && this.maxX > 0) {
// Y-axis
var x0 = -this.minX * this.scaleX;
ctx.beginPath();
ctx.moveTo(x0 ,0);
ctx.lineTo(x0 ,canvas.height);
ctx.closePath();
ctx.stroke();
// ticks
var tickspace = Math.ceil( (this.maxY - this.minY) / 10);
for (var y = -tickspace; y>this.minY; y -= tickspace ) {
var yy = (y - this.minY) * this.scaleY ;
ctx.beginPath();
ctx.moveTo(x0 -5 ,canvas.height-yy );
ctx.lineTo(x0 + 5, canvas.height-yy );
ctx.stroke();
}
for (var y = tickspace; y<this.maxY; y += tickspace ) {
var yy = (y - this.minY) * this.scaleY ;
ctx.beginPath();
ctx.moveTo(x0 -5 , canvas.height-yy );
ctx.lineTo(x0 + 5, canvas.height- yy );
ctx.stroke();
}
}
}
}
Plot.prototype.replot = function ( ) {
var x1;
var x2;
var y1;
var y2;
var opacity;
var radius;
var x;
var y;
var f;
var legend;
var color_idx;
var dashed;
var fillareaTo;
var nlegend = 0;
var res;
var canvas = this.buffer;
// var canvas=document.getElementById(this.canvasId);
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
this.plotAxis();
// use shadow but not on axis
ctx.shadowColor = '#999';
ctx.shadowBlur = 3;
ctx.shadowOffsetX = 3;
ctx.shadowOffsetY = 3;
const minX = this.minX;
const minY = this.minY;
const scaleX = this.scaleX;
const scaleY = this.scaleY;
const height = canvas.height;
var xplot = function (x) {
return (x-minX ) * scaleX ;
}
var yplot = function (y) {
return height - (y-minY)*scaleY ;
}
// Plot areas
for (var n=0; n < this.areas.length; n++) {
res = this.areas[n];
x1 = res[0];
y1 = res[1];
x2 = res[2];
y2 = res[3];
color_idx = res[4];
opacity = res[5];
if(color_idx == -1) {
color_idx = n+1;
}
setcolortransparent(ctx, color_idx, opacity);
var rectwidth = Math.abs(x2-x1);
var rectheight = Math.abs(y2 -y1);
var rectx = Math.min(x1,x2);
var recty = Math.max(y1,y2);
ctx.fillRect(( rectx-this.minX ) * this.scaleX , canvas.height - ( recty - this.minY) * this.scaleY , rectwidth * this.scaleX , rectheight * this.scaleY );
}
// Plot lines
ctx.lineWidth="3";
var cp = Infinity;
for (var n=0; n < this.lines.length; n++) {
res = this.lines[n];
if ( ( res[0] >= this.minX && res[0] <= this.maxX && res[1] >= this.minY && res[1] <= this.maxY ) //start in plot
|| (( res[2] >= this.minX && res[2] <= this.maxX && res[3] >= this.minY && res[3] <= this.maxY )) // end in plot
|| ( res[0] < this.minX && res[2] > this.maxX && ((res[1] >= this.minY && res[1] <= this.maxY) || (res[3] >= this.minY && res[3] <= this.maxY)) ) // overflow on x axis but y inside plot
|| ( res[2] < this.minX && 0 > this.maxX && ((res[1] >= this.minY && res[1] <= this.maxY) || (res[3] >= this.minY && res[3] <= this.maxY)) )
|| ( res[1] < this.minY && res[3] > this.maxY && ((res[0] >= this.minX && res[0] <= this.maxY) || (res[2] >= this.minX && res[2] <= this.maxX)) )// y-axis
|| ( res[3] < this.minY && res[1] > this.maxY && ((res[0] >= this.minX && res[0] <= this.maxX) || (res[2] >= this.minX && res[2] <= this.maxX)) )
) {
x1 = xplot(res[0]);
y1 = yplot(res[1]);
x2 = xplot(res[2]);
y2 = yplot(res[3]);
if ( Math.abs(x2-x1)>1 || Math.abs(y2-y1) > 1 ) {
color_idx = res[4];
dashed = res[5];
if(color_idx == -1) {
color_idx = n+1;
}
if ( color_idx != cp )
setcolor(ctx, color_idx);
if (dashed) {
ctx.setLineDash([5]);
ctx.lineWidth="1";
}
ctx.beginPath();
ctx.moveTo(x1 , y1);
ctx.lineTo(x2 ,y2);
ctx.stroke();
if (dashed) {
ctx.setLineDash([1, 0]);
ctx.lineWidth="3";
}
cp = color_idx;
}
}
}
ctx.lineWidth="1";
// Plot points
var xp = Infinity;
var yp = Infinity;
var cp = Infinity;
var op = -1;
for (var n=0; n < this.points.length; n++) {
res = this.points[n];
if ( res[0] >= this.minX && res[0] <= this.maxX && res[1] >= this.minY && res[1] <= this.maxY) {
x = xplot(res[0]);
y = yplot(res[1]);
if ( Math.abs(x-xp)>1 || Math.abs(y-yp) > 1 ) {
color_idx = res[2];
radius = res[3];
opacity = res[4];
if ( op != opacity || cp != color_idx) {
if ( opacity > 1.0 )
setcolor(ctx, color_idx);
else
setcolortransparent(ctx, color_idx, opacity);
}
ctx.beginPath();
ctx.arc( x , y , radius, 0, 2 * Math.PI , true);
ctx.closePath();
ctx.fill();
xp = x;
yp = y;
cp = color_idx;
op = opacity;
}
}
}
// Plot paths (sets of point-lines with all the same style, e.g., for lalolab functions)
for (var n=0; n < this.paths.length; n++) {
res = this.paths[n];
color_idx = res[1];
radius = res[2];
opacity = res[3];
dashed = res[4];
var marker = (opacity > 0 );
if ( opacity > 1.0 )
setcolor(ctx, color_idx);
else
setcolortransparent(ctx, color_idx, opacity);
if (dashed) {
ctx.setLineDash([5]);
ctx.lineWidth="1";
}
else{
ctx.lineWidth="3";
}
ctx.beginPath();
x = xplot(res[0][0][0]);
y = yplot(res[0][0][1]);
ctx.arc( x , y , radius, 0, 2 * Math.PI , true);
ctx.moveTo(x,y);
for ( var i=1; i < res[0].length; i++) {
x = xplot(res[0][i][0]);
y = yplot(res[0][i][1]);
if ( x >= 0 && x <= canvas.width && y >= 0 && y <= canvas.height ) {
if( marker )
ctx.arc( x , y , radius, 0, 2 * Math.PI , true);
ctx.lineTo(x,y);
}
}
//ctx.closePath();
ctx.stroke();
//ctx.fill();
ctx.setLineDash([1, 0]);
ctx.lineWidth="1";
}
// Plot functions
for(var n=0; n < this.fcts.length; n++) {
res = this.fcts[n];
f = res[0];
legend = res[1];
color_idx = res[2];
dashed = res[3];
fillareaTo = res[4];
if(color_idx == -1) {
color_idx = n+1;
}
setcolor(ctx, color_idx);
if (dashed) {
ctx.setLineDash([5]);
ctx.lineWidth="1";
}
else{
ctx.lineWidth="3";
}
if ( fillareaTo !== false ) {
ctx.beginPath();
ctx.moveTo(canvas.width, canvas.height - (fillareaTo - this.minY)* this.scaleY);
ctx.lineTo(0, canvas.height - (fillareaTo - this.minY)* this.scaleY );
//ctx.moveTo(0,canvas.height/2);
}
else {
ctx.moveTo(0,canvas.height/2);
ctx.beginPath();
}
for(var x=this.minX; x < this.maxX; x += (this.maxX-this.minX) / this.Nsamples ) {
var y = f(x);
var yp = canvas.height - ( y - this.minY) * this.scaleY ;
if (yp >= 0 && yp <= canvas.height)
ctx.lineTo(xplot(x) , yp );
else
ctx.moveTo(xplot(x) , yp);
}
ctx.stroke();
if ( fillareaTo !== false ) {
ctx.closePath();
setcolortransparent(ctx, color_idx, 0.5);
ctx.fill();
}
ctx.setLineDash([1, 0]);
ctx.lineWidth="1";
// Add legend:
if ( this.legend != "" && legend != "") {
setcolor(ctx, color_idx);
if ( this.legend == "topright")
ctx.strokeText(legend, canvas.width - 100, 20*(nlegend+1));
else if ( this.legend == "topleft")
ctx.strokeText(legend, 10, 20*(nlegend+1));
else if ( this.legend == "bottomright")
ctx.strokeText(legend, canvas.width - 100, canvas.height - 20*(nlegend+1));
else if ( this.legend == "bottomleft")
ctx.strokeText(legend,10, canvas.height - 20*(nlegend+1));
nlegend++;
}
}
}
// Copy buffer to viewport
var viewcanvas = document.getElementById(this.canvasId);
var ctx = viewcanvas.getContext("2d");
ctx.drawImage(this.buffer, this.viewX, this.viewY, viewcanvas.width,viewcanvas.height,0,0, viewcanvas.width,viewcanvas.height);
}
Plot.prototype.plot = function ( f, legend, color_idx, dashed , fillareaTo ) {
if (typeof(fillareaTo) === 'undefined')
fillareaTo = false;
if (typeof(dashed) === 'undefined')
dashed = false;
if (typeof(color_idx) === 'undefined')
color_idx = -1;
if (typeof(legend) === 'undefined') {
if (dashed)
legend = "";
else
legend = f.name;
}
this.fcts.push([f, legend, color_idx,dashed, fillareaTo]);
this.replot();
}
Plot.prototype.plot_line = function ( x1,y1,x2,y2, color_idx, dashed ) {
if (typeof(dashed) === 'undefined')
dashed = false;
if (typeof(color_idx) === 'undefined')
color_idx = -1;
this.lines.push([x1,y1,x2,y2, color_idx,dashed]);
//this.replot();
}
Plot.prototype.plot_area = function ( x1,y1,x2,y2, color_idx, opacity ) {
if (typeof(opacity) === 'undefined')
opacity = 1.0;
if (typeof(color_idx) === 'undefined')
color_idx = -1;
this.areas.push([x1,y1,x2,y2, color_idx,opacity]);
this.replot();
}
Plot.prototype.plot_path = function ( x,y, color_idx, radius, opacity, dashed ) {
if (typeof(dashed) === 'undefined')
var dashed = false;
if (typeof(color_idx) === 'undefined')
var color_idx = -1;
if (typeof(opacity) === 'undefined')
var opacity = 1;
if (typeof(radius) === 'undefined')
var radius = 5;
this.paths.push([x,y, color_idx,radius, opacity, dashed]);
//this.replot();
}
Plot.prototype.clear = function () {
var canvas = document.getElementById(this.canvasId);
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
this.plotAxis();
// Empty list of functions to plot:
while(this.fcts.length > 0) {
this.fcts.pop();
}
while(this.lines.length > 0) {
this.lines.pop();
}
while(this.areas.length > 0) {
this.areas.pop();
}
while(this.points.length > 0) {
this.points.pop();
}
}
}
Plot.prototype.setScalePlot = function ( minX, maxX, Nsamples, scaleY) {
this.minX = minX;
this.maxX = maxX;
this.Nsamples = Nsamples;
var canvas = document.getElementById(this.canvasId);
this.scaleX = canvas.width / (maxX - minX) ;
this.scaleY = this.scaleX * scaleY;
this.maxY = (canvas.height/2) / this.scaleY ;
this.minY = -this.maxY;// centered view
//this.clear();
this.originalminX = this.minX;
this.originalmaxX = this.maxX;
this.originalminY = this.minY;
this.originalmaxY = this.maxY;
}
Plot.prototype.view = function ( minX, maxX, minY, maxY) {
this.minX = minX;
this.maxX = maxX;
this.minY = minY;
this.maxY = maxY;
var canvas = this.buffer;
this.scaleX = canvas.width / (maxX - minX) ;
this.scaleY = canvas.height / (maxY - minY) ;
this.replot();
}
Plot.prototype.translate = function ( dx, dy ) {
var canvas = document.getElementById(this.canvasId);
var newX = this.viewX - dx;
var newY = this.viewY - dy;
if ( newX >= 0 && newX < this.buffer.width - canvas.width && newY >= 0 && newY < this.buffer.height - canvas.height ) {
this.viewX = newX;
this.viewY = newY;
var ctx = canvas.getContext("2d");
ctx.clearRect (0, 0 , canvas.width, canvas.height);
ctx.drawImage(this.buffer, this.viewX, this.viewY, canvas.width,canvas.height,0,0, canvas.width,canvas.height);
}
}
Plot.prototype.zoom = function ( zx, zy, x, y) {
var viewcanvas = document.getElementById(this.canvasId);
var canvas = this.buffer;
if ( zy > 0 )
canvas.height *= zy;
else
canvas.height = viewcanvas.height;
if ( zx > 0 )
canvas.width *= zx;
else
canvas.width = viewcanvas.width;
// do not zoom out further than original
if ( canvas.width < viewcanvas.width )
canvas.width = viewcanvas.width;
if( canvas.height < viewcanvas.height )
canvas.height = viewcanvas.height;
// do not zoo in too much
if ( canvas.width > 10000)
canvas.width = 10000;
if( canvas.height > 10000 )
canvas.height > 10000;
var sx = this.scaleX;
var sy = this.scaleY;
this.scaleX = canvas.width / (this.maxX - this.minX) ;
this.scaleY = canvas.height / (this.maxY - this.minY) ;
// zoom center is (x,y)
if ( arguments.length < 4 ) {
var x = viewcanvas.width/2;
var y = viewcanvas.height/2;// by default viewport center is fixed during zoom
}
this.viewX = ((this.viewX + x) * this.scaleX / sx) - x;
this.viewY = ((this.viewY + y) * this.scaleY / sy) - y;
if ( this.viewX < 0 )
this.viewX = 0;
if (this.viewY < 0 )
this.viewY = 0;
if ( this.viewX > canvas.width - viewcanvas.width )
this.viewX = canvas.width - viewcanvas.width ;
if ( this.viewY > canvas.height - viewcanvas.height )
this.viewY = canvas.height - viewcanvas.height ;
if( sx != this.scaleX || sy != this.scaleY )
this.replot();
}
Plot.prototype.resetzoom = function ( ) {
var viewcanvas = document.getElementById(this.canvasId);
var canvas = this.buffer;
this.viewX = 0;
this.viewY = 0;
canvas.height = viewcanvas.height;
canvas.width = viewcanvas.width;
this.scaleX = viewcanvas.width / (this.maxX - this.minX) ;
this.scaleY = viewcanvas.height / (this.maxY - this.minY) ;
this.replot();
}
Plot.prototype.pick_point = function(e) {
if(e.button == 0) {
e.preventDefault();
var canvas = document.getElementById(this.canvasId);
var rect = canvas.getBoundingClientRect();
var xmouse = e.clientX - rect.left; // mouse coordinates relative to plot
var ymouse = e.clientY - rect.top;
var x = xmouse / this.scaleX + this.minX;
var y = (canvas.height - ymouse ) / this.scaleY + this.minY;
return [x,y];
}
else
return false; // not correct button
}
Plot.prototype.proximityX = function (x, x0, epsilon) {
if (typeof(epsilon) === 'undefined')
epsilon = (this.maxX - this.minX) / 20;
return ( Math.abs(x - x0) < epsilon ) ;
}
Plot.prototype.plotmathjax = function(stringindex, x, y) {
var canvas = document.getElementById(this.canvasId);
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
var label = document.getElementById("jaxstring"+stringindex);
label.style.top = canvas.height/2 - ( y * this.scaleY ) + canvas.offsetTop;
label.style.left = (x - this.minX) * this.scaleX + canvas.offsetLeft;
label.style.visibility = "visible";
}
}
Plot.prototype.jpeg = function() {
var canvas = document.getElementById(this.canvasId);
var image = canvas.toDataURL("image/jpeg");
document.location.href = image.replace("image/jpeg", "image/octet-stream");
}
Plot.prototype.zoomoriginal = function () {
this.view(this.originalminX,this.originalmaxX,this.originalminY,this.originalmaxY);
}
Plot.prototype.mousestartmove = function ( e ) {
var canvas = document.getElementById(this.canvasId);
if ( e.button == 0 ) {
this.MOVING = true;
var rect = canvas.getBoundingClientRect();
this.xprev = e.clientX - rect.left; // mouse coordinates relative to plot
this.yprev = e.clientY - rect.top;
}
else {
this.MOVING = false;
}
}
Plot.prototype.mousestopmove = function ( e ) {
this.MOVING = false;
}
Plot.prototype.mouseposition = function ( e ) {
var canvas = document.getElementById(this.canvasId);
var rect = canvas.getBoundingClientRect();
var xmouse = e.clientX - rect.left;
var ymouse = e.clientY - rect.top;
if ( this.MOVING ) {
var dx = this.xprev - xmouse ;
var dy = ymouse - this.yprev;
if ( Math.abs( dx ) > 1 || Math.abs( dy ) > 1 ) {
//this.view(this.minX+dx/this.scaleX,this.maxX+dx/this.scaleX, this.minY+dy/this.scaleY, this.maxY+dy/this.scaleY);
this.translate(dx, dy);
}
this.xprev = xmouse;
this.yprev = ymouse;
}
else {
var x = xmouse / this.scaleX + this.minX;
var y = (canvas.height - ymouse ) / this.scaleY + this.minY;
return "x = " + x.toFixed(3) + ", y = " + y.toFixed(3);
}
}
////////////////////////////
// Define Object class "ColorPlot" for (x,y) plots with z giving the point color
/////////////////////////////
function ColorPlot(canvasId) {
if(typeof(canvasId) === 'undefined' )
canvasId = "plotcanvas";
this.canvasId = canvasId;
this.minX = 0;
this.maxX = 10;
this.scaleX = 1;
this.scaleY = 1;
this.minY = 0;
this.maxY = 1.5;
this.minZ = 0;
this.maxZ = 1;
this.x = new Array();
this.y= new Array();
this.z= new Array();
this.cmap = this.colormap();
var canvas = document.getElementById(this.canvasId);
this.buffer = document.createElement('canvas');
this.buffer.width = canvas.width;
this.buffer.height = canvas.height;
this.viewX = 0;
this.viewY = 0;
}
ColorPlot.prototype.colormap = function (cmapname) {
switch(cmapname) {
default:
var cmap = [
[0, 0, 143],
[0, 0, 159],
[0, 0, 175],
[0, 0, 191],
[0, 0, 207],
[0, 0, 223],
[0, 0, 239],
[0, 0, 255],
[0, 15, 255],
[0, 31, 255],
[0, 47, 255],
[0, 63, 255],
[0, 79, 255],
[0, 95, 255],
[0, 111, 255],
[0, 127, 255],
[0, 143, 255],
[0, 159, 255],
[0, 175, 255],
[0, 191, 255],
[0, 207, 255],
[0, 223, 255],
[0, 239, 255],
[0, 255, 255],
[15, 255, 239],
[31, 255, 223],
[47, 255, 207],
[63, 255, 191],
[79, 255, 175],
[95, 255, 159],
[111, 255, 143],
[127, 255, 127],
[143, 255, 111],
[159, 255, 95],
[175, 255, 79],
[191, 255, 63],
[207, 255, 47],
[223, 255, 31],
[239, 255, 15],
[255, 255, 0],
[255, 239, 0],
[255, 223, 0],
[255, 207, 0],
[255, 191, 0],
[255, 175, 0],
[255, 159, 0],
[255, 143, 0],
[255, 127, 0],
[255, 111, 0],
[255, 95, 0],
[255, 79, 0],
[255, 63, 0],
[255, 47, 0],
[255, 31, 0],
[255, 15, 0],
[255, 0, 0],
[239, 0, 0],
[223, 0, 0],
[207, 0, 0],
[191, 0, 0],
[175, 0, 0],
[159, 0, 0],
[143, 0, 0],
[127, 0, 0]];
break;
}
return cmap;
}
ColorPlot.prototype.addPoint = function(x,y,z) {
this.x.push(x);
this.y.push(y);
this.z.push(z);
}
ColorPlot.prototype.plotAxis = function() {
var canvas = this.buffer;
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
ctx.fillStyle="white";
ctx.fillRect (0,0 , canvas.width, canvas.height);
ctx.strokeStyle = "black";
if (this.minY < 0 && this.maxY > 0) {
// X-axis
var y0 = canvas.height - (-this.minY * this.scaleY);
ctx.beginPath();
ctx.moveTo(0, y0);
ctx.lineTo(canvas.width, y0 );
ctx.closePath();
ctx.stroke();
// ticks
var tickspace = Math.ceil( (this.maxX - this.minX) / 10);
for (var x = -tickspace; x>this.minX; x -= tickspace ) {
var xx = (x - this.minX) * this.scaleX ;
ctx.beginPath();
ctx.moveTo(xx,y0 - 5 );
ctx.lineTo(xx, y0 + 5 );
ctx.stroke();
}
for (var x = tickspace; x < this.maxX ; x+=tickspace ) {
var xx = (x - this.minX) * this.scaleX ;
ctx.beginPath();
ctx.moveTo(xx,y0 - 5 );
ctx.lineTo(xx, y0 + 5 );
ctx.stroke();
}
}
if (this.minX < 0 && this.maxX > 0) {
// Y-axis
var x0 = -this.minX * this.scaleX;
ctx.beginPath();
ctx.moveTo(x0 ,0);
ctx.lineTo(x0 ,canvas.height);
ctx.closePath();
ctx.stroke();
// ticks
for (var y = Math.ceil(this.minY); y < this.maxY; y++ ) {
var yy = canvas.height - (y -this.minY) * this.scaleY;
ctx.beginPath();
ctx.moveTo(x0-5,yy);
ctx.lineTo(x0+5,yy);
ctx.stroke();
}
}
}
}
ColorPlot.prototype.replot = function ( ) {
var x,y,z;
var canvas=this.buffer;
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
this.plotAxis();
// use shadow but not on axis
ctx.shadowColor = '#999';
ctx.shadowBlur = 3;
ctx.shadowOffsetX = 3;
ctx.shadowOffsetY = 3;
// Plot points
var xp = Infinity;
var yp = Infinity;
var zp = Infinity;
for (var i=0; i < this.x.length; i++) {
if ( this.x[i] >= this.minX && this.x[i] <= this.maxX && this.y[i] >= this.minY && this.y[i] <= this.maxY) {
x = (this.x[i]-this.minX ) * this.scaleX ;
y = canvas.height - (this.y[i] - this.minY) * this.scaleY ;
z = Math.floor( (this.z[i] - this.minZ) * this.scaleZ);
if ( z >= this.cmap.length )
z = this.cmap.length-1;
if ( z < 0)
z = 0;
if ( Math.abs(x-xp)>1 || Math.abs(y-yp) > 1 || z != zp ) {
if ( z != zp )
ctx.fillStyle = "rgb(" + this.cmap[z][0] + "," + this.cmap[z][1] + "," + this.cmap[z][2]+ ")";
ctx.beginPath();
ctx.arc( x , y , 5, 0, 2 * Math.PI , true);
ctx.closePath();
ctx.fill();
zp = z;
xp = x;
yp = y;
}
}
}
}
// Copy buffer to viewport
var viewcanvas = document.getElementById(this.canvasId);
var ctx = viewcanvas.getContext("2d");
ctx.drawImage(this.buffer, this.viewX, this.viewY, viewcanvas.width,viewcanvas.height,0,0, viewcanvas.width,viewcanvas.height);
}
ColorPlot.prototype.clear = function () {
this.plotAxis();
this.x = new Array();
this.y = new Array();
this.z = new Array();
}
ColorPlot.prototype.setScale = function ( minX, maxX, minY, maxY, minZ, maxZ) {
this.minX = minX;
this.maxX = maxX;
this.minY = minY;
this.maxY = maxY;
this.minZ = minZ;
this.maxZ = maxZ;
var canvas = document.getElementById(this.canvasId);
this.scaleX = canvas.width / (maxX - minX) ;
this.scaleY = canvas.height / (maxY - minY);
this.scaleZ = this.cmap.length / (maxZ - minZ) ;
//this.clear();
this.originalminX = this.minX;
this.originalmaxX = this.maxX;
this.originalminY = this.minY;
this.originalmaxY = this.maxY;
}
ColorPlot.prototype.view = function ( minX, maxX, minY, maxY) {
this.minX = minX;
this.maxX = maxX;
this.minY = minY;
this.maxY = maxY;
var canvas = this.buffer;
this.scaleX = canvas.width / (maxX - minX) ;
this.scaleY = canvas.height / (maxY - minY) ;
this.replot();
}
ColorPlot.prototype.translate = function ( dx, dy ) {
var canvas = document.getElementById(this.canvasId);
var newX = this.viewX - dx;
var newY = this.viewY - dy;
if ( newX >= 0 && newX < this.buffer.width - canvas.width && newY >= 0 && newY < this.buffer.height - canvas.height ) {
this.viewX = newX;
this.viewY = newY;
var ctx = canvas.getContext("2d");
ctx.clearRect (0, 0 , canvas.width, canvas.height);
ctx.drawImage(this.buffer, this.viewX, this.viewY, canvas.width,canvas.height,0,0, canvas.width,canvas.height);
}
}
ColorPlot.prototype.zoom = function ( zx, zy, x, y) {
var viewcanvas = document.getElementById(this.canvasId);
var canvas = this.buffer;
if ( zy > 0 )
canvas.height *= zy;
else
canvas.height = viewcanvas.height;
if ( zx > 0 )
canvas.width *= zx;
else
canvas.width = viewcanvas.width;
// do not zoom out further than original
if ( canvas.width < viewcanvas.width )
canvas.width = viewcanvas.width;
if( canvas.height < viewcanvas.height )
canvas.height = viewcanvas.height;
// do not zoo in too much
if ( canvas.width > 10000)
canvas.width = 10000;
if( canvas.height > 10000 )
canvas.height > 10000;
var sx = this.scaleX;
var sy = this.scaleY;
this.scaleX = canvas.width / (this.maxX - this.minX) ;
this.scaleY = canvas.height / (this.maxY - this.minY) ;
// zoom center is (x,y)
if ( arguments.length < 4 ) {
var x = viewcanvas.width/2;
var y = viewcanvas.height/2;// by default viewport center is fixed during zoom
}
this.viewX = ((this.viewX + x) * this.scaleX / sx) - x;
this.viewY = ((this.viewY + y) * this.scaleY / sy) - y;
if ( this.viewX < 0 )
this.viewX = 0;
if (this.viewY < 0 )
this.viewY = 0;
if ( this.viewX > canvas.width - viewcanvas.width )
this.viewX = canvas.width - viewcanvas.width ;
if ( this.viewY > canvas.height - viewcanvas.height )
this.viewY = canvas.height - viewcanvas.height ;
if( sx != this.scaleX || sy != this.scaleY )
this.replot();
}
ColorPlot.prototype.resetzoom = function ( ) {
var viewcanvas = document.getElementById(this.canvasId);
var canvas = this.buffer;
this.viewX = 0;
this.viewY = 0;
canvas.height = viewcanvas.height;
canvas.width = viewcanvas.width;
this.scaleX = viewcanvas.width / (this.maxX - this.minX) ;
this.scaleY = viewcanvas.height / (this.maxY - this.minY) ;
this.replot();
}
ColorPlot.prototype.jpeg = function() {
var canvas = document.getElementById(this.canvasId);
var image = canvas.toDataURL("image/jpeg");
document.location.href = image.replace("image/jpeg", "image/octet-stream");
}
ColorPlot.prototype.zoomoriginal = function () {
this.view(this.originalminX,this.originalmaxX,this.originalminY,this.originalmaxY);
}
ColorPlot.prototype.mousestartmove = function ( e ) {
var canvas = document.getElementById(this.canvasId);
if ( e.button == 0 ) {
this.MOVING = true;
var rect = canvas.getBoundingClientRect();
this.xprev = e.clientX - rect.left; // mouse coordinates relative to plot
this.yprev = e.clientY - rect.top;
}
else {
this.MOVING = false;
}
}
ColorPlot.prototype.mousestopmove = function ( e ) {
this.MOVING = false;
}
ColorPlot.prototype.mouseposition = function ( e ) {
var canvas = document.getElementById(this.canvasId);
var rect = canvas.getBoundingClientRect();
var xmouse = e.clientX - rect.left;
var ymouse = e.clientY - rect.top;
if ( this.MOVING ) {
var dx = this.xprev - xmouse ;
var dy = ymouse - this.yprev;
if ( Math.abs( dx ) > 1 || Math.abs( dy ) > 1 ) {
this.translate(dx,dy);
}
this.xprev = xmouse;
this.yprev = ymouse;
}
else {
var x = xmouse / this.scaleX + this.minX;
var y = (canvas.height - ymouse ) / this.scaleY + this.minY;
return "x = " + x.toFixed(3) + ", y = " + y.toFixed(3);
}
}
/////////////////////////////////
// Define Object class "Plot2D"
function Plot2D(canvasId, tableId) {
if(typeof(canvasId) === 'undefined' )
this.canvasId = "plotcanvas2D";
else
this.canvasId = canvasId;
if(typeof(tableId) === 'undefined' )
this.tableId = ""; // No data table by default
else
this.tableId = tableId;
this.minX1 = -10;
this.maxX1 = 10;
this.minX2 = -10;
this.maxX2 = 10;
this.scaleX1 ;
this.scaleX2 ;
this.NsamplesX1 = 500;
this.NsamplesX2 = 500;
// Training set 2D
this.Xapp = new Array();
this.Yapp = new Array();
this.m = 0;
////// Cross browser support ////
var ctx = document.getElementById(this.canvasId).getContext("2d");
if ( !ctx.setLineDash ) {
ctx.setLineDash = function () {};
}
}
Plot2D.prototype.clear = function () {
var canvas = document.getElementById(this.canvasId);
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
/* put this into setscale2D : */
this.scaleX1 = canvas.width / (this.maxX1 - this.minX1);
this.scaleX2 = canvas.height / (this.maxX2 - this.minX2);
this.NsamplesX1 = canvas.width / 4;
this.NsamplesX2 = canvas.height / 4;
/////
ctx.fillStyle = "white";
ctx.fillRect (0,0 , canvas.width, canvas.height);
ctx.strokeStyle = "black";
ctx.lineWidth = "1";
if (this.minX2 < 0 && this.maxX2 > 0) {
// X1-axis
ctx.beginPath();
ctx.moveTo(0,canvas.height + this.minX2 * this.scaleX2);
ctx.lineTo(canvas.width,canvas.height + this.minX2 * this.scaleX2);
ctx.closePath();
ctx.stroke();
}
if (this.minX1 < 0 && this.maxX1 > 0) {
// X2-axis
ctx.beginPath();
ctx.moveTo(( -this.minX1 ) * this.scaleX1 ,0);
ctx.lineTo(( -this.minX1 ) * this.scaleX1 ,canvas.height);
ctx.closePath();
ctx.stroke();
}
}
//this.clearData();
}
Plot2D.prototype.clearData = function () {
if( this.tableId != "" )
document.getElementById(this.tableId).innerHTML = "<tr> <td> x1 </td><td> x2 </td><td> y </td></tr> ";
while(this.Yapp.length > 0) {
this.Yapp.pop();
this.Xapp.pop();
}
this.m = 0;
}
Plot2D.prototype.levelcurve = function (f, level ) {
var canvas = document.getElementById(this.canvasId);
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
var started = false;
ctx.fillStyle = "rgb(0,0,200)";
ctx.strokeStyle = "rgb(0,0,200)";
//ctx.lineWidth="3";
//ctx.beginPath();
var Y = new Array();
var i = 0;
var j = 0;
// Compute function values
for(var x1=this.minX1; x1 < this.maxX1; x1 += (this.maxX1-this.minX1) / this.NsamplesX1 ) {
Y[i] = new Array();
for(var x2=this.minX2; x2 < this.maxX2; x2 += (this.maxX2-this.minX2) / this.NsamplesX2 ) {
var x = [x1, x2];
Y[i][j] = f(x) ;
j++;
}
i++;
}
// Draw level curve
var i = 0;
var j = 0;
for(var x1=this.minX1; x1 < this.maxX1; x1 += (this.maxX1-this.minX1) / this.NsamplesX1 ) {
for(var x2=this.minX2; x2 < this.maxX2; x2 += (this.maxX2-this.minX2) / this.NsamplesX2 ) {
if ( ( j > 0 && Y[i][j] >= level && Y[i][j-1] <= level )
|| ( j > 0 && Y[i][j] <= level && Y[i][j-1] >= level )
|| ( i > 0 && Y[i][j] <= level && Y[i-1][j] >= level )
|| ( i > 0 && Y[i][j] >= level && Y[i-1][j] <= level ) ) {
/*
if ( !started ){
ctx.moveTo(( x1-this.minX1 ) * this.scaleX1, canvas.height/2 - ( x2 * this.scaleX2 ));
started = true;
}
else
ctx.lineTo(( x1-this.minX1 ) * this.scaleX1 , canvas.height/2 - ( x2 * this.scaleX2 ));
*/
ctx.fillRect (( x1-this.minX1 ) * this.scaleX1 - 2, canvas.height - ( ( x2 - this.minX2) * this.scaleX2 ) - 2, 4, 4);
}
j++;
}
i++;
}
// ctx.closePath();
//ctx.stroke();
}
}
Plot2D.prototype.colormap = function(f) {
var canvas = document.getElementById(this.canvasId);
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
var started = false;
var maxf = -Infinity;
var minf = +Infinity;
var Y = new Array();
var i = 0;
var j = 0;
// Compute function values
for(var x1=this.minX1; x1 < this.maxX1; x1 += (this.maxX1-this.minX1) / this.NsamplesX1 ) {
Y[i] = new Array();
for(var x2=this.minX2; x2 < this.maxX2; x2 += (this.maxX2-this.minX2) / this.NsamplesX2 ) {
var x = [x1, x2];
Y[i][j] = f(x) ;
if(Y[i][j] > maxf ) {
maxf = Y[i][j];
}
if(Y[i][j] < minf ) {
minf = Y[i][j];
}
j++;
}
i++;
}
var colorScale = 255 / (maxf - minf);
// Draw colormap
var i = 0;
var j = 0;
for(var x1=this.minX1; x1 < this.maxX1; x1 += (this.maxX1-this.minX1) / this.NsamplesX1 ) {
for(var x2=this.minX2; x2 < this.maxX2; x2 += (this.maxX2-this.minX2) / this.NsamplesX2 ) {
if (Math.abs(Y[i][j] ) < 0.00001 ) {
ctx.fillStyle = "black";
}
else if (Y[i][j] < 0 ) {
ctx.fillStyle = "rgba(0,0," + (255 - Math.floor((Y[i][j] - minf) * colorScale )) + ", 0.9)";
}
else {
//ctx.fillStyle = "rgba(" + Math.floor((Y[i][j] - minf) * colorScale ) + ",0,255,0.5)";
ctx.fillStyle = "rgba(" + Math.floor((Y[i][j] - minf) * colorScale ) + ",0,0, 0.9)";
}
ctx.fillRect (( x1-this.minX1 ) * this.scaleX1 - 2, canvas.height - ( ( x2 - this.minX2) * this.scaleX2 )- 2, 4, 4);
//margin
if (Math.abs(Y[i][j] ) < 1 ) {
ctx.fillStyle = "rgba(200,200,200,0.5)";
ctx.fillRect (( x1-this.minX1 ) * this.scaleX1 - 2, canvas.height - ( ( x2 - this.minX2) * this.scaleX2 )- 2, 4, 4);
}
j++;
}
i++;
}
}
}
Plot2D.prototype.point = function (x1, x2, color_idx, opacity, radius ) {
if (typeof(opacity) === 'undefined')
opacity = 1.1;
if (typeof(radius) === 'undefined')
radius = 5;
var canvas = document.getElementById(this.canvasId);
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
if (opacity < 1.0 )
setcolortransparent(ctx, color_idx, opacity);
else
setcolor(ctx, color_idx);
ctx.beginPath();
ctx.arc( ( x1-this.minX1 ) * this.scaleX1 , canvas.height - ( x2 - this.minX2) * this.scaleX2, radius, 0, 2 * Math.PI , true);
// arc( x, y, radius, agnlestart, angleend, sens)
ctx.closePath();
ctx.fill();
}
}
Plot2D.prototype.pointmouse = function (event ) {
if(event.button == 0) {
event.preventDefault();
var canvas = document.getElementById(this.canvasId);
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
var rect = canvas.getBoundingClientRect();
var x = event.clientX - rect.left; // mouse coordinates relative to plot
var y = event.clientY - rect.top;
var color_idx = parseInt(document.getElementById("selectcolor").value);
// Add to training set
var etiquette = color_idx;
var x1 = x / this.scaleX1 + this.minX1;
var x2 = (canvas.height - y) / this.scaleX2 + this.minX2;
// plot point
this.point(x1,x2,color_idx );
this.Xapp[this.m] = new Array();
this.Xapp[this.m][0] = x1;
this.Xapp[this.m][1] = x2;
this.Yapp[this.m] = etiquette;
this.m++;
if ( this.tableId != "" ) {
// add to table of points
var t = document.getElementById(this.tableId);
t.innerHTML += "<tr><td>"+ x1.toFixed(2) + "</td><td>" + x2.toFixed(2) + "</td><td>" + etiquette + "</td></tr>";
}
}
}
}
Plot2D.prototype.plot_data = function () {
if (this.m != this.Yapp.length )
this.m = this.Yapp.length;
for(var i=0;i < this.m ;i++) {
this.point (this.Xapp[i][0], this.Xapp[i][1], this.Yapp[i] );
}
}
Plot2D.prototype.plot_vector = function(start_x1,start_x2, end_x1,end_x2, vectorname, veccolor) {
if(typeof(veccolor) === 'undefined') {
veccolor = 0;
}
start_x1 = (start_x1 - this.minX1) * this.scaleX1;
end_x1 = (end_x1 - this.minX1) * this.scaleX1;
start_x2 = (start_x2 - this.minX2) * this.scaleX2;
end_x2 = (end_x2 - this.minX2) * this.scaleX2;
var theta1 = Math.atan((end_x2 - start_x2)/(end_x1 - start_x1)); // angle entre vecteur et axe X1
var theta2 = Math.atan((end_x1 - start_x1) /(end_x2 - start_x2)); // angle entre vecteur et axe X2
var arrowsize = 10;
var arrow1_x1 = end_x1 ;
var arrow1_x2 = end_x2 ;
var arrow2_x1 = end_x1 ;
var arrow2_x2 = end_x2 ;
if ( end_x2 >= start_x2) {
arrow1_x1 -= arrowsize*Math.sin(theta2 - Math.PI/12);
arrow1_x2 -= arrowsize*Math.cos(theta2 - Math.PI/12);
}
else {
arrow1_x1 += arrowsize*Math.sin(theta2 - Math.PI/12);
arrow1_x2 += arrowsize*Math.cos(theta2 - Math.PI/12);
}
if ( end_x1 >= start_x1 ) {
arrow2_x1 -= arrowsize*Math.cos(theta1 - Math.PI/12);
arrow2_x2 -= arrowsize*Math.sin(theta1 - Math.PI/12);
}
else {
arrow2_x1 += arrowsize*Math.cos(theta1 - Math.PI/12);
arrow2_x2 += arrowsize*Math.sin(theta1 - Math.PI/12);
}
var canvas = document.getElementById(this.canvasId);
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
ctx.lineWidth="1";
setcolor(ctx,veccolor);
ctx.beginPath();
ctx.moveTo(start_x1,canvas.height - start_x2);
ctx.lineTo(end_x1,canvas.height - end_x2);
ctx.lineTo(arrow1_x1,canvas.height - arrow1_x2);
ctx.lineTo(arrow2_x1,canvas.height - arrow2_x2);
ctx.lineTo(end_x1,canvas.height - end_x2);
ctx.stroke();
ctx.fill();
if(typeof(vectorname) !== 'undefined') {
ctx.lineWidth="1";
var dx =5;
if ( end_x1 < start_x1)
dx = -15;
ctx.strokeText(vectorname, end_x1 + dx,canvas.height - end_x2);
}
}
}
Plot2D.prototype.plot_line = function(start_x1,start_x2, end_x1,end_x2, linename, linecolor, dashed, linewidth) {
if(typeof(linecolor) === 'undefined') {
linecolor = 0;
}
if(typeof(dashed) === 'undefined') {
dashed = false;
}
if(typeof(linewidth) === 'undefined') {
linewidth = 1;
}
start_x1 = (start_x1 - this.minX1) * this.scaleX1;
end_x1 = (end_x1 - this.minX1) * this.scaleX1;
start_x2 = (start_x2 - this.minX2) * this.scaleX2;
end_x2 = (end_x2 - this.minX2) * this.scaleX2;
var canvas = document.getElementById(this.canvasId);
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
ctx.lineWidth=""+linewidth;
setcolor(ctx,linecolor);
if (dashed) {
ctx.setLineDash([5]);
//ctx.lineWidth="1";
}
ctx.beginPath();
ctx.moveTo(start_x1,canvas.height - start_x2);
ctx.lineTo(end_x1,canvas.height - end_x2);
ctx.stroke();
ctx.setLineDash([1, 0]);
if(typeof(linename) !== 'undefined') {
if ( linename != "" ) {
ctx.lineWidth="1";
ctx.strokeText(linename, (end_x1 + start_x1)/2 - 10 ,canvas.height - 10 - (end_x2+start_x2)/2);
}
}
}
}
Plot2D.prototype.plot_classifier = function (w, b, coloridx, disappear) {
if (typeof(disappear) === 'undefined')
var disappear = false;
if (typeof(coloridx) === 'undefined')
var coloridx = 0;
var x1 = this.minX1;
var x2 = this.maxX1;
var y1;
var y2;
if (w[1] != 0) {
y1 = (-b - w[0]*x1) / w[1];
y2 = (-b - w[0]*x2) / w[1];
}
else {
x1 = -b / w[0];
x2 = -b / w[0];
y1 = this.minX2;
y2 = this.maxX2;
}
var canvas = document.getElementById(plot.canvasId);
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
ctx.lineWidth="3";
if ( disappear )
ctx.strokeStyle = "grey";
else
setcolor(ctx, coloridx);
ctx.setLineDash([1, 0]);
ctx.beginPath();
ctx.moveTo(( x1-this.minX1 ) * this.scaleX1 , canvas.height/2 - ( y1 * this.scaleX2 ));
ctx.lineTo(( x2-this.minX1 ) * this.scaleX1 , canvas.height/2 - ( y2 * this.scaleX2 ));
ctx.stroke();
}
}
Plot2D.prototype.coord2datavector = function(x1,x2) {
var canvas = document.getElementById(this.canvasId);
var x = [0,0] ;
x[0] = ( x1 / this.scaleX1 ) + this.minX1 ;
x[1] = (-( x2-canvas.height) / this.scaleX2 ) + this.minX2;
return x;
}
Plot2D.prototype.plotmathjax = function(stringindex, x, y) {
var canvas = document.getElementById(this.canvasId);
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
var label = document.getElementById("jaxstring"+stringindex);
label.style.top = canvas.height - ( y - this.minX2) * this.scaleX2 + canvas.offsetTop;
label.style.left = (x - this.minX1) * this.scaleX1 + canvas.offsetLeft;
label.style.visibility = "visible";
}
}
Plot2D.prototype.clearmathjax = function(stringindex) {
var label = document.getElementById("jaxstring"+stringindex);
label.style.visibility = "hidden";
}
Plot2D.prototype.text = function (x1,x2,txt) {
var canvas = document.getElementById(this.canvasId);
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
ctx.lineWidth="0.5";
ctx.strokeStyle = "black";
ctx.strokeText(txt, ( x1-this.minX1 ) * this.scaleX1 , canvas.height - ( x2 - this.minX2) * this.scaleX2);
}
}
///////////////////////////////
/// Plot 3D ///////////////////
///////////////////////////////
function Plot3D(canvasId) {
if(typeof(canvasId) === 'undefined' )
this.canvasId = "plotcanvas3D";
else
this.canvasId = canvasId;
var canvas = document.getElementById(this.canvasId);
this.minX1 = -10;
this.maxX1 = 10;
this.minX2 = -10;
this.maxX2 = 10;
this.minX3 = -10;
this.maxX3 = 10;
this.scaleX1 ;
this.scaleX2 ;
this.scaleX3 ;
this.NsamplesX1 = 50;
this.NsamplesX2 = 50;
this.NsamplesX3 = 50;
this.axisNameX1 = "x1";
this.axisNameX2 = "x2";
this.axisNameX3 = "x3";
// Training set 3D
this.X = new Array();
this.Y = new Array();
// other stuff to plot
this.lines = new Array();
this.planes = new Array();
this.spheres = new Array();
// 2D Graphics
this.view2D = new Array();
this.viewminX1 = -10;
this.viewmaxX1 = 10;
this.viewminX2 = -10;
this.viewmaxX2 = 10;
this.viewscaleX1 = canvas.width / (this.viewmaxX1 - this.viewminX1);
this.viewscaleX2 = canvas.width / (this.viewmaxX2 - this.viewminX2);
this.angleX = 0.0;//- Math.PI/6; // rotations around axis
this.angleY = 0.0;
this.angleZ = 0.0;// - Math.PI/8;
this.cameraDistance = 20;
// Mouse animation
this.ROTATING = false;
this.mouseX = 0;
this.mouseY = 0;
// automatic animation
this.animation = null;
this.animateAuto = 0; // if 0: do not relaunch animation after mouse released
// if > 0: samplingrate of animation
////// Cross browser support ////
var ctx = document.getElementById(this.canvasId).getContext("2d");
if ( !ctx.setLineDash ) {
ctx.setLineDash = function () {};
}
if(window.addEventListener)
canvas.addEventListener('DOMMouseScroll', this.mousezoom, false);//firefox
//for IE/OPERA etc
canvas.onmousewheel = this.mousezoom;
}
Plot3D.prototype.test = function() {
this.X.push([5,0,0]);
this.X.push([0,5,0]);
this.X.push([0,0,5]);
this.Y.push(1);
this.Y.push(2);
this.Y.push(3);
this.X.push([2,0,0]);
this.X.push([0,-6,0]);
this.X.push([0,0,2]);
this.Y.push(1);
this.Y.push(2);
this.Y.push(3);
this.X.push([5,5,5]);
this.Y.push(3);
this.sphere([5,-5, 1], 50, "", 1) ;
this.sphere([-5,5, -3], 30, "", 3) ;
this.replot();
this.animateAuto = 100;
this.animate(50);
}
Plot3D.prototype.computeRanges = function () {
var i;
for (i=0;i<this.Y.length ; i++) {
var norm = Math.sqrt( this.X[i][0]*this.X[i][0] + this.X[i][1]*this.X[i][1] + this.X[i][2]*this.X[i][2] )
if ( norm > this.maxX2 ) {
this.maxX2 = norm;
this.minX2 = -norm;
}
}
}
Plot3D.prototype.replot = function() {
// Compute 2D coordinates from 3D ones
var x1;
var x2;
var distance;
var opacity;
var radius;
var res;
var i;
var maxDistance = this.cameraDistance + this.maxX2 - this.minX2;
this.clear();
// plotorigin
this.point2D(0, 0, 0 , 1.0, 3 ) ;
// plot axis
this.line([ -1, 0, 0], [10, 0,0] , this.axisNameX1);
this.line([ 0, -1, 0], [0, 10 ,0] ,this.axisNameX2);
this.line([ 0, 0, -1], [0, 0,10] , this.axisNameX3);
// plot points
for (i=0;i<this.Y.length ; i++) {
res = this.project(this.X[i] );
x1 = res[0];
x2 = res[1];
distance = res[2];
if ( distance < maxDistance )
opacity = ( distance / maxDistance ) ;
else
opacity = 1.0;
radius = Math.floor(2 + (1 - opacity) * 10);
this.point2D(x1, x2, this.Y[i] , opacity, radius ) ;
}
// plot lines
for (i=0;i<this.lines.length; i++) {
this.line(this.lines[i][0],this.lines[i][1],this.lines[i][2],this.lines[i][3]);
}
// plot planes
for (i=0;i<this.planes.length; i++) {
this.drawplane(this.planes[i][0],this.planes[i][1],this.planes[i][2],this.planes[i][3]);
}
// plot spheres
// plot the most distant ones first !!!
var distances = new Array();
for (i=0;i<this.spheres.length; i++) {
var res = this.project( this.spheres[i][0] );
distances[i] = res[2];
}
for (var n=0;n<this.spheres.length; n++) {
var idx = 0;
for ( i=1; i< this.spheres.length; i++) {
if ( distances[i] > distances[idx] )
idx = i;
}
this.drawsphere( this.spheres[idx][0], this.spheres[idx][1], this.spheres[idx][2], this.spheres[idx][3] );
distances[idx] = -1;
}
}
Plot3D.prototype.clear = function( ) {
var canvas = document.getElementById(this.canvasId);
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
ctx.clearRect(0,0,canvas.width,canvas.height);
}
}
Plot3D.prototype.clear_data = function( ) {
while (this.Y.length > 0) {
this.Y.pop();
this.X.pop();
}
}
Plot3D.prototype.clear_planes = function( ) {
while(this.planes.length > 0) {
this.planes.pop();
}
}
Plot3D.prototype.rotateX = function( deltaangle ) {
this.angleX += deltaangle;
this.replot();
}
Plot3D.prototype.rotateY = function( deltaangle ) {
this.angleY += deltaangle;
this.replot();
}
Plot3D.prototype.rotateZ = function( deltaangle , do_replot) {
if ( typeof(do_replot) == "undefined" )
var do_replot = true;
this.angleZ += deltaangle;
if ( do_replot )
this.replot();
}
Plot3D.prototype.mouserotation = function(e) {
if ( this.ROTATING ) {
e.preventDefault();
var dx = e.clientX - this.mouseX;
var dy = e.clientY - this.mouseY;
this.mouseX = e.clientX;
this.mouseY = e.clientY;
if ( Math.abs(dx) > 0.2 )
this.rotateZ(dx / 20, !(Math.abs(dy) > 0.2) );
if ( Math.abs(dy) > 0.2 )
this.rotateX(dy / 20);
}
}
Plot3D.prototype.mousedown = function(e) {
e.preventDefault();
this.ROTATING = true;
this.mouseX = e.clientX;
this.mouseY = e.clientY;
this.animateStop();
}
Plot3D.prototype.mouseup = function(e) {
e.preventDefault();
this.ROTATING = false;
if ( this.animateAuto > 0 ) {
this.animate( this.animateAuto );
}
}
Plot3D.prototype.mousezoom = function(e) {
// !!! use plot3 instead of this due to event handler...
var delta = 0;
if (!e)
e = window.event;
e.preventDefault();
// normalize the delta
if (e.wheelDelta) {
// IE and Opera
delta = e.wheelDelta / 30;
}
else if (e.detail) {
delta = -e.detail ;
}
plot3.cameraDistance -= delta ;
if ( plot3.cameraDistance < 5 ) {
plot3.cameraDistance = 5;
}
else if ( plot3.cameraDistance > 100 )
plot3.cameraDistance = 100;
plot3.replot();
}
Plot3D.prototype.project = function ( x3D ) {
/*
x3D : points in World coordinate system
Camera / view coordinate system initialized like World system
Camera is fixed to (0,cameraDistance,0) in camera system
1. rotate World in camera system
2. project camera system to 2D XZ plane since camera on Y-axis
3. distance to camera = cameraDistance + Y
*/
// 1. rotation
var tmpX = new Array(3);
// rotation around X-axis:
tmpX[0] = x3D[0]; // does not change X-coordinate
tmpX[1] = Math.cos(this.angleX) * x3D[1] - Math.sin(this.angleX) * x3D[2];
tmpX[2] = Math.sin(this.angleX) * x3D[1] + Math.cos(this.angleX) * x3D[2];
// rotation around Y-axis:
var tmpY = new Array(3);
tmpY[0] = Math.cos(this.angleY) * tmpX[0] - Math.sin(this.angleY) * tmpX[2];
tmpY[1] = tmpX[1];
tmpY[2] = Math.sin(this.angleY) * tmpX[0] + Math.cos(this.angleY) * tmpX[2];
// rotation around Z-axis:
var tmpZ = new Array(3);
tmpZ[0] = Math.cos(this.angleZ) * tmpY[0] - Math.sin(this.angleZ) * tmpY[1];
tmpZ[1] = Math.sin(this.angleZ) * tmpY[0] + Math.cos(this.angleZ) * tmpY[1];
tmpZ[2] = tmpY[2];
// Scaling
var scale = ( this.cameraDistance/20 ) ;
tmpZ[0] /= scale;
tmpZ[1] /= scale;
tmpZ[2] /= scale;
// Project to 2D plane
var x1 = tmpZ[0];
var x2 = tmpZ[2];
var distance = this.cameraDistance + tmpZ[1];
return [x1,x2, distance];
}
Plot3D.prototype.line = function( start, end, linename, linecolor, dashed, linewidth ) {
var start_x1;
var start_x2;
var res = this.project(start);
start_x1 = res[0];
start_x2 = res[1];
var end_x1;
var end_x2;
res = this.project(end);
end_x1 = res[0];
end_x2 = res[1];
this.line2D(start_x1, start_x2, end_x1, end_x2, linename, linecolor, dashed, linewidth);
}
Plot3D.prototype.plot_line = function( start, end, linename, color ) {
if (typeof(color) === 'undefined')
var color = 0;
this.lines.push([start, end, linename, color]);
this.line( start, end, linename, color );
}
Plot3D.prototype.plane = function( start, end, polyname, color ) {
if (typeof(color) === 'undefined')
var color = 3;
if (typeof(polyname) === 'undefined')
var polyname = "";
this.planes.push([start, end, polyname, color]);
this.drawplane( start, end, polyname, color );
}
Plot3D.prototype.drawplane = function( start, end, polyname, color ) {
var res;
var corner1 = new Array(3);// 2 other corners
var corner2 = new Array(3);
corner1[0] = start[0];
corner1[1] = end[1];
corner1[2] = start[2];
corner2[0] = end[0];
corner2[1] = start[1];
corner2[2] = end[2];
res = this.project(start);
var start_x1 = res[0];
var start_x2 = res[1];
res = this.project(end);
var end_x1 = res[0];
var end_x2 = res[1];
res = this.project(corner1);
var corner1_x1 = res[0];
var corner1_x2 = res[1];
res = this.project(corner2);
var corner2_x1 = res[0];
var corner2_x2 = res[1];
this.polygone2D( [ start_x1, corner1_x1, end_x1, corner2_x1], [ start_x2, corner1_x2, end_x2, corner2_x2], polyname, color);
}
Plot3D.prototype.sphere = function( center, radius, spherename, color ) {
if (typeof(color) === 'undefined')
var color = 1;
if (typeof(spherename) === 'undefined')
var spherename = "";
this.spheres.push([center, radius, spherename, color ]);
this.drawsphere( center, radius, spherename, color );
}
Plot3D.prototype.drawsphere = function( center, radius, spherename, color ) {
var res;
res = this.project(center);
var x1 = res[0];
var x2 = res[1];
var distance = res[2];
if ( distance >= 0 ) {
var opacity = 1.0;
var maxDistance = this.cameraDistance + this.maxX2 - this.minX2;
if ( distance < maxDistance )
opacity = 0.5 * ( distance / maxDistance ) ;
var radius2D = Math.floor(radius * ( 0 +3* (1 - opacity)*(1 - opacity) ) );
this.disk2D( x1, x2, radius2D, spherename, color, opacity);
}
}
Plot3D.prototype.point2D = function (x1, x2, color_idx, opacity, radius ) {
if ( x1 >= this.viewminX1 && x1 <= this.viewmaxX1 && x2 >= this.viewminX2 && x2 <= this.viewmaxX2 ) {
if (typeof(opacity) === 'undefined')
var opacity = 1.1;
if (typeof(radius) === 'undefined')
var radius = 5;
var canvas = document.getElementById(this.canvasId);
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
if (opacity < 1.0 )
setcolortransparent(ctx, color_idx, opacity);
else
setcolor(ctx, color_idx);
ctx.beginPath();
ctx.arc( ( x1-this.viewminX1 ) * this.viewscaleX1 , canvas.height - ( x2 - this.viewminX2) * this.viewscaleX2, radius, 0, 2 * Math.PI , true);
// arc( x, y, radius, agnlestart, angleend, sens)
ctx.closePath();
ctx.fill();
}
}
}
Plot3D.prototype.line2D = function(start_x1,start_x2, end_x1,end_x2, linename, linecolor, dashed, linewidth) {
if(typeof(linecolor) === 'undefined') {
linecolor = 0;
}
if(typeof(dashed) === 'undefined') {
dashed = false;
}
if(typeof(linewidth) === 'undefined') {
linewidth = 1;
}
start_x1 = (start_x1 - this.viewminX1) * this.viewscaleX1;
end_x1 = (end_x1 - this.viewminX1) * this.viewscaleX1;
start_x2 = (start_x2 - this.viewminX2) * this.viewscaleX2;
end_x2 = (end_x2 - this.viewminX2) * this.viewscaleX2;
var canvas = document.getElementById(this.canvasId);
if ( start_x1 < 0 )
start_x1 = 0;
if ( start_x1 >= canvas.width )
start_x1 = canvas.width-1;
if ( start_x2 <= 0 )
start_x2 = 1;
if ( start_x2 > canvas.height )
start_x2 = canvas.height;
if ( end_x1 < 0 )
end_x1 = 0;
if ( end_x1 >= canvas.width )
end_x1 = canvas.width-1;
if ( end_x2 <= 0 )
end_x2 = 1;
if ( end_x2 > canvas.height )
start_x2 = canvas.height;
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
ctx.lineWidth=""+linewidth;
setcolor(ctx,linecolor);
if (dashed) {
ctx.setLineDash([5]);
//ctx.lineWidth="1";
}
ctx.beginPath();
ctx.moveTo(start_x1,canvas.height - start_x2);
ctx.lineTo(end_x1,canvas.height - end_x2);
ctx.stroke();
if (dashed) {
ctx.setLineDash([1, 0]);
}
if(typeof(linename) !== 'undefined') {
if (linename != "") {
var x = -10 + (end_x1 + start_x1)/2 ;
var y = canvas.height + 10 - (end_x2 + start_x2)/2 ;
if (linename.indexOf("jaxstring") == 0 ) {
// put mathjaxstring as line name
var label = document.getElementById(linename);
label.style.fontSize = "70%";
label.style.top = y + canvas.offsetTop;
label.style.left = x + canvas.offsetLeft;
label.style.visibility = "visible";
}
else {
ctx.lineWidth="1";
ctx.strokeText(linename, x, y );
}
}
}
}
}
Plot3D.prototype.polygone2D = function(x1,x2, polyname, color) {
/*
x1,x2 : arrayx of X1,X2 coordinates of all points
*/
if(typeof(color) === 'undefined') {
color = 3;
}
var i;
// loop over all points:
for (i=0;i<x1.length;i++) {
x1[i] = (x1[i] - this.viewminX1) * this.viewscaleX1;
x2[i] = (x2[i] - this.viewminX2) * this.viewscaleX2;
}
var canvas = document.getElementById(this.canvasId);
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
setcolortransparent(ctx,color, 0.5);
ctx.beginPath();
ctx.moveTo(x1[0],canvas.height - x2[0]);
for (i=0;i<x1.length;i++) {
ctx.lineTo( x1[i],canvas.height - x2[i]);
}
ctx.fill();
if(typeof(polyname) !== 'undefined') {
if (polyname != "") {
var x = -10 + x1[0];
var y = canvas.height + 10 - x2[0];
if (polyname.indexOf("jaxstring") == 0 ) {
// put mathjaxstring as line name
var label = document.getElementById(polyname);
label.style.fontSize = "70%";
label.style.top = y + canvas.offsetTop;
label.style.left = x + canvas.offsetLeft;
label.style.visibility = "visible";
}
else {
ctx.lineWidth="1";
ctx.strokeText(polyname, x, y );
}
}
}
}
}
Plot3D.prototype.disk2D = function (x1, x2, radius, spherename, color, opacity ) {
if (typeof(opacity) === 'undefined')
var opacity = 1.1;
if (typeof(radius) === 'undefined')
var radius = 5;
if ( x1 + radius >= this.viewminX1 && x1 - radius <= this.viewmaxX1 && x2 + radius >= this.viewminX2 && x2 - radius <= this.viewmaxX2 ) {
var canvas = document.getElementById(this.canvasId);
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
var x1view = ( x1-this.viewminX1 ) * this.viewscaleX1 ;
var x2view = canvas.height - ( x2 - this.viewminX2) * this.viewscaleX2;
if (opacity < 1.0 )
setcolortransparentgradient(ctx, color, opacity, Math.sqrt(x1view*x1view+x2view*x2view) + radius);
else
setcolorgradient(ctx, color, Math.sqrt(x1view*x1view+x2view*x2view) + radius);
ctx.beginPath();
ctx.arc( x1view, x2view, radius, 0, 2 * Math.PI , true);
ctx.closePath();
ctx.fill();
if(typeof(spherename) !== 'undefined') {
if (spherename != "") {
var x = -10 + x1view;
var y = 10 + x2view;
if (spherename.indexOf("jaxstring") == 0 ) {
// put mathjaxstring as line name
var label = document.getElementById(spherename);
label.style.fontSize = "70%";
label.style.top = x2view + canvas.offsetTop;
label.style.left = x1view + canvas.offsetLeft;
label.style.visibility = "visible";
}
else {
var words = spherename.split("*");
ctx.textAlign = "center"; // center of text appear at x position
var txtsize = Math.floor(0.2 * radius) ;
var tmpfont = ctx.font;
ctx.font = txtsize + "pt sans-serif";
ctx.fillStyle = "black";
if ( words.length == 1 ) {
ctx.fillText( spherename, x1view , x2view ) ;
}
else {
for (var i = 0; i< words.length; i++) {
ctx.fillText( words[i], x1view ,x2view - (words.length/2 - i - 0.5)* (1.5 * txtsize)) ;
}
}
ctx.font = tmpfont;
}
}
}
}
}
}
Plot3D.prototype.animate = function(samplingRate) {
if ( typeof(samplingRate) === 'undefined' )
var samplingRate = this.animateAuto ;
this.animateStop(); // make sure a single animation runs
var p3 = this;
this.animation = setInterval( function () {
p3.rotateZ(0.01); // cannot use "this" here => plot3
}, samplingRate
);
}
Plot3D.prototype.animateStop = function() {
if ( this.animation != null ) {
clearInterval( this.animation );
this.animation = null;
}
}
Plot3D.prototype.isInSphere = function (x, y, z, sphere) {
var dx = (x - sphere[0][0]);
var dy = (y - sphere[0][1]);
var dz = (z - sphere[0][2]);
var norm2 = dx*dx+dy*dy+dz*dz;
if ( norm2 <= sphere[1]*sphere[1] )
return true;
else
return false;
}
////////////////////////////////////////
// General canvas tools
function setcolor(ctx, color_idx) {
if( color_idx > 10 ) {
setcolortransparent(ctx, color_idx - 10, 0.5);
return;
}
switch(color_idx) {
case -1:
ctx.fillStyle = "white";
ctx.strokeStyle = "white";
break;
case 0:
ctx.fillStyle = "rgb(0,0,0)";
ctx.strokeStyle = "rgb(0,0,0)";
break;
case 1:
ctx.fillStyle = "rgb(0,0,200)";
ctx.strokeStyle = "rgb(0,0,200)";
break;
case 2:
ctx.fillStyle = "rgb(200,0,0)";
ctx.strokeStyle = "rgb(200,0,0)";
break;
case 3:
ctx.fillStyle = "rgb(0,200,0)";
ctx.strokeStyle = "rgb(0,200,0)";
break;
case 4:
ctx.fillStyle = "rgb(200,0,200)";
ctx.strokeStyle = "rgb(200,0,200)";
break;
case 5:
ctx.fillStyle = "rgb(255,255,0)";
ctx.strokeStyle = "rgb(255,255,0)";
break;
case 6:
ctx.fillStyle = "rgb(0,255,255)";
ctx.strokeStyle = "rgb(0,255,255)";
break;
case 7:
ctx.fillStyle = "rgb(102,51,0)";
ctx.strokeStyle = "rgb(102,51,0)";
break;
case 8:
ctx.fillStyle = "rgb(204,51,0)";
ctx.strokeStyle = "rgb(204,51,0)";
break;
case 9:
ctx.fillStyle = "rgb(255,102,204)";
ctx.strokeStyle = "rgb(255,102,204)";
break;
case 10:
ctx.fillStyle = "rgb(120,120,120)";
ctx.strokeStyle = "rgb(120,120,120)";
break;
default:
ctx.fillStyle = "rgb(0,0,200)";
ctx.strokeStyle = "rgb(0,0,200)";
break;
}
}
function setcolortransparent(ctx, color_idx, opacity) {
switch(color_idx) {
case 0:
ctx.fillStyle = "rgba(0,0,0," + opacity +" )";
ctx.strokeStyle = "rgba(0,0,0," + opacity +" )";
break;
case 1:
ctx.fillStyle = "rgba(0,0,200," + opacity +" )";
ctx.strokeStyle = "rgba(0,0,200," + opacity +" )";
break;
case 2:
ctx.fillStyle = "rgba(200,0,0," + opacity +" )";
ctx.strokeStyle = "rgba(200,0,0," + opacity +" )";
break;
case 3:
ctx.fillStyle = "rgba(0,200,0," + opacity +" )";
ctx.strokeStyle = "rgba(0,200,0," + opacity +" )";
break;
case 4:
ctx.fillStyle = "rgba(200,0,200," + opacity +" )";
ctx.strokeStyle = "rgba(200,0,200," + opacity +" )";
break;
case 5:
ctx.fillStyle = "rgba(255,255,0," + opacity +" )";
ctx.strokeStyle = "rgba(255,255,0," + opacity +" )";
break;
case 6:
ctx.fillStyle = "rgba(0,255,255," + opacity +" )";
ctx.strokeStyle = "rgba(0,255,255," + opacity +" )";
break;
case 7:
ctx.fillStyle = "rgba(102,51,0," + opacity +" )";
ctx.strokeStyle = "rgba(102,51,0," + opacity +" )";
break;
case 8:
ctx.fillStyle = "rgba(204,51,0," + opacity +" )";
ctx.strokeStyle = "rgba(204,51,0," + opacity +" )";
break;
case 9:
ctx.fillStyle = "rgab(255,102,204," + opacity +" )";
ctx.strokeStyle = "rgba(255,102,204," + opacity +" )";
break;
case 10:
ctx.fillStyle = "rgba(120,120,120," + opacity +" )";
ctx.strokeStyle = "rgba(120,120,120," + opacity +" )";
break;
default:
ctx.fillStyle = "rgba(0,0,200," + opacity +" )";
ctx.strokeStyle = "rgba(0,0,200," + opacity +" )";
break;
}
}
function setcolorgradient(ctx, color_idx,size) {
if ( typeof(size) === "undefined")
var size = 400 * Math.sqrt(2);
var gradient = ctx.createRadialGradient(0,0,size, 0 , 2*Math.PI, true);
gradient.addColorStop(1,"white");
switch(color_idx) {
case 0:
gradient.addColorStop(0,"rgb(0,0,0 )");
break;
case 1:
gradient.addColorStop(0,"rgb(0,0,200 )");
break;
case 2:
gradient.addColorStop(0,"rgb(200,0,0 )");
break;
case 3:
gradient.addColorStop(0,"rgb(0,200,0 )");
break;
case 4:
gradient.addColorStop(0,"rgb(200,0,200 )");
break;
case 5:
gradient.addColorStop(0,"rgb(255,255,0 )");
break;
default:
gradient.addColorStop(0,"rgb(0,0,200 )");
break;
}
ctx.fillStyle = gradient;
}
function setcolortransparentgradient(ctx, color_idx, opacity,size) {
if ( typeof(size) === "undefined")
var size = 400 * Math.sqrt(2);
var gradient = ctx.createRadialGradient(0,0,size, 0 , 2*Math.PI, true);
gradient.addColorStop(1,"white");
switch(color_idx) {
case 0:
gradient.addColorStop(0.3,"rgba(0,0,0," + opacity +" )");
gradient.addColorStop(0,"rgb(0,0,0 )");
break;
case 1:
gradient.addColorStop(0.3,"rgba(0,0,200," + opacity +" )");
gradient.addColorStop(0,"rgb(0,0,200 )");
break;
case 2:
gradient.addColorStop(0.3,"rgba(200,0,0," + opacity +" )");
gradient.addColorStop(0,"rgb(200,0,0 )");
break;
case 3:
gradient.addColorStop(0.3,"rgba(0,200,0," + opacity +" )");
gradient.addColorStop(0,"rgb(0,200,0 )");
break;
case 4:
gradient.addColorStop(0.3,"rgba(200,0,200," + opacity +" )");
gradient.addColorStop(0,"rgb(200,0,200 )");
break;
case 5:
gradient.addColorStop(0.3,"rgba(255,255,0," + opacity +" )");
gradient.addColorStop(0,"rgb(255,255,0 )");
break;
default:
gradient.addColorStop(0.3,"rgba(0,0,200," + opacity +" )");
gradient.addColorStop(0,"rgb(0,0,200 )");
break;
}
ctx.fillStyle = gradient;
}