Grundlagenpraktikum V30: Grundlagen Der Rechnerarithmetik Technische Universität Hamburg-Harburg Institut für Zuverlässiges Rechnen http://www.ti3.tu-harburg.de/RechArith/index.html Stand: 05. April 2006 Inhaltsverzeichnis 1 Einleitung 1 2 Gleitpunktarithmetik 1 2.1 Gleitpunktzahlen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 2.2 Rundung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 2.3 Die arithmetischen Operationen für Gleitpunktzahlen . . . . . . . . . . . . . . . . . . . . . . 5 2.4 Bemerkungen und Beispiele . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 2.5 Fehlerfortpflanzung während der Rechnung . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 3 Kondition eines Problems und Kondition eines Verfahrens 10 4 Fehleranalyse 12 5 Ausblick und Literatur 15 6 Versuchsbeschreibung und -durchführung 17 7 Auswertung und Überlegungen 19 8 Kurzeinführung MATLAB 19 1 Einleitung Elektronische Rechenanlagen werden in immer stärkerem Maße zur Problemlösung in Industrie und Wissenschaft eingesetzt. Bei all diesen Problemen verarbeiten numerische Algorithmen gemäß einer Rechenvorschrift numerische Daten auf einem Rechner. Diese Rechner arbeiten in fast allen Fällen mit der Gleitpunktarithmetik. Die üblichen elementaren Rechenoperationen +, −, ·, / werden durch die auf dem Rechner implemen· ,3 / für Gleitpunktzahlen ersetzt. Diese Operationen stimmen jedoch mit den −, 3 +,3 tierten Operationen 3 exakten Operationen +, −, ·, / nur näherungsweise überein. Daher sind Zweifel angebracht, ob die durch den Rechner erzielten Ergebnisse immer richtig sind, wenn Millionen von Rechenoperationen durchgeführt werden. Diese Zweifel werden dadurch verstärkt, daß schon bei kleinsten Aufgabenstellungen falsche Resultate berechnet werden können. Betrachten wir zum Beispiel die Summe 1050 + 812 − 1050 + 1035 + 511 − 1035 = 1323. (1) Summiert man diese Zahlen auf einer elektronischen Rechenanlage auf, so wird man in aller Regel den Wert 0 erhalten. Es wird Ihnen leichtfallen, die Ursachen für diesen Fehler zu erkennen, wenn Sie im Umgang mit Rechnern vertraut sind. Etwas subtiler ist die Auswertung des Polynoms 170.4x3 − 356.41x2 + 168.97x + 18.601 (2) an der Stelle x = 1.091608. Der exakte Wert für dieses Polynom an dieser Stelle ist 8.21248 · 10−14 . Fast alle Rechner liefern hier falsche Resultate. Viele weitere Beispiele werden Sie im Verlauf des Praktikums kennenlernen. Aber schon diese beiden sehr einfachen Beispiele machen deutlich, daß die weitverbreitete Rechnergläubigkeit fehl am Platz ist: Die Resultate, die der Rechner liefert, müssen“ oder (in der abge” schwächten Form) werden schon stimmen“. Es stellen sich hier die Fragen: ” • Warum liefern Rechner in gewissen Situationen falsche Ergebnisse? • Welchen arithmetischen Gesetzen genügen Rechner? Offenbar gehorchen sie nicht den Gesetzen, die wir kennen. • Sind diese Beispiele Ausnahmen? Sind sie Anomalien? • Wie kann man solche Beispiele erkennen und klassifizieren? Als zukünftiger Ingenieur werden Sie während Ihres Studiums und voraussichtlich in Ihrem späteren Beruf mit der Programmierung von Computern bzw. mit der Benutzung vorhandener Programmpakete konfrontiert werden. Dieses Praktikum soll Ihnen helfen, Ergebnisse, die ein Rechner erzielt, richtig zu beurteilen und nicht von vornherein als mathematisch bewiesen zu akzeptieren. Sie werden die Grundlagen der implementierten Rechnerarithmetiken, gut und schlecht konditionierte Probleme und Algorithmen kennenlernen. Die damit verbundenen theoretischen Überlegungen und einige Anschauungsbeispiele werden im folgenden als Vorbereitung auf das Praktikum geschildert. Ziel ist es, die Phänomene, die bei schlecht konditionierten Problemen bzw. Algorithmen in Verbindung mit der zugrunde liegenden Rechnerarithmetik auftreten, im praktischen Versuch auf unterschiedlichen Rechnern zu demonstrieren und zu verstehen. 2 Gleitpunktarithmetik Für ein grundlegendes Verständnis ist es wichtig zu wissen, wie üblicherweise auf einem Rechner Zahlen dargestellt werden und wie mit ihnen gerechnet wird. 1 2.1 Gleitpunktzahlen Es gibt viele verschiedene Methoden, reelle Zahlen durch ein endliches System von Zahlen auf einem Rechner zu approximieren. Auf fast allen elektronischen Rechenanlagen benutzt man heute die sogenannte Gleitpunktdarstellung (floating point) von Zahlen. Diese Darstellung basiert auf der Tatsache, daß für jede reelle Zahl x ∈ IR gilt: k X x=± mi bi mit 0 ≤ mi ≤ b − 1, mi ∈ IN. (3) i=−∞ Dabei heißt b ∈ IN Basis. Ist b gleich 2, 8, 10 bzw. 16, so spricht man von einer Dual-, Oktal-, Dezimal- bzw. Hexadezimaldarstellung. Beispielsweise besitzt 18.5 die Dezimal- und Dualdarstellungen 18.5 = 1·101 + 8·100 + 5·10−1 = 1·24 + 0·23 + 0·22 + 1·21 + 0·20 + 1·2−1 . Auf einem Rechner können natürlich nur endlich viele Ziffern gespeichert werden. Daher arbeitet eine Rechenanlage üblicherweise mit normalisierten Gleitpunktzahlen: x = ±m·be mit m = l−1 X mi b−i i=0 (4) mi ∈ IN, 0 ≤ mi ≤ b − 1, m0 6= 0 und E1 ≤ e ≤ E2 , e ∈ ZZ, m heißt Mantisse, l Mantissenlänge und e Exponent. Die Zahl 18.5 besitzt demnach die dezimale bzw. duale normalisierte Gleitpunktdarstellung 18.5 = 1.85·101 = (1·100 + 8·10−1 + 5·10−2 ) · 101 = 1.00101·24 = (1·20 + 0·2−1 + 0·2−2 + 1 · 2−3 + 0·2−4 + 1·2−5 ) · 24 . Auf den meisten Rechnern werden die normalisierten Gleitpunktzahlen zur Basis b = 2 dargestellt. In diesem Fall ist 1 ≤ m < 2, da m0 6= 0. Einige Rechner erlauben auch Dezimaldarstellungen (1 ≤ m < 10), ebenso sind Hexadezimaldarstellungen auf einigen Rechenanlagen (IBM, Telefunken) üblich. Die auf einem Rechner darstellbaren Zahlen nennt man auch Maschinenzahlen. Um die Portabilität von Algorithmen und die Vergleichbarkeit von Ergebnissen auf verschiedenen Rechenanlagen zu erhöhen, wurde vom IEEE ein Standardisierungsvorschlag für die binäre Gleitpunktarithmetik ausgearbeitet [3]. Dieser spezifiziert • die Zahlenformate, • Anforderungen an die Genauigkeit der Operationen und der Konvertierung von Dezimalzahlen in die Binärdarstellung und zurück, • die Fehlerzustände zur Ausnahmebehandlung und • die Rundung mit den Richtungen towards nearest, towards negative infinity, towards positive infinity, towards zero. Eine einfach genaue Maschinenzahl (single, 32 Bit) kann nach IEEE wie folgt dargestellt werden: 2 31 30 23 Exponent 22 Mantisse ± 1.m1 m2 . . . m23 · 2e 0 mit − 126 ≤ e ≤ 127 Dies entspricht einer Rechengenauigkeit von ungefähr 7 bis 8 Dezimalstellen, da 2−24 ≈ 10−7 . Da Gleitpunktzahlen grundsätzlich als normalisiert (d.h. m0 6= 0 in (4)) angenommen werden, ist bei der Basis 2 immer m0 = 1. Diese 1 wird nicht explizit gespeichert, sondern implizit als gegeben angenommen. Man spricht von einer impliziten 1 oder implicit one. Sie wird aber trotzdem in der Mantissenlänge mitgezählt, so daß bei einfach genauen Maschinenzahlen l = 24 gilt! Standard ist heute in der Regel eine Darstellung entsprechend des IEEE double Formats, bei dem 64 Bit zur Darstellung einer Maschinenzahl verwendet werden: 63 62 52 Exponent 51 Mantisse ± 1.m1 m2 . . . m52 · 2e 0 mit − 1022 ≤ e ≤ 1023 Die Mantissenlänge l und der Exponentenbereich E1 ≤ e ≤ E2 legen das Maß für die Rechengenauigkeit und die Größe des Zahlenbereichs fest. Viele Benutzer von Rechenanlagen haben den Eindruck, daß die Maschinenzahlen gleichmäßig über die reelle Zahlenachse verteilt sind. Dies ist falsch; die Maschinenzahlen sind über den Zahlenbereich nicht gleichabständig verteilt: m 0 e 2 -1 0 1 2 0.5 1 2 4 1 1 1.25 1.5 1.75 1.002 1.012 1.102 1.112 0.5 1 2 4 0.625 1.25 2.5 5 0.75 1.5 3 6 0.875 1.75 3.5 7 e 2 3 5 4 6 7 8 R Die Skizze enthält für ein einfaches Gleitpunktsystem mit E1 = −1, E2 = 2, l = 3 und b = 2 alle möglichen normalisierten Gleitpunktzahlen (siehe Tabelle). Offensichtlich werden die Abstände der Gleitpunktzahlen immer kleiner, je kleiner die Beträge der Gleitpunktzahlen werden. Dies ist eine über das Beispiel hinaus richtige, allgemein gültige Beobachtung. 2.2 Rundung Die Menge der Maschinenzahlen ist endlich. Es stellt sich daher die Frage, wie eine reelle Zahl x ∈ IR, die keine Maschinenzahl ist, durch eine Maschinenzahl approximiert werden kann. In diesem Zusammenhang spricht man auch von Rundung. Dieses Problem stellt sich sowohl bei der Eingabe von Daten in einen Rechner als auch während des Ablaufs einer Rechnung. Bei der Dateneingabe ist zu beachten, daß selbst im Dezimalsystem sehr einfach darstellbare Zahlen in vielen Fällen keine Maschinenzahlen sind. Ein instruktives 3 Beispiel ist die Zahl 0.1, die häufig als Schrittweite in Algorithmen benutzt wird. Diese Zahl hat die folgenden periodischen Entwicklungen (0.1)10 = (0.0001100110011 . . .)2 = (0.012121212 . . .)4 = (0.063146314 . . .)8 = (0.199999 . . .)16 . Benutzt man 0.1 als Schrittweite für eine Schleife in einem Algorithmus, so ist nicht sicher, wie oft die Schleife durchlaufen wird. Dies kann zu groben Fehlern führen. Während des Ablaufs einer Rechnung wird im allgemeinen das Resultat x ± y, x · y, x/y der einfachen arithmetischen Operationen nicht zu den Maschinenzahlen gehören, selbst wenn beide Operanden x, y Maschinenzahlen sind. Das exakte Resultat muß dann durch eine Maschinenzahl ersetzt werden. Der Fehler, den man dabei begeht, heißt Rundungsfehler. Den bei der Eingabe einer Zahl gemachten Rundungsfehler nennt man speziell Konvertierungsfehler. Eine Rundung kann offenbar als eine Abbildungsvorschrift aufgefaßt werden, die einer reellen Zahl x ∈ IR eine Maschinenzahl rd(x) ∈ IM zuordnet wobei IM die Menge der Maschinenzahlen bezeichnet. Von einer vernünftigen Rundung wird man verlangen: |x − rd(x)| ≤ |x − f | für alle f ∈ IM. (5) Mit anderen Worten: die Abbildung ist dergestalt, daß keine Maschinenzahl näher an x liegt, als rd(x). In diesem Sinne ist die Rundung bestmöglich oder optimal. Es sei hier vorweggeschickt, daß auf einigen Rechnern schlechtere Rundungen implementiert sind. Die obige Rundungsvorschrift (5) realisieren verschiedene Verfahren, die sich in der Behandlung von reellen Zahlen unterscheiden, die genau in der Mitte zweier aufeinanderfolgender Maschinenzahlen liegen. Zunächst stellt man x in normalisierter Form x = ±m · be mit m = m0 .m1 . . . ml−1 ml . . . , 0 ≤ mi ≤ b − 1, m0 6= 0 dar. Bei der kaufmännischen Rundung bildet man nun m .m . . . m , 0 1 l−1 m e := m0 .m1 . . . ml−1 + b−(l−1) , Verwendet man round to even, so ist m0 .m1 . . . ml−1 , m .m . . . m , 0 1 l−1 m e := m0 .m1 . . . ml−1 + b−(l−1) , m0 .m1 . . . ml−1 + b−(l−1) , falls ml < falls ml ≥ falls ml .ml+1 . . . < falls ml .ml+1 . . . = falls ml .ml+1 . . . = falls ml .ml+1 . . . > b 2 b 2. b 2 b 2 und b 2 und b 2. ml−1 gerade ml−1 ungerade (6) (7) Im Gegensatz zur kaufmännischen Rundung, die Zahlen, die genau in der Mitte zweier Maschinenzahlen liegen zur betragsmäßig größeren, also von der 0 weg runden, werden diese Zahlen hier so gerundet, daß die letzte Ziffer der gerundeten Zahl gerade ist. Bei zweistelliger Mantisse wird 12.5 somit kaufmännisch auf 13, mit round to even aber auf 12 gerundet. 13.5 wird mit beiden Verfahren auf 14 gerundent. 4 Sind die Ziffern m0 = m1 = . . . = ml−1 = b − 1, so tritt bei der Addition von b−(l−1) ein Überlauf in allen Stellen auf. Die entstehende Mantisse 10.0 . . . hat l + 1 Stellen. In diesem Fall schiebt man das Komma eine Stelle nach links, schneidet die letzte 0 ab und erhöht e um 1. Schließlich setzt man rd(x) := m·b e e, falls E1 ≤ e ≤ E2 . (8) In den Fällen, in denen e < E1 ist, spricht man von Exponentenunterlauf (underflow). Dies bedeutet, das die berechnete Zahl so klein wird, daß sie sich nicht mehr im darstellbaren Zahlenbereich des Rechners befindet und als 0 interpretiert wird. Ist beispielsweise b = 2, l = 8 und E1 = −64, so gilt ¡ ¢ ¡ ¢ rd (1.0001000)2 · 2−64 − (1.0000000)2 · 2−64 = rd (1.0000000)2 · 2−68 = 0. Ist e > E2 spricht man von Exponentenüberlauf (overflow). Es sei bemerkt, daß die Behandlung von underflow und overflow rechnerabhängig ist. Besonders pathologische Fälle treten auf, wenn ein overflow erst nach dem Runden eintritt: ist b = 10, l = 8 und E2 = 64, so würde 9.99999997·1064 nach (6), (8) auf 1.0000000·1065 gerundet, was keine Maschinenzahl ist. Die Rundungsvorschriften (6) und (8) entsprechen im Dezimalsystem genau unserer üblichen Rundung. (Bitte machen Sie sich dies anhand einiger Beispiele klar!) Da |m| ≥ 1 folgt für den relativen Fehler ¯ ¯ ¯ rd(x) − x ¯ ¯ ¯≤ ¯ ¯ x b 2 · b−l b 1 ≤ · b−l = · b−l+1 =: eps. |m| 2 2 (9) Dies gilt auch bei Verwendung von round to even. Dabei ist vorausgesetzt, daß kein overflow oder underlow auftritt und x 6= 0 ist. Die Zahl eps := 12 b−l+1 heißt Maschinengenauigkeit. Ist b = 2, so ist eps = 2−l , und für b = 10 gilt eps = 21 · 10−l+1 . Mit dieser Abkürzung kann man auch schreiben: rd(x) = x(1 + ε) 2.3 mit |ε| ≤ eps. (10) Die arithmetischen Operationen für Gleitpunktzahlen Die Einzelheiten in der Ausführung der arithmetischen Operationen +, −, ·, / sind von Maschine zu Maschine verschieden. Bestenfalls kann man erwarten, daß das exakte Resultat einer Operation x∗y mit ∗ ∈ {+, −, ·, /} durch ein im vorhergehenden Abschnitt beschriebenes optimal gerundetes Resultat rd(x ∗ y) ersetzt wird. Im folgenden wird beschrieben, wie man dies durch Verwendung eines doppelt langen Akkumulators erreichen kann. +,3 −, 3 · ,3 / bezeichnen wir die auf dem Rechner implementierten arithmetischen Operationen und die Mit 3 Operanden mit x = mx ·bex ∈ IM, y = my ·bey ∈ IM. Zunächst betrachten wir die Addition und Subtraktion. Dabei sei o.B.d.A. |x| ≥ |y| vorausgesetzt. Zunächst wird ex − ey berechnet. Es sind zwei Fälle zu unterscheiden: Fall 1: ex − ey > l: In diesem Fall sind die l signifikanten Stellen des Ergebnisses (nach Rundung) identisch mit denen von x und folglich wird rd(x + y) := x. Fall 2: ex − ey ≤ l: Die Mantisse my von y wird auf dem doppelt langen Akkumulator (das sind 2 · l Speicherzellen) um ex − ey Stellen nach rechts verschoben (dies entspricht einer Division durch bex −ey ), und die exakte Summe mx +my·b−(ex −ey ) berechnet. Durch Verschiebung nach links oder rechts wird diese Summe mit einer Potenz von b so multipliziert, daß die Mantisse normalisiert ist. Entsprechend dieser Verschiebung 5 wird der Exponent des Ergebnisses geändert. Zum Schluß rundet man die 2 · l-stellige Mantisse entsprechend der implementierten Rundung auf l Stellen. Einige Beispiele sollen diesen Vorgang klarmachen. Wir benutzen dabei die 4-stellige dezimale Gleitpunktarithmetik, also l = 4, b = 10. Der Exponentenbereich soll groß genug angenommen werden, so daß kein overflow oder underflow entsteht. 6.314·104 + 3.865·101 = 6.3140000·104 + 0.0038650·104 = 6.3178650·104 Die exakte Summe wird auf 6.318·104 gerundet. 7.418·104 + 6.158·104 = 7.4180000·104 + 6.1580000·104 = 13.5760000·104 = 1.3576000·105 Die exakte Summe wird zum Endergebnis 1.358 · 105 gerundet. 1.005·10−4 − 9.963·10−5 = 1.0050000·10−4 − 0.9963000·10−4 = 0.0087000·10−4 = 8.700·10−7 Die exakte Summe ist eine Maschinenzahl und muß nicht gerundet werden. Bei diesem letzten Beispiel heben sich die ersten drei von vielen signifikanten Ziffern auf. Man spricht in diesem Fall von Auslöschung. Man beachte aber, daß im Fall der Auslöschung die berechnete Summe immer exakt ist. Dies soll besonders herausgestellt werden, da man üblicherweise bei Auslöschung an einen Genauigkeitsverlust denkt. In welchem Zusammenhang Auslöschung und Genauigkeitsverlust trotzdem stehen, wird später geklärt. Wie man sieht, wird bei der Durchführung von Addition und Subtraktion mit doppelt langem Akkumulator exakt gerechnet und ganz am Ende einmal gerundet. Der dabei gemachte Rundungsfehler ergibt sich also nur aus der implementierten Rundungsvorschrift. Dementsprechend gilt (vgl. (10)): + y := rd(x + y) = (x + y)(1 + ε) x3 mit |ε| ≤ eps (11) − y := rd(x − y) = (x − y)(1 + ε) x3 mit |ε| ≤ eps. (12) · y berechnet man auf einem doppelt langen Akkumulator, in dem man zunächst die Summe Das Produkt x 3 ex + ey bildet, das 2 · l-stellige exakte Produkt berechnet und gegebenenfalls um eine Stelle nach rechts verschiebt. Anschließend wird wieder auf l Stellen gerundet. 2.213·10−2 · 8.714·10−4 = 19.284100·10−6 = 1.9284100·10−5 Das exakte Produkt wird zum Endergebnis 1.928·10−5 gerundet. Genauso wie bei der Addition erhalten wir demnach · y := rd(x · y) = x · y(1 + ε) x3 mit |ε| ≤ eps. (13) / y, y 6= 0 wird gebildet, indem zunächst e Der Quotient x 3 x − ey berechnet wird. Die Mantisse mx wird auf die ersten l Stellen des doppeltlangen Akkumulators gelegt. Nun dividiert man den Akkumulatorinhalt durch die Mantisse my , normalisiert und rundet auf l Stellen. Offenbar gilt auch hier / y := rd(x/y) = (x/y)(1 + ε) x3 mit |ε| ≤ eps. (14) Zusammenfassend können wir feststellen, daß bei Implementierung der optimalen Rundungsvorschrift (6), (8) und unter Benutzung eines doppeltlangen Akkumulators die arithmetischen Grundoperationen +, −, ·, / im Rahmen der zugrunde liegenden Maschinenzahlen bestmöglich implementiert werden können. Mit etwas mehr Aufwand kann das gleiche Ergebnis mit einem etwas kürzeren Akkumulator erreicht werden. In jedem Fall wird das exakte Ergebnis durch die am nächsten gelegene Maschinenzahl ersetzt. 6 Bei vielen heutigen Anlagen sind jedoch die Rundung und die arithmetischen Grundoperationen nicht optimal implementiert. Es gelten dann lediglich Abschätzungen der Form ± y = x(1 + ε ) ± y(1 + ε ) x3 x y mit |εx |, |εy | ≤ k · eps, (15) wobei k eine kleine natürliche Zahl ist. 2.4 Bemerkungen und Beispiele Die im vorhergehenden Abschnitt geschilderten Gleitpunktoperationen könnten den Eindruck erwecken, daß zumindest bei optimaler Rundungsvorschrift kaum nennenswerte Fehler auftreten. Aber leider sind schon die einfachsten Grundgesetze wie Assoziativ- und Distributivgesetze auf einem Rechner nicht erfüllt. Sie können leicht nachprüfen, daß z.B. ein Rechner mit 8 Stellen in der Mantisse (b=10) für a = 2.3371258·10−4 , b = 3.3678429·102 , c = −3.3677811·102 die folgenden Ergebnisse berechnet: −4 + + (b 3 + c) = 2.3371258·10 a3 3 6.1800000·10−3 = 6.4137126·10−3 (16) 2 − + b) 3 + c = 3.3678452·10 3 (a 3 3.3677811·102 = 6.4100000·10−3 . (17) Das exakte Resultat ist a+b+c = 6.41371258·10−3 . Entsprechendes gilt für das Distributivgesetz (Aufgabe!). Da schon diese einfachen Gesetze keine Gültigkeit haben, sind natürlich auch sehr viele Folgerungen wie Kürzungsregeln usw. im Allgemeinen nicht erfüllt. Es kann also in einigen Fällen sehr wesentlich sein, auf welche Weise und insbesondere in welcher Reihenfolge algebraische Ausdrücke in ein Programm umgesetzt werden. Ein besonders unangenehmes Phänomen der Gleitpunktrechnung ist die Auslöschung. Wir haben bereits im vorhergehenden Abschnitt gesehen, daß bei der Auslöschung die berechnete Summe immer exakt ist (und somit kein Rundungsfehler gemacht wird) und doch signifikante Ziffern verloren gehen. Dies führt zu großen Fehlern, wenn die Operanden bereits vorher rundungsfehlerbehaftet sind. Sind beispielsweise in fünfstelliger Gleitpunktarithmetik vier Maschinenzahlen x1 = 3.4512·103 x3 = 2.7835·103 x2 = 2.8991·102 x4 = 3.5916·102 gegeben, so haben die exakten Produkte die Gestalt x1 · x2 = 1.000537392·106 x3 · x4 = 9.9972186·105 . Für die exakte Differenz gilt x1 · x2 − x3 · x4 = 8.15532·102 . Auf einer Maschine mit optimaler Rundung wird zunächst 6 · x = 1.0005·10 x1 3 2 5 · x = 9.9972·10 x3 3 4 berechnet, dann subtrahiert und gerundet 2 · x ) 3 · x ) = 7.8000·10 . (x1 3 2 − (x3 3 4 (18) Der Vergleich dieser beiden Resultate zeigt, daß das gleitpunktmäßig errechnete Ergebnis (18) keine einzige korrekte Ziffer wiedergibt. 7 Ein in der Praxis häufig auftretendes Problem ist die Bestimmung von Funktionswerten, wobei die Potenzreihenentwicklung der Funktion bekannt ist. Ein besonders einfaches Beispiel ist die Taylorreihe der Exponentialfunktion x2 x3 xn ex = 1 + x + + + ... + + ... 2! 3! n! Aus der Analysis ist bekannt, daß ex eine ganze Funktion ist und für jeden Wert x ∈ IR konvergiert. Es soll der Wert ex an der Stelle x = −5.5 berechnet werden. Rechnet man in fünfstelliger dezimaler Gleitpunktarithmetik die ersten 25 Summanden aus und addiert diese, so erhält man xn n! e−5.5 Die Koeffizienten xn n! = + + + + + + + + + + + + + + + + + + + + + + + + Zwischensumme sn = n P k=0 1.00000000000000 - 5.50000000000000 15.12500000000000 -27.72900000000000 38.12700000000000 -41.94000000000000 38.44500000000000 -30.20700000000000 20.76700000000000 -12.69100000000000 6.98010000000000 - 3.49010000000000 1.59960000000000 - 0.67676000000000 0.26587000000000 - 0.09748700000000 0.03351100000000 - 0.01084200000000 0.00331290000000 - 0.00095899000000 0.00026372000000 - 0.00006906800000 0.00001726700000 - 0.00000412910000 0.00000094627000 xk k! 1.00000000000000 - 4.50000000000000 10.62500000000000 -17.10400000000000 21.02300000000000 -20.91700000000000 17.52800000000000 -12.67900000000000 8.08800000000000 - 4.60300000000000 2.37710000000000 - 1.11300000000000 0.48660000000000 - 0.19016000000000 0.07571000000000 - 0.21777000000000 0.01173400000000 0.00089200000000 0.00420490000000 0.00324590000000 0.00350960000000 0.00344050000000 0.00345780000000 0.00345370000000 0.00345460000000 wurden in fünfstelliger Gleitpunktarithmetik nach der Rekursionsformel xn−1 x xn = · n! (n − 1)! n ausgewertet. In Wirklichkeit gilt aber e−5.5 = 4.0867 . . . · 10−3 . Exaktes Ergebnis und die näherungsweise berechnete Summe stimmen in keiner Ziffer der Mantisse überein. Was läuft in diesem Beispiel falsch? Zunächst beobachtet man, daß die einzelnen Summanden durch die Multiplikationen und Divisionen bestenfalls 5 signifikante Ziffern besitzen und diese teilweise in einer Größenordnung von 102 liegen. Das berechnete Ergebnis besitzt die Größenordnung 10−2 und somit die gleiche Größenordnung wie beispielsweise die nicht signifikante Ziffer 7 der Zahl 3.8127·101 . Offenbar tritt hier ebenfalls, allerdings subtiler, das Phänomen der 8 Auslöschung auf. Bessere Ergebnisse können bei diesem Algorithmus offenbar nur mit höherer Genauigkeit erzielt werden. Allerdings wird dadurch die Rechenzeit beträchtlich erhöht. Einen guten Algorithmus erhält man aus der Formel e−x = e1x : e−5.5 = 1 e5.5 = 1 = 0.0040865 1 + 5.5 + 15.125 + . . . in fünfstelliger Dezimalarithmetik. In der Summe im Nenner tritt keine Auslöschung mehr auf, das berechnete Resultat besitzt nur noch einen Fehler von 0.007%. Dieser Restfehler ist einzig die Summe der Rundungsfehler der Multiplikationen, Divisionen und Additionen. Auf vielen Rechenanlagen ist die Exponentialfunktion als Standardfunktion vorhanden. Üblicherweise wird sie berechnet, indem zunächst x = x e + n mit n ∈ ZZ, 0 ≤ x e < 1 dargestellt wird und das Additionstheorem x x e+n x e n e =e = e · e benutzt wird. In vielen praktischen Situationen treten transzendente Funktionen auf, die standardmäßig nicht auf Rechnern vorhanden sind, aber deren Potenzreihenentwicklung bekannt ist. In solchen Fällen sollte man die Potenzreihendarstellung und Gesetzmäßigkeiten dieser Funktion genau untersuchen, bevor ein Algorithmus konzipiert wird. 2.5 Fehlerfortpflanzung während der Rechnung Besteht eine numerische Rechnung aus vielen Rechenoperationen, dann pflanzen sich die Rundungsfehler von Schritt zu Schritt fort. Das letzte Beispiel (Bestimmung von e−5.5 ) demonstriert eindrucksvoll, daß diese Fehlerfortpflanzung zu völlig falschen Resultaten führen kann. Daher haben sich zahlreiche Mathematiker mit der Theorie der Fehlerfortpflanzung für verschiedene Probleme und Algorithmen befaßt. Diese Theorien sind für viele Problemstellungen sehr tiefliegend und können im Rahmen dieses Praktikums nicht behandelt werden. Hier sollen nur zwei sehr einfach zusammengesetzte Gleitpunktoperationen untersucht werden. Im folgenden setzen wir voraus, daß während der Rechnung kein overflow oder underflow eintritt. Betrachten · x 3 · x , wobei die x Maschinenzahlen sind. Wird wir zunächst das zusammengesetzte Produkt x1 3 2 · ... 3 n i die Multiplikation in der Reihenfolge ausgeführt, in der sie geschrieben ist (also von links nach rechts), so gilt nach Formel (13) p1 = x1 · x = x · x (1 + ε ) p2 = x1 3 2 1 2 2 .. . · x = x · x · . . . · x (1 + ε ) · (1 + ε ) · . . . · (1 + ε ). pr = pr−1 3 r 1 2 r 2 3 r Für das mit Gleitpunktoperationen berechnete Produkt erhält man somit · x 3 · x pn := x1 3 2 · ... 3 n = x1 · x2 · . . . · xn (1 + ε2 ) · (1 + ε3 ) · . . . · (1 + εn ). Wegen |εi | ≤ eps für i = 2, . . . , n gilt (1 − eps)n−1 ≤ (1 + ε2 ) · (1 + ε3 ) · . . . · (1 + εn ) ≤ (1 + eps)n−1 , und es folgt die Fehlerabschätzung mit (1 − eps)n−1 ≤ 1 + F ≤ (1 + eps)n−1 . · x 3 · x x1 3 2 · ... 3 n = x1 · x2 · . . . · xn · (1 + F ) 9 (19) Ist beispielsweise eps = 2−l und n − 1 deutlich kleiner als l, so ist der relative Fehler des Produkts klein. Obwohl der errechnete Wert des Produkts von der Reihenfolge abhängt, in welcher die Multiplikation ausgeführt wird (Assoziativ- und Distributivgesetze haben keine Gültigkeit!), ist die Fehlerabschätzung (19) offenbar unabhängig von dieser Reihenfolge. Ein in der Praxis häufig auftretendes Problem ist die Addition mehrerer Zahlen. Gerade für solche Probleme werden Vektorrechner gebaut. Bei der Berechnung von Summen kann nicht mehr angenommen werden, daß das berechnete Ergebnis einen nur kleinen relativen Fehler besitzt, obwohl dies für die Summe zweier Zahlen noch richtig ist, falls die optimale Rundungsvorschrift benutzt wird. Besäße die Summe mehrerer Zahlen + x 3 + x einen kleinen relativen Fehler, so müsste x1 3 2 + ... 3 n gleich (x1 + x2 + . . . + xn )(1 + ε) + ... 3 + x sein. Ist die exakte Summe x1 + . . . + xn oder die berechnete Summe x1 3 n gleich Null, so ist obige Gleichung meist für kein ε mit |ε| < 1 erfüllt. Aus (11) erhält man eine Fehlerabschätzung anderer Natur, wobei |εi | ≤ eps: s1 = x 1 + x = (s + x )(1 + ε ) s2 = x 1 3 2 1 2 2 .. . + x = (s sr = sr−1 3 r r−1 + xr )(1 + εr ). Multipliziert man diese Beziehung explizit aus, so folgt sn = x1 (1 + η1 ) + x2 (1 + η2 ) + . . . + xn (1 + ηn ) (20) mit 1 + η1 = (1 + ε2 ) · (1 + ε3 ) · . . . · (1 + εn ) 1 + ηr = (1 + εr ) · . . . · (1 + εn ), r = 2, . . . , n und (1 − eps)n−1 ≤ 1 + η1 ≤ (1 + eps)n−1 (1 − eps)n−r+1 ≤ 1 + ηr ≤ (1 + eps)n−r+1 , r = 2, . . . , n. Wie man sieht, sind die Fehlerschranken von der Reihenfolge der Summation abhängig. Die obere Schranke für den Gesamtfehler ist am kleinsten, wenn man die Summanden in der Reihenfolge aufsteigender Beträge addiert, da dann der größtmögliche Faktor 1 + η1 mit den kleinsten xi multipliziert wird. Die Fehlerabschätzung (20) kann gedeutet werden als die exakte Summe von leicht gestörten Daten xi (1 + ηi ), denn die Faktoren (1 + ηi ) liegen sehr nahe bei 1, falls n − r klein im Verhältnis zu l ist. 3 Kondition eines Problems und Kondition eines Verfahrens Man nennt ein mathematisches Problem gut konditioniert, wenn eine geringe relative Störung der Eingabedaten des Problems auch nur eine geringe relative Änderung der Lösung des Problems zur Folge hat. Kann dagegen eine geringe relative Änderung der Eingabedaten eine große relative Änderung des Ergebnisses zur Folge haben, so nennt man das Problem schlecht konditioniert. 10 Gut konditioniertes Problem P Pe . . . . E=x e=x E e Gleichungssystem Ax = b P = (A, b) , E = x = A−1 b Ein numerisches Verfahren zur Lösung eines mathematischen Problems heißt gut konditioniert, wenn seine Lösung die exakte Lösung eines mathematischen Problems ist, das aus dem ursprünglichen mathematischen Problem durch geringe relative Änderung der Eingabedaten hervorgeht. Andernfalls heißt das numerische Verfahren schlecht konditioniert. Es ist sehr wesentlich, zwischen der Kondition eines mathematischen Problems und der Kondition eines numerischen Verfahrens zu unterscheiden. Während man bei einem schlecht konditionierten Verfahren in fast allen Fällen ein besseres Verfahren entwickeln kann, lassen sich bei schlecht konditionierten Problemen i.a. nur durch Erhöhung der Eingabe- und Rechengenauigkeit bessere Resultate erzielen. Gut konditionierter Algorithmus P Pe . . . . E=x e=x E e z.B. GAUß-Algorithmus mit floating point Rechnung Die beiden in der Einleitung angegebenen Beispiele (1) und (2) sind typisch schlecht konditionierte Probleme. Beispielsweise muß der erste Koeffizient 1050 in der Summe (1) nur um −1323 (das entspricht einer relativen Störung von 10−47 ) gestört werden, damit der vom Rechner berechnete Wert 0 der exakte Wert der Summe ist. Auf praktisch keinem Rechner ist diese relative Änderung überhaupt eingebbar, da dazu eine Mantissenlänge von wenigstens 48 Dezimalstellen (oder eine entsprechende Anzahl von Binärstellen) notwendig wäre. Obwohl das Problem der Summation dieser speziellen Zahlen extrem schlecht konditioniert ist (die relative Änderung 10−47 entspricht dem Verhältnis von einem einzigen Gramm zu etwa 1014 = 100000000000000 Sonnenmassen), ist das Verfahren der Summation gut konditioniert: Für jede beliebige Summe ist das errechnete Gleitpunktergebnis nach (20) gleich der exakten Summe geringfügig gestörter Eingabedaten. Es liegt also ein gut konditioniertes Verfahren, aber ein schlecht konditioniertes Problem vor. Betrachtet man nun die Berechnung von e−5.5 , so erkennt man aus den Eigenschaften und dem Verhalten der Exponentialfunktion sofort, daß es sich um ein gut konditioniertes mathematisches Problem handelt. Und wir haben gerade gesehen, daß die Summation ein gut konditioniertes Verfahren ist! Hier tritt ein scheinbarer Widerspruch auf, denn ein gut konditioniertes Problem und ein dazu gut konditioniertes numerisches Verfahren müssen relativ gute Ergebnisse liefern. 11 Dieser scheinbare Widerspruch läßt sich aufklären. Die Bestimmung von e−5.5 kann nicht als einfache Additin on von unabhängigen Summanden xn! aufgefaßt werden. Vielmehr ist jeder dieser Summanden abhängig von dem einzigen Eingabewert −5.5 und nur dieser Eingabewert und die Störung diese Eingabewertes kann zur Beurteilung des Verfahrens herangezogen werden. Denn eine geringfügige Störung des Eingabeparameters −5.5 ändert den Wert e−5.5 ebenfalls geringfügig (das Problem ist also gut konditioniert), es ändert den i Wert der Gleitpunktsumme der xi! allerdings bis zur Unkenntlichkeit. Dieses Verfahren für die Berechnung von ex , x negativ, ist also schlecht konditioniert. 4 Fehleranalyse Viele mathematische Probleme und Algorithmen wurden hinsichtlich ihres Verhaltens gegenüber Eingabefehlern und Rundungsfehlern während der Rechnung untersucht. Dabei sind die Vorwärtsanalyse (forward analysis) und die Rückwärtsanalyse (backward analysis) zwei Hauptuntersuchungsformen, die häufig benutzt werden. Bei der Vorwärtsanalyse versucht man eine Abschätzung für die Differenz zwischen exaktem und berechnetem Ergebnis zu erhalten. Eine solche Abschätzung kann berechnet werden, indem der Fehler jedes einzelnen Rechenschritts abgeschätzt wird. In vielen Fällen sind solche Abschätzungen sehr pessimistisch, da immer der schlimmste Fall (worst case) mit berücksichtigt werden muß. Bei der Rückwärtsanalyse bemüht man sich dagegen, an bestimmten Stellen der Rechung zu zeigen, daß der berechnete Wert der exakte Wert eines leicht gestörten Problems ist. Man überprüft also die Gutartigkeit des numerischen Verfahrens. In der Anwendung erweist sich die Rückwärtsanalyse häufig als leichter durchführbar. Andererseits ist die Rückwärtsanalyse in gewisser Weise nicht vollständig, da man letztlich immer die Differenz zwischen der berechneten und exakten Lösung kennenlernen möchte. Die Fehlerabschätzung (19) für das · . . .3 · x Produkt x1 3 n ist eine Vorwärtsanalyse, während es sich bei der Fehlerabschätzung für die Berechnung + + x der Summe x1 3 . . . 3 n um eine Rückwärtsanalyse handelt. Wir wollen zu der obigen Definition einige weitere Beispiele betrachten: 1. Beispiel: Die Ihnen aus der Schule bekannte quadratische Gleichung ax2 + bx + c = 0, a, b, c ∈ IR, a 6= 0 besitzt genau die beiden Werte x1 = −b + √ b2 − 4ac , 2a x2 = −b − √ b2 − 4ac 2a als Lösungen. Die Lösungen x1 , x2 hängen stetig von den Eingabekoeffizienten a, b, c ab. Dies legt die Vermutung nahe, daß eine Implementierung dieser Formel auf einem Rechner zu keinen großen numerischen Problemen führen sollte. Im folgenden wird eine dezimale Gleitpunktarithmetik mit l = 8 und E1 = −50, E2 = 50 benutzt. Fall 1: a = 1, b = −105 , c = 1 Die exakten Lösungen dieser quadratischen Gleichung, auf 11 signifikante Stellen optimal gerundet, sind x1 = 99999.999990 x2 = 0.000010000000001. 12 Benutzt man obige Formel, so liefert der Modellrechner die Näherungen x e1 = 100000.00 x e2 = 0. Die Näherung x e2 = 0 hat mit der wahren Lösung x2 ≈ 10−5 keine gemeinsame signifikante Ziffer und ist somit ein völlig falsches Näherungsresultat. Es ist unmittelbar klar, daß Auslöschung aufgetreten ist: √ √ Es ist −b − b2 − 4a = 105 − 1010 − 4. Die Subtraktion vor der Wurzel wird ohne Fehler ausgeführt, der eigentliche Fehler ist der Rundungsfehler 1010 −4 ≈ 1010 in 8-stelliger Rechnung. Stört man die Eingabedaten a, b, c nur geringfügig, so ändern sich offenbar die exakten Lösungen ebenfalls geringfügig. Das Problem ist gut konditioniert, und demnach muß der Algorithmus schlecht konditioniert sein. Ein besserer Algorithmus, der die Auslöschung vermeidet, stellt zunächst eine der Lösungen in der Form √ b + sign(b) b2 − 4ac x1 = − 2a dar, wobei sign(b) das Vorzeichen von b ist. Aus ax2 + bx + c = a(x − x1 )(x − x2 ) folgt sofort ax1 x2 = c, und es ergibt sich für die zweite Lösung x2 = c . a · x1 Für den obigen Fall a = 1, b = −105 , c = 1 erhält man bei Anwendung dieser Formeln die beiden guten Näherungslösungen x e1 = 100000.00, x e2 = 0.000010000000. Fall 2: a = 1.0000000, b = −4.0000000, c = 3.9999999. Die exakten Lösungen dieser quadratischen Gleichung, auf 11 signifikante Stellen optimal gerundet, sind x1 = 1.9996837720 x2 = 2.0003162280. In unserem Modellrechner erhält man bei Anwendung der obigen Formel bei beiden Versionen x e1 = x e2 = 2.0000000. Diese beiden Näherungslösungen stimmen nur in den ersten 4 Stellen mit den exakten Lösungen überein, obwohl die (nur wenigen) Rechenoperationen mit achtstelliger Genauigkeit durchgeführt sind. Diese Näherungslösungen sind exakte Lösungen der quadratischen Gleichungen x2 − 4x + 4 = 0. Die Koeffizienten a und b dieser Gleichung sind identisch mit denen der obigen Gleichung. Lediglich c unterscheidet sich um δ := 0.0000001. Wir setzen ε2 := δ. Die berechneten Lösungen sind also die exakten Lösungen einer sehr leicht gestörten Gleichung. Demnach ist der Algorithmus für dieses Problem gut konditioniert. Die verlorengegangenen Stellen können nur durch die schlechte Kondition des Problems verursacht werden: Die Originalgleichung hat die Gestalt x2 − 4x + 4 − ε2 = 0 und besitzt die Nullstellen 2 + ε, 2 − ε. Ändert man c in der Größenordnung ε2 , so ändern sich die Lösungen in der Größenordung von ε. 13 Die quadratische Gleichung ist immer dann schlecht konditioniert wenn Auslöschung bei der Berechnung von b2 − 4ac auftritt, d.h. wenn die beiden Nullstellen nahe beieinanderliegen. 2. Beispiel: Das Gleichungssystem 1.2969 · x + 0.8648 · y = 0.8642 0.2161 · x + 0.1441 · y = 0.1440 besitzt die exakten Lösungen x = 2, y = −2. Nehmen wir an, wir hätten mit Hilfe eines numerische Verfahrens die Näherungslösungen x e = 0.9911, ye = −0.4870 erhalten. Die Näherung und exakte Lösungen besitzen keine gemeinsamen signifikanten Stellen. Man könnte zunächst glauben, das numerische Verfahren sei schlecht konditioniert. Setzt man aber die Näherungslösung in das Gleichungssystem ein, so erhält man die neue rechte Seite eb1 = 0.86419999 eb2 = 0.14400001 Die beiden rechten Seiten unterscheiden sich in jeder Komponente nur um den Betrag 10−8 . Das bedeutet, daß das benutzte numerische Verfahren für dieses Problem eine Lösung berechnet, die im Sinne der Rückwärtsanalyse hervorragend ist. Das Verfahren ist demnach für dieses Problem sehr gut konditioniert. Es folgt, daß das Gleichungssystem sehr schlecht konditioniert ist. 3. Beispiel: Zur Berechnung der Integrale Z1 xn ex−1 dx In = für n = 1, 2, 3, . . . 0 können die bekannten numerischen Integrationsverfahren (Trapezregel, Simpsonregel, . . . ) benutzt werden. Mit partieller Integration Z1 Z1 ¯1 n x−1 n x−1 ¯ x e dx = x e ¯ − n · xn−1 ex−1 dx 0 0 0 erhält man die Iterationsformel In = 1 − n · In−1 n = 1, 2, . . . und I1 = 1 . e Eine andere Möglichkeit für die numerische Berechnung der obigen Integrale bietet sich mit der Auswertung dieser einfachen Iterationsvorschrift an. Bei Berechnung mit 6 Dezimalstellen erhält man I1 ≈ 0.367879 I6 ≈ 0.127120 I2 ≈ 0.264242 I7 ≈ 0.110160 I3 ≈ 0.207274 I8 ≈ 0.118720 I4 ≈ 0.170904 I9 ≈ −0.0684800. I5 ≈ 0.145480 Obwohl der Integrand x9 ex−1 positiv auf dem gesamten Intervall (0, 1) ist, ist der berechnete Näherungswert negativ, also völlig falsch. Das Problem ist gut konditioniert, denn der Integrand xn ex−1 ist beliebig 14 oft differenzierbar, und eine leichte Störung der Integralgrenzen kann keine großen Auswirkungen auf den Integralwert zur Folge haben. Demnach muß der Algorithmus sehr schlecht konditioniert sein. Warum? Bei der Eingabe des Startwertes I1 = 1e wurde ein kleiner Fehler (Konvertierungsfehler) der Größenordnung 4·10−7 gemacht. Bei der Berechnung von I2 wurde dieser Fehler mit dem Faktor −2 multipliziert. Dieser Fehler wiederum wurde bei der Berechnung von I3 mit dem Faktor −3 multipliziert. So fortfahrend folgt, daß schließlich der Fehler bei der Berechnung von E9 die Größenordnung (−2) · (−3) · . . . · (−9) · 4·10−7 = 9! · 4·10−7 = 362880 · 4·10−7 ≈ 0.15 besitzt. Der auf drei signifikante Stellen gerundete exakte Wert von I9 ist 0.0916. Wenn man zu dem berechneten Wert I9 ≈ −0.068 den sehr großen Fehler 0.15 dazu addiert, erhält man ungefähr den exakten Wert. Das obige Iterationsverfahren ist demnach ein äußerst instabiler Algorithmus. Man spricht in einem solchen Fall auch von Fehlerexplosion. Aus fehlerexplosiven Verfahren können sehr häufig stabile, fehlerdämpfende Verfahren entwickelt werden. Falls die obige Iterationsformel in der Form In−1 = 1 − In , n n = . . . , 3, 2, also rückwärts geschrieben wird, dann wird der Fehler in jedem Iterationsschritt mit dem Faktor 1/n multipliziert. Wählt man beispielsweise als Startwert I20 = 0, so liefert diese Rückwärtsiteration die Näherung I20 ≈ 0.0 I14 ≈ 0.0627322 I19 ≈ 0.0500000 I13 ≈ 0.0669477 I18 ≈ 0.0500000 I12 ≈ 0.0717733 I17 ≈ 0.0527778 I11 ≈ 0.0773523 I16 ≈ 0.0557190 I10 ≈ 0.0838771 I15 ≈ 0.0590176 I9 ≈ 0.0916123. Man zeigt leicht, daß schon für I15 der Fehler beim Start durch das fehlerdämpfende Verfahren verschwunden ist und alle Werte I15 bis I9 6 signifikante Stellen besitzen. 5 Ausblick und Literatur Eine ausführliche Beschreibung der Rundungsfehleranalyse für normalisierte Gleitpunktarithmetik und ihre Anwendung auf das Rechnen mit Polynomen und Matrizen findet man in dem Buch von Wilkinson [7]. In diesem Buch wird auch die Rundungsfehleranalyse für Festpunktrechnung untersucht. Bei der Festpunktrechnung ist die Lage des Dezimalpunktes an einer bestimmten Stelle in der Mantisse fixiert. Die Angabe des Exponenten entfällt somit. Anwendung fand die Festpunktrechnung früher besonders im kaufmännischen Bereich. Im Vergleich zur Gleitpunktarithmetik sind die Fehlerabschätzungen der Festpunktarithmetik etwas günstiger, z.B. ist die Addition sogar assoziativ. Allerdings müssen der Rechnung eingehende Untersuchungen vorausgehen, um sicherzustellen, daß die vorkommenden Festpunktzahlen den zulässigen Bereich nicht verlassen. Dies ist ein entscheidender Nachteil der Festpunktarithmetik. Behelfen kann man sich häufig durch Einführung von Skalenfaktoren an vielen Stellen der Festpunktrechnung; dies entspricht aber dann einer 15 speziellen Art von Gleitpunktrechnung. Daher ist auf heutigen Rechenanlagen praktisch ausschließlich die normalisierte Gleitpunktarithmetik implementiert. In dem Buch von Kulisch und Miranker [4] wird die Gleitpunktarithmetik in eine mathematische Theorie eingebettet und untersucht. Eine Konsequenz dieser Theorie ist es, zu den arithmetischen GrundoperatioPn nen das Skalarprodukt i=1 ai · bi zweier Vektoren a, b ∈ IR als Grundoperation hinzuzufügen und gemäß der optimalen Rundungsvorschrift auszuwerten. Diese Auswertung ist mit Hilfe eines mehrfach-langen AkPn kumulators möglich. Mit dieser zusätzlichen Grundoperation können beispielsweise Summen i=1 xi oder Produkte zweier Matrizen maximal genau berechnet werden. Eine sehr vielversprechende Methode, eine automatische Rundungsfehleranalyse auf dem Rechner durchzuführen, ist die Intervallarithmetik. Hier wird jede auftretende Zahl x durch ein Intervall [x, x] = {x ∈ IR | x ≤ x ≤ x} ersetzt. Die arithmetischen Grundoperationen ∗ ∈ {+, −, ·, /} können in natürlicher Weise auf Intervalle durch die Formel [x, x] ∗ [y, y] := {z = x ∗ y | x ∈ [x, x], y ∈ [y, y]} erweitert werden. Die Formeln sind leicht auf einem Rechner zu implementieren. Beispielsweise gilt für die Addition [x, x] + [y, y] = [x + y, x + y]. Eine sehr schöne Einführung in die Methoden der Intervallarithmetik findet man in den Büchern von Ahlefeld und Herzberger [1] und von Moore [5]. Die Intervallarithmetik neigt allerdings zu Überschätzungs- und Aufblähungseffekten, wenn man ganz naiv in einem Algorithmus reelle Zahlen und arithmetische Operationen durch Intervalle und obige Intervalloperationen ersetzt. Daher wurden für viele Problemstellungen spezielle Intervallalgorithmen entwickelt, bei denen solche Aufblähungseffekte nicht Auftreten. In der Arbeit von Rump [6] sind Intervallalgorithmen beschrieben, die für viele Problemstellungen Ergebnisse liefern, die bis zur letzten Stelle der Mantisse genau sind. Sämtliche Konvertierungs-, Rundungs- und Auslöschungsfehler werden also automatisch durch diese Algorithmen erfasst und abgeschätzt. Neuerdings wurden im Institut für Zuverlässiges Rechnen Algorithmen entwickelt, die darüber hinaus eine automatische und garantiert richtige Sensitivitätsanalyse gestatten. Mit diesen Methoden werden nicht nur alle Rundungsfehler erfaßt und abgeschätzt, sondern gleichzeitig die Richtigkeit der Problemstellung überprüft. Das Standardwerk bezüglich der Genauigkeit und Stabilität von Algorithmen ist das Buch von Highham [2]. Hier wird auf das Verhalten von numerischen Algorithmen in Berechnungen mit endlicher Genauigkeit eingegangen. Literatur [1] G. Alefeld and J. Herzberger. Einführung in die Intervallrechnung. B.I. Wissenschaftsverlag, 1974. [2] N.J. Highham. Accuracy and Stability of Numerical Algorithms. Society for Industrial and Applied Mathematics, 1961. [3] ANSI/IEEE 754-1985, Standard for Binary Floating-Point Arithmetic, 1985. 16 [4] U. Kulisch and W.L. Miranker. Computer Arithmetic in Theory and Practice. Academic Press, New York, 1981. [5] R.E. Moore. Methods and Applications of Interval Analysis. SIAM, Philadelphia, 1979. [6] S.M. Rump. Solving Algebraic Problems with High Accuracy. Habilitationsschrift. pages 51–120, 1983. [7] J.H. Wilkinson. Rundungsfehler. 1969. 6 Versuchsbeschreibung und -durchführung Aufgabe 1: Der Wert von p2 − 2q 2 ist zu berechnen. a) Berechnen Sie diesen für die Eingabedaten p = 665857.0 und q = 470832.0 mit MATLAB. b) Stören Sie jeweils zweimal die Eingabedaten p, q in der letzten signifikanten Ziffer von p und q und berechnen Sie den obigen Wert mit MATLAB erneut. Aufgabe 2: Zu berechnen ist die Funktion f (x, p) = sinh(px) − px p3 an der Stelle x = 1 für p = 10−4 , 10−8 , 10−10 . Verwenden Sie dazu in MATLAB die folgenden drei Algorithmen: a) naive Auswertung von sinh(x), b) Auswertung unter Beachtung von sinh(x) = 12 (ex − e−x ), c) Auswertung der ersten drei Terme der Taylorreihe f (x, p) = x3 p2 x5 p4 x7 + + + R(p, x). 3! 5! 7! Aufgabe 3: Die folgenden algebraisch äquivalenten Ausdrücke 9x4 − y 4 + 2y 2 (3x2 − y 2 )(3x2 + y 2 ) + 2y 2 8x4 + (x2 + y 2 )(x2 − y 2 ) + 2y 2 2y 2 − y 4 + 9x4 9x4 + 2y 2 − y 4 9x4 − y 2 (y 2 − 2) sollen ausgewertet werden. a) Berechnen Sie diese Ausdrücke mit MATLAB für die Werte x = 10864.0, y = 18817.0. 17 b) Stören Sie die Eingabedaten x, y in der letzten Dezimalstelle und berechnen Sie die Werte der obigen Ausdrücke für die gestörten Daten mit MATLAB. Aufgabe 4: Das Integral Z1 xn = 0 xn dx, x + 13 n = 0, 1, 2 . . . genügt wegen Z1 xn + 13xn−1 = 0 xn + 13xn−1 dx = x + 13 der Iterationsformel xn = −13xn−1 + Z1 xn−1 dx = 0 1 n 1 . n Für den Startwert gilt Z1 x0 = 0 ¯1 1 ¯ dx = ln(x + 13)¯ = ln(14) − ln(13). x + 13 0 a) Berechnen Sie nach der obigen Iterationsformel mit MATLAB x0 , x1 , x2 , . . . , x20 . b) Verwenden Sie die Iterationsformel rückwärts. Geben Sie sich einen Startwert x20 ihrer eigenen Wahl vor. Aufgabe 5: Die Lösung des linearen Gleichungssystems 64919121 · x − 159018721 · y = 2 41869520.5 · x − 102558961 · y = −5 ist zu berechnen. a) Verwenden Sie dazu die Cramersche Regel und den Gauß-Algorithmus in MATLAB. b) Stören Sie die Eingabedaten der Koeffizientenmatrix in der letzten Stelle und berechnen Sie die Lösung mit den Formeln aus Teil a). c) Was geschieht, wenn nur die rechte Seite gestört wird? Aufgabe 6: Es soll die Lösung von f (x) = ∞ X i=0 xi ex − 1 = (i + 1)! x mit f (0) = 1 für x = 10−5 , 10−8 , 10−12 , 10−14 , 10−16 mit Hilfe der Exponentialfunktion berechnet werden. a) Implementieren Sie hierzu einen naiven Algorithmus, welcher die Exponentialfunktion in MATLAB nutzt. b) Verwenden Sie nun den Algorithmus: 18 y=exp(x); if y==1 f=1; else f=(y-1)/log(y); end f Aufgabe 7: Lassen Sie die nächsten beiden Berechnungen in MATLAB ausführen. for i = 1 : 60 √ x= x end for i = 1 : 60 x = x2 end Benutzen Sie dazu einmal 0 < x < 1 und einmal x > 1. 7 Auswertung und Überlegungen Für alle Beispiele sollen die mit MATLAB berechneten Ergebnisse in übersichtlicher Form nebeneinander dargestellt werden. Gestörte Eingabedaten sind jeweils mit anzugeben. In jedem Fall sollen die Konditionen des Problems, die Kondition des Verfahrens und die auftretenden Fehler (Rundungs-, Auslöschungs- und Konvertierungsfehler) schriftlich beurteilt werden. 8 Kurzeinführung MATLAB Mit help topic können Sie sich Details zu dem Befehl, der Funktion oder dem Symbol topic anzeigen lassen. Damit MATLAB Ergebnisse mit einer höheren Stellenanzahl anzeigt, sollten Sie zu Beginn Ihrer MATLAB Sitzung einmal format long eingeben. Zu Aufgabe 1: Ein Semikolon hinter einer Zuweisung unterdrückt die Ausgabe. >> p= 665857.0; >> r= 4*2 r= 8 Mit der ↑-Taste können die letzten Befehle zurückgeholt werden. help Befehl zeigt die Kurzhilfe an. Zu Aufgabe 2: Es ist möglich die Elemente eines Vektors elementweise zu berechnen. Dabei sind die Befehle ./ ; .* ; .b zu verwenden. >> x= 1; y=[2; 3; 4]; f= (y * x) ./ y . b 2 - factorial(3) 3!“ entspricht factorial(3) ” 19 Zu Aufgabe 3: Man kann auch mehrere Gleichungen in einem Vektor speichern. >> RESULT= [x-y; x b 2+y b 2; 3*x; -6] Zu Aufgabe 4: For-Schleifen und Ausgaben werden ähnlich wie in C realisiert. >> for n=1:20 xn= xn*n b 2; fprintf(’x%2g= %g\n’, n, xn) end ln 5“ entspricht log(5) ” Zu Aufgabe 5: 2x2 Matrix: Determinante: Spaltenvertauschung: Gauß-Algorithmus: >> >> >> >> A= [1, 2; -3, 4]; det(A); [b, A(:,2)] x= A\b Zu Aufgabe 6 + 7: Zum Berechnen der Exponentialfunktion und des Logarithmus können folgende Befehle verwendet werden: exp(x) log(x) Zum Quadrieren und Wurzelziehen bieten sich sqr(x) sqrt(x) an. 20