/// <summary> /// This function executes the backward reduction algorithm provided in /// the assignment text given an augmented matrix in row Echelon form. /// </summary> /// /// <param name="a"> /// An N-by-M augmented matrix in row Echelon form. /// </param> /// /// <returns> /// The resulting N-by-M matrix after executing the algorithm. /// </returns> public static Matrix BackwardReduction(this Matrix a) { Vector pRow = new Vector(0); int pRowIndex = -1; int uCol = -1; // Finds pivot row for (int i = a.M_Rows - 1; i >= 0; i--) { pRow = a.Row(i); if (BasicExtensions.IsZeroVector(pRow)) { continue; } pRowIndex = i; uCol = BasicExtensions.FirstValueIndex(pRow); break; } // Scale pivot row to 1 a.ElementaryRowScaling(pRowIndex, 1.0 / pRow[uCol]); // Using pivot row to reduce entries to zero for (int i = 0; i < a.M_Rows; i++) { if (i == pRowIndex) { break; } a.ElementaryRowReplacement(i, -a[i, uCol], pRowIndex); } // If this was the last row to be scaled end of recursion is reached. if (a.M_Rows - 1 <= 0) { return(a); } // step 2 forming submatrix to process other rows. Last row of a is excluded. Vector[] subMatrixVectors = new Vector[a.M_Rows - 1]; for (int i = 0; i < subMatrixVectors.Length; i++) { subMatrixVectors[i] = a.Row(i); } Matrix subMatrix = BasicExtensions.VectorCombine(subMatrixVectors); subMatrix = subMatrix.BackwardReduction(); Vector[] retVectors = new Vector[a.M_Rows]; retVectors[a.M_Rows - 1] = a.Row(a.M_Rows - 1); for (int i = 0; i < a.M_Rows - 1; i++) { retVectors[i] = subMatrix.Row(i); } return(BasicExtensions.VectorCombine(retVectors)); }
/// <summary> /// This function executes the forward reduction algorithm provided in /// the assignment text to achieve row Echelon form of a given /// augmented matrix. /// </summary> /// /// <param name="a"> /// An N-by-M augmented matrix. /// </param> /// /// <returns> /// An N-by-M matrix that is the row Echelon form. /// </returns> public static Matrix ForwardReduction(this Matrix a) { // If submatrix has zero rows, end of recursion is reached if (a.M_Rows - 1 <= 0) { return(a); } Vector colJ = new Vector(0); var pRow = -1; // step 1 locate pivot column for (var colLoop = 0; colLoop < a.N_Cols; colLoop++) { colJ = a.Column(colLoop); if (BasicExtensions.IsZeroVector(colJ)) { continue; } // step 2 find first non-zero entry pRow = BasicExtensions.FirstValueIndex(colJ); break; } // if all rows are zero rows end of recursion is reached. if (pRow == -1) { return(a); } // step 2 reduction a.ElementaryRowInterchange(0, pRow); for (var i = 1; i < colJ.Size; i++) { a.ElementaryRowReplacement(i, (-colJ[i] / colJ[0]), 0); } // step 3 forming submatrix. Vector[] subMatrixVectors = new Vector[a.M_Rows - 1]; for (int i = 1; i < a.M_Rows; i++) { subMatrixVectors[i - 1] = a.Row(i); } Matrix subMatrix = BasicExtensions.VectorCombine(subMatrixVectors); // applying steps 1 and 2 on submatrix subMatrix = subMatrix.ForwardReduction(); // building return matrix with vectors Vector[] retVectors = new Vector[a.M_Rows]; retVectors[0] = a.Row(0); for (int i = 1; i < a.M_Rows; i++) { retVectors[i] = subMatrix.Row(i - 1); } return(BasicExtensions.VectorCombine(retVectors)); }