IEnumerable <Tuple <Vector, Vector> > Combine(Matrix M1, Matrix M2) { Debug.Assert(M1.CountLines == M2.CountLines); for (int i = 0; i < M1.CountLines; i++) { yield return(new Tuple <Vector, Vector>(M1.Line(i), M2.Line(i))); } }
/// <summary> /// Matrix wird in Dreiecksform gebracht /// </summary> /// <param name="countColsToNormalize">Anzahl der zu normalisierenden Spalen</param> /// <returns></returns> public Matrix Dreieck(int countColsToNormalize) { Matrix M = new Matrix(this); for (int col = 0; col < countColsToNormalize; col++) { // Zeile mit Koeff != 0 in der zu normalisierenden Spalte suchen int line; for (line = 0; line < M.CountLines; line++) { if ((col == 0 || M[line, col - 1] == 0) && M[line, col] != 0) { break; } } if (line < M.CountLines) { Vector normLine = M.Line(line) * (1.0 / M[line, col]); normLine[col] = 1.0; // Alle restlichen Zeilen in der Matrix umformen, so daß in der Spalte nur eine 1 stehen bleibt for (int line2 = 0; line2 < M.CountLines; line2++) { for (int col2 = 0; col2 < M.Dimensions; col2++) { if (line == line2) { M[line2, col2] = normLine[col2]; } else { M[line2, col2] -= normLine[col2] * M[line2, col2]; } } } } } return(M); }
/// <summary> /// Invertierung nach Austauschverfahren (Pivot) /// y = M x -> x = MInv y /// </summary> /// <param name="Minv"></param> /// <returns></returns> public bool Invert(out Matrix Minv) { Minv = new Matrix(this); int[] ixX = IndexGenerator(Dimensions).ToArray(); bool[] Xchanged = BoolFieldGenerator(false, Dimensions).ToArray(); int[] ixY = IndexGenerator(CountLines).ToArray(); bool[] Ychanged = BoolFieldGenerator(false, Dimensions).ToArray(); int pivotC = 0, pivotL = 0; try { // Tauschen aller x gegen alle y for (pivotC = 0; pivotC < Math.Min(this.Dimensions, this.CountLines); pivotC++) { // Suchen in aktueller Spalte nach einem Koeff für eine Zeile, deren y noch nicht getauscht wurde pivotL = ColAsTriple(Minv, pivotC, Ychanged).Where(line => line.Item2 != 0 && !line.Item3).First().Item1; // x und y tauschen. Tausch protokollieren int tausch = ixX[pivotC]; ixX[pivotC] = ixY[pivotL]; ixY[pivotL] = tausch; Xchanged[pivotC] = Ychanged[pivotL] = true; // Inversion in Hilfsmatrix durchführen Matrix M2 = new Matrix(Minv); double p = Minv[pivotC, pivotL]; M2.SetLine(pivotL, Minv.Line(pivotL) * (-1 / p)); M2.SetColumn(pivotC, Minv.Column(pivotC) * (1 / p)); M2[pivotL, pivotC] = 1 / p; for (int line = 0; line < Dimensions; line++) { if (line != pivotL) { for (int col = 0; col < Dimensions; col++) { if (col != pivotC) { M2[line, col] = Minv[line, col] + -Minv[line, pivotC] * Minv[pivotL, col] / p; } } } } // Hilfsmatrix zur neuen gültigen erklären Minv = M2; } // Umsortieren der Zeilen Matrix M3 = new Matrix(Minv.CountLines, Minv.Dimensions); for (int line = 0; line < CountLines; line++) { M3.SetLine(ixY[line], Minv.Line(line)); } Matrix M4 = new Matrix(Minv.CountLines, Minv.Dimensions); for (int col = 0; col < Dimensions; col++) { M4.SetColumn(ixX[col], M3.Column(col)); } Minv = M4; } catch (Exception) { return(false); } // Reihenfolge wiederherstellen return(true); }