public static Matrix <T> ToEchelonForm <T>( this Matrix <T> m, Func <T> constructor, int toIgnore = 0) where T : FieldMember, new() { Matrix <T> n = m.ToSortedForm(constructor); int from = -1; // Put the rows in echelon form (some substitution will be required) while (!n.IsEchelon(constructor, toIgnore)) { from++; // Substitution can unsort the rows if (!n.IsSorted(constructor, toIgnore)) { n = n.ToSortedForm(constructor, toIgnore); } List <int> rows = Enumerable.Range(from + 1, n.Height - n.AmountOfNullRows(toIgnore) - from - 1).ToList(); int pivot = n.GetPivot(from, constructor, toIgnore); foreach (var to in rows) { if (n.GetPivot(from, constructor, toIgnore) < n.GetPivot(to, constructor, toIgnore)) { continue; } if (n.GetPivot(from, constructor, toIgnore) == n.GetPivot(to, constructor, toIgnore)) { try { T scale = n[to, pivot].Negative <T>().Multiply(n[from, pivot].Inverse <T>()); RowOperation <T> .SubstitutionOperation(from, to, scale).ActOn(n); } catch (IncompatibleOperationException) { throw new ImpossibleEchelonFormException(); } } if (n.GetPivot(from, constructor, toIgnore) > n.GetPivot(to, constructor, toIgnore) && n.GetPivot(to, constructor, toIgnore) != -1) { RowOperation <T> .SwitchingOperation(from, to).ActOn(n); } } } return(n); }
/// <summary> /// Convert the Matrix to reduced echelon form /// </summary> /// <param name="m"></param> /// <param name="constructor">The constructor to make a null instance of T</param> /// <param name="toIgnore">The amount of rows that needn't be considered when converting.</param> /// <returns></returns> public static Matrix <T> ToReducedEchelonForm <T>( this Matrix <T> m, Func <T> constructor, int toIgnore = 0) where T : FieldMember, new() { // First convert to normal echelon form Matrix <T> n = m.ToUnitPivots(constructor, toIgnore); int from = n.Height - n.AmountOfNullRows(toIgnore); // Put the rows in echelon form (some substitution will be required) while (!n.IsReducedEchelon(constructor, toIgnore)) { from--; List <int> rows = Enumerable.Range(0, from).ToList(); // Go from the bottom to the top rows.Reverse(); int pivot = n.GetPivot(from, constructor, toIgnore); foreach (var to in rows) { if (!n[to, pivot].IsNull()) { try { T scale = n[to, pivot].Negative <T>().Multiply(n[from, pivot].Inverse <T>()); RowOperation <T> .SubstitutionOperation(from, to, scale).ActOn(n); } catch (IncompatibleOperationException) { throw new ImpossibleEchelonFormException(); } } } } return(n); }