Rundungsfehler bei der Matrixeninversion



  • Hallo!
    Ich muss für die FH ein Programm schreiben, dass die Inverse einer Matrix mittels Austauschverfahren berechnet und diese Inverse dann prüfen mittels der Einheitsmatrix:

    A(Ursprungsmatrix) * B(inverse Matrix) = Einheitsmatrix

    Die Einheitsmatrix stimmt allerdings aufgrund Rundungsfehler im System nicht genau...es kommt also nicht
    1 0 0
    0 1 0
    0 0 1
    raus, sondern zum Beispiel:

    1 -1,152364E-16 0
    0 1,0000000001 -4,2563978E-15
    0 0 1

    Wie kann ich das beheben?



  • Mit einem Format-Specifier: ToString("F5")
    (Fixed point mit 5 Nachkommastellen)

    Bei störenden Nullen am Ende noch ein .TrimEnd('0') anhängen.



  • Dan invertiere B nochmal und bestimme den Abstand der Werte zu A, danach invertiere das invertierte von B nochmal und bestimme den Abstand zu B,..

    Dann hast Du doch Deine Rundungsfehler,...

    Und Ausserdem gilt
    BAB=(BA)B=EB=BBAB=(BA)B=EB=B

    d.h. Du kannst auch den Linksseitigen Fehler ermitteln und entsprechende Korrekturen vornehmen...

    Sei gegrüßt



  • zeusosc schrieb:

    Dan invertiere B nochmal und bestimme den Abstand der Werte zu A, danach invertiere das invertierte von B nochmal und bestimme den Abstand zu B,..

    Dann hast Du doch Deine Rundungsfehler,...

    Mit solchen Tricks macht man es nur noch schlimmer. Das ist auch kein Wunder, wenn der Abstand genau in den letzten signifikaten Stellen rumkrebst und die Anzahl signifikanter Stellen mit jeder Invertierung abnehmen kann.

    int size = 15;
    
    Matrix A = new Matrix(size, size);
    
    for (int i = 0; i < size; ++i)
    	for (int j = 0; j < size; ++j)
    		A[i, j] = 1.0 / (i + j + 1);
    
    Matrix B = Matrix.Inverse(A);
    Matrix C = Matrix.Inverse(B); 
    
    Matrix Error = C - A;
    
    //Bisschen fragwürdig. Kann man auch weglassen mit keinem anderen Ergebniss
    for (int i = 0; i < size; ++i)
    	for (int j = 0; j < size; ++j)
    		Error[i, j] = Math.Abs(Error[i, j]);
    
    //"Fehlerkorrektur". C war zweimal invertiert und Annahme linearer 
    //Fehlerfortpflanzung. Also halben Error abziehen
    Matrix CorrectedB = B - 0.5 * Error;
    
    Matrix X = new Matrix(Matrix.Identity(size)) -  A * CorrectedB;
    Matrix Y = new Matrix(Matrix.Identity(size)) -  A * B;
    
    double ErrorWithCorrectedB = 0;
    double ErrorWithNormalB = 0;
    for (int i = 0; i < size; ++i)
    	for (int j = 0; j < size; ++j)
    	{
    		ErrorWithCorrectedB += Math.Abs(X[i, j]);
    		ErrorWithNormalB += Math.Abs(Y[i, j]);
    	}
    
    if (ErrorWithCorrectedB > ErrorWithNormalB)
    	Console.WriteLine("--- verschlimmbessert ---");
    

    (Advanced Matrix Library in C#. NET von CodeProject)


Anmelden zum Antworten