Was bisher anscheinend nicht erwähnt wurde, sind die Konzepte eines instabilen Algorithmus und eines schlecht konditionierten Problems . Ich werde zuerst auf die ersteren eingehen, da dies eine häufigere Gefahr für unerfahrene Numeriker darstellt.
Betrachten Sie die Berechnung der Potenzen des (reziproken) goldenen Schnitts φ=0.61803…
. Eine Möglichkeit ist die Verwendung der Rekursionsformel φ^n=φ^(n-2)-φ^(n-1)
, beginnend mit φ^0=1
und φ^1=φ
. Wenn Sie diese Rekursion in Ihrer bevorzugten Computerumgebung ausführen und die Ergebnisse mit genau bewerteten Leistungen vergleichen, werden Sie eine langsame Erosion signifikanter Zahlen feststellen. Folgendes passiert zum Beispiel in Mathematica :
ph = N[1/GoldenRatio];
Nest[Append[#1, #1[[-2]] - #1[[-1]]] & , {1, ph}, 50] - ph^Range[0, 51]
{0., 0., 1.1102230246251565*^-16, -5.551115123125783*^-17, 2.220446049250313*^-16,
-2.3592239273284576*^-16, 4.85722573273506*^-16, -7.147060721024445*^-16,
1.2073675392798577*^-15, -1.916869440954372*^-15, 3.1259717037102064*^-15,
-5.0411064211886014*^-15, 8.16837916750579*^-15, -1.3209051907825398*^-14,
2.1377864756200182*^-14, -3.458669982359108*^-14, 5.596472721011714*^-14,
-9.055131861349097*^-14, 1.465160458236081*^-13, -2.370673237795176*^-13,
3.835834102607072*^-13, -6.206507137114341*^-13, 1.004234127360273*^-12,
-1.6248848342954435*^-12, 2.6291189633497825*^-12, -4.254003796798193*^-12,
6.883122762265558*^-12, -1.1137126558640235*^-11, 1.8020249321541067*^-11,
-2.9157375879969544*^-11, 4.717762520172237*^-11, -7.633500108148015*^-11,
1.23512626283229*^-10, -1.9984762736468268*^-10, 3.233602536479646*^-10,
-5.232078810126407*^-10, 8.465681346606119*^-10, -1.3697760156732426*^-9,
2.216344150333856*^-9, -3.5861201660070964*^-9, 5.802464316340953*^-9,
-9.388584482348049*^-9, 1.5191048798689004*^-8, -2.457963328103705*^-8,
3.9770682079726053*^-8, -6.43503153607631*^-8, 1.0412099744048916*^-7,
-1.6847131280125227*^-7, 2.725923102417414*^-7, -4.4106362304299367*^-7,
7.136559332847351*^-7, -1.1547195563277288*^-6}
Das angebliche Ergebnis für φ^41
hat das falsche Vorzeichen, und noch früher haben die berechneten und tatsächlichen Werte für φ^39
keine gemeinsamen Ziffern ( 3.484899258054952
* ^ - 9 for the computed version against the true value
7.071019424062048 *^-9
). Der Algorithmus ist daher instabil, und man sollte diese Rekursionsformel nicht in ungenauer Rechnung verwenden. Dies liegt an der inhärenten Natur der Rekursionsformel: Es gibt eine "abklingende" und "wachsende" Lösung für diese Rekursion und der Versuch, die "abklingende" Lösung durch Vorwärtslösung zu berechnen, wenn es eine alternative "wachsende" Lösung gibt für numerische Trauer. Man sollte also sicherstellen, dass seine numerischen Algorithmen stabil sind.
Nun zum Konzept eines schlecht konditionierten Problems: Auch wenn es einen stabilen Weg gibt, etwas numerisch zu tun, kann es durchaus sein, dass das Problem, das Sie gerade haben, von Ihrem Algorithmus nicht gelöst werden kann. Dies liegt am Problem selbst und nicht an der Lösungsmethode. Das kanonische Beispiel in der Numerik ist die Lösung linearer Gleichungen mit der sogenannten "Hilbert-Matrix":
Die Matrix ist das kanonische Beispiel für eine schlecht konditionierte Matrix: Wenn Sie versuchen, ein System mit einer großen Hilbert-Matrix zu lösen, erhalten Sie möglicherweise eine ungenaue Lösung.
Hier ist eine Mathematica- Demonstration: Vergleichen Sie die Ergebnisse der exakten Arithmetik
Table[LinearSolve[HilbertMatrix[n], HilbertMatrix[n].ConstantArray[1, n]], {n, 2, 12}]
{{1, 1}, {1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1, 1}, {1, 1, 1, 1, 1,
1}, {1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1,
1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}}
und ungenaue Arithmetik
Table[LinearSolve[N[HilbertMatrix[n]], N[HilbertMatrix[n].ConstantArray[1, n]]], {n, 2, 12}]
{{1., 1.}, {1., 1., 1.}, {1., 1., 1., 1.}, {1., 1., 1., 1., 1.},
{1., 1., 1., 1., 1., 1.}, {1., 1., 1., 1., 1., 1., 1.},
{1., 1., 1., 1., 1., 1., 1., 1.}, {1., 1., 1., 1., 1., 1., 1., 1., 1.},
{1., 1., 1., 0.99997, 1.00014, 0.999618, 1.00062, 0.9994, 1.00031,
0.999931}, {1., 1., 0.999995, 1.00006, 0.999658, 1.00122, 0.997327,
1.00367, 0.996932, 1.00143, 0.999717}, {1., 1., 0.999986, 1.00022,
0.998241, 1.00831, 0.975462, 1.0466, 0.94311, 1.04312, 0.981529,
1.00342}}
(Wenn Sie es in Mathematica ausprobiert haben , werden Sie einige Fehlermeldungen bemerken, die auf eine schlechte Konditionierung hinweisen.)
In beiden Fällen ist es keine Heilung, einfach die Präzision zu erhöhen. es wird nur die unvermeidliche Erosion von Zahlen verzögern.
Dies ist, was Sie konfrontiert werden könnten. Die Lösungen könnten schwierig sein: Zum einen gehen Sie entweder zurück zum Zeichenbrett oder stöbern in Zeitschriften / Büchern / was auch immer, um herauszufinden, ob jemand anderes eine bessere Lösung gefunden hat als Sie; Zum anderen geben Sie das Problem entweder auf oder formulieren es neu, sodass es leichter zu lösen ist.
Ich werde Sie mit einem Zitat von Dianne O'Leary verlassen:
Das Leben wirft uns vielleicht ein paar schlecht konditionierte Probleme zu, aber es gibt keinen guten Grund, sich mit einem instabilen Algorithmus zufrieden zu geben.