<!--Define JavaScript functions.-->

function solaxbr(dataForm){			
  // Main program for solving the system Ax = b.
  // Assumes all entries are real numbers.
  // Gets input from a textarea box via sub-routine tinabr.
  
 var MAXDIM = 12;           // Maximum size, N, of system accepted by this script.

 var dataFormElements = dataForm.elements; // Reference to the form elements array.
 var textareaIndex = 0;  // The form array index for the textarea element
 var textareaString = "";
 
 var MATRIXDIM = 0;	// The dimension, N, of the system to be entered.
 var inverseAFlag = 0;	// Assume determinant AND inverse will be computed
 var dummy;			// Float variable

 var A = new Array(MAXDIM);
 var PMatrix = new Array(MAXDIM);		// Permutation Matrix
 var LowerMatrix = new Array(MAXDIM);		// Lower Matrix
 var UpperMatrix = new Array(MAXDIM);		// Upper Matrix
 var b = new Array(MAXDIM);
 var ipvt = new Array(MAXDIM);			// Vector for keeping track of permutations
 
 for (var i = 0; i < MAXDIM; i++){	// Create the square Matrices
   A[i] = new Array(MAXDIM);
   PMatrix[i] = new Array(MAXDIM);
   LowerMatrix[i] = new Array(MAXDIM);
   UpperMatrix[i] = new Array(MAXDIM);
   } // End of for i loop
   
 // strPar is a dummy variable for passing the output string by reference  
 var strPar = new Object();
 strPar.outmsgstr = "";
 
 // inputPar is a dummy variable for passing input parameters by reference
 var inputPar = new Object();
 inputPar.mDim = 0;
 inputPar.inEr = 0;
 
 // outputPar is a dummy variable for passing output parameters by reference
 var outputPar = new Object();
 outputPar.rcond = 0;			// The condition number
 outputPar.outEr = 0;			// Error code
 
 // detOPar is a dummy variable for passing determinant parameters by reference
 var detOPar = new Object();
 detOPar.det1 = 1.0;
 detOPar.det2 = 0.0;

 document.getElementById('output').innerHTML = "";
 
 textareaString = textareaString + dataFormElements[textareaIndex].value;
 
 // Pass the raw array into the sub-routine tinabr for processing.
 tinabr(textareaString, inputPar, A, b);

 if (inputPar.inEr != 0) return;
 
 MATRIXDIM = inputPar.mDim;
 
 //  *******************************************************************
 // At this point, MATRIXDIM should be the matrix dimension 
 // and the A and b matrices should contain their appropriate values.
 //  ********************************************************************

saxbr(MATRIXDIM, A, b, ipvt, outputPar);

 //  *******************************************************************
 // At this point, the original A matrix has been overwritten by 
 // coefficients of the LU decomposition and b contains the solution vector, x.
 //  ********************************************************************

strPar.outmsgstr = "<br /> &nbsp; &nbsp; The <b>x</b> vector components follow: <br /> &nbsp; &nbsp;";
realVecOut(MATRIXDIM, b, strPar);

strPar.outmsgstr = strPar.outmsgstr + "<br /> &nbsp; &nbsp; Error Code &nbsp; = &nbsp; " + outputPar.outEr + "<br /> &nbsp; &nbsp;";

strPar.outmsgstr = strPar.outmsgstr + " rcond &nbsp; = &nbsp; " + outputPar.rcond + "<br /> &nbsp; &nbsp;";

// Initialize the P, L, and U Matrices

for (var i = 0; i < MATRIXDIM; i++){
  for (var j = 0; j < MATRIXDIM; j++){
    if (j >= i) {
      UpperMatrix[i][j] = A[i][j];
      if (j == i)  PMatrix[i][j] = LowerMatrix[i][j] = 1.0;
      else  PMatrix[i][j] = LowerMatrix[i][j] = 0.0;
    } // End if (j >= i)
    else {   // j < i
      PMatrix[i][j] = UpperMatrix[i][j] = 0.0;
      LowerMatrix[i][j] = -A[i][j];
    } // End else j < i
  } // End for j loop
} // End for i loop

if ((1.0 + outputPar.rcond) == 1.0) inverseAFlag = 1; // Compute determinant only

calcdetAr(MATRIXDIM, A, ipvt, detOPar, inverseAFlag);

strPar.outmsgstr = strPar.outmsgstr + " The determinant of [A] &nbsp; = &nbsp; " + (detOPar.det1)*Math.pow(10.0,(detOPar.det2)) + "<br /> &nbsp; &nbsp;";

// The following code block is extra to SGEFS, to explicitly output the [P], [L], and [U] Matrices.
// ************************************************************************

// Rearrange the L Matrix according to ipvt

for (var i = 1; i < (MATRIXDIM - 1); i++){
  if (ipvt[i] != i){
    for (var j = 0; j < i; j++) {
	dummy = LowerMatrix[i][j];
        LowerMatrix[i][j] = LowerMatrix[ipvt[i]][j];
        LowerMatrix[ipvt[i]][j] = dummy;
    } // End for j loop
  } // End if (ipvt[i] != i)
} // End for i loop

// Rearrange the P Matrix according to ipvt
for (var i = (MATRIXDIM - 1); i >= 0; i--){  // Make sure to do ONE LESS loop than matrix dimension
  if (ipvt[i] != i){  // Swap the rows
    for (var j = 0; j < MATRIXDIM; j++){
      dummy = PMatrix[i][j];
      PMatrix[i][j] = PMatrix[ipvt[i]][j];
      PMatrix[ipvt[i]][j] = dummy;
    } // End for j
  } // End if (ipvt[i] != i)
} // End for i

// End of extra code block to explicitly define the [P][L][U] Matrices.
// ************************************************************************

strPar.outmsgstr = strPar.outmsgstr + "<br /> &nbsp; &nbsp; The <b>[U]</b> Matrix components follow: <br /> &nbsp; &nbsp;";
sqmrOut(MATRIXDIM, UpperMatrix, strPar);

strPar.outmsgstr = strPar.outmsgstr + "<br /> &nbsp; &nbsp; The <b>[L]</b> Matrix components follow: <br /> &nbsp; &nbsp;";
sqmrOut(MATRIXDIM, LowerMatrix, strPar);

strPar.outmsgstr = strPar.outmsgstr + "<br /> &nbsp; &nbsp; The <b>[P]</b> Matrix components follow: <br /> &nbsp; &nbsp;";
sqmrOut(MATRIXDIM, PMatrix, strPar);

if (inverseAFlag > 0){ 
  strPar.outmsgstr = strPar.outmsgstr + "<br /> &nbsp; &nbsp; rcond indicates A near singular so A-inverse not computed. <br /> &nbsp; &nbsp;";
} //End if (inverseAFlag > 0)
else {
  strPar.outmsgstr = strPar.outmsgstr + "<br /> &nbsp; &nbsp; <b>[A]</b> inverse components follow: <br /> &nbsp; &nbsp;";
  sqmrOut(MATRIXDIM, A, strPar);
} 

document.getElementById('output').innerHTML = strPar.outmsgstr;

return;
}  //End of solaxbr

// end of JavaScript-->