// Matrix reduction
this.reducedValues = this.values;
this.reducedErrors = this.errors;
Matrix matv0 = new Matrix(this.reducedValues);
Matrix mate0 = new Matrix(this.reducedErrors);
int nn = this.diagonalLength - 1;
for(int i=0; i<nn; i++){
matv0 = new Matrix(this.reducedValues);
// Isolate sub-matrix
int nrow = this.numberOfRows-i;
int ncol = this.numberOfColumns - i;
Matrix mat1 = matv0.getSubMatrix(i, i, this.numberOfRows-1, numberOfColumns-1);
double[][] subv = mat1.getArrayCopy();
// Get pivot indices
int[] max = mat1.pivot();
int pivotI = max[0]+i;
int pivotJ = max[1]+i;
// Swap rows
double[] holdv1 = this.reducedValues[i];
double[] holde1 = this.reducedErrors[i];
this.reducedValues[i] = this.reducedValues[pivotI];
this.reducedErrors[i] = this.reducedErrors[pivotI];
this.reducedValues[pivotI] = holdv1;
this.reducedErrors[pivotI] = holde1;
// Swap columns
double holdv2 = 0.0;
double holde2 = 0.0;
for(int j=0; j<numberOfRows; j++){
holdv2 = this.reducedValues[j][i];
holde2 = this.reducedErrors[j][i];
this.reducedValues[j][i] = this.reducedValues[j][pivotJ];
this.reducedErrors[j][i] = this.reducedErrors[j][pivotJ];
this.reducedValues[j][pivotJ] = holdv2;
this.reducedErrors[j][pivotJ] = holde2;
}
// Reduce sub-matrix
Matrix matValueHold = new Matrix(this.reducedValues);
Matrix matErrorHold = new Matrix(this.reducedErrors);
double[][] valueHold = matValueHold.getArrayCopy();
double[][] errorHold = matErrorHold.getArrayCopy();
for(int j=i+1; j<this.numberOfRows; j++){
for(int k=i; k<this.numberOfColumns; k++){
double ratio1 = 1.0;
if(this.reducedValues[j][i]!=this.reducedValues[i][i])ratio1 = this.reducedValues[j][i]/this.reducedValues[i][i];
valueHold[j][k] = this.reducedValues[j][k] - ratio1*this.reducedValues[i][k];
double hold = this.reducedErrors[j][k] + this.reducedErrors[i][k]*ratio1*ratio1;
double ratio2 = 1.0;
if(this.reducedValues[i][k]!=this.reducedValues[i][i])ratio2 = this.reducedValues[i][k]/this.reducedValues[i][i];
hold += this.reducedErrors[j][i]*ratio2*ratio2;
errorHold[j][k] = hold + this.reducedErrors[i][i]*ratio1*ratio1*ratio2*ratio2;
}
}
matValueHold = new Matrix(valueHold);
matErrorHold = new Matrix(errorHold);
this.reducedValues = matValueHold.getArrayCopy();
this.reducedErrors = matErrorHold.getArrayCopy();
}
// Convert errors to standard deviations
for(int i=0; i<this.numberOfRows; i++){
for(int j=0; j<this.numberOfColumns; j++){