next up previous contents
Next: Auswertung von Ausdrücken Up: Grundlegende Sprachelemente Previous: Operatoren

Beispiel: Newton-Approximation

Das Verfahren zur Ermittlung einer Nullstelle einer Funktion f: R $\rightarrow$R ist uns aus dem 1. Semester bekannt:

x0 := geeigneter Startwert

xi+1 := xi - f(xi)/f´(xi)


\begin{picture}(8,9)
\par % Achsenabschnitte
\multiput(2,2.9)(1,0){5}{\line(0,1)...
...8}}
\par % Kurve
\qbezier(0,2)(4,2)(5,4)
\qbezier(5,4)(5.5,5)(6,8)
\end{picture}

es gilt: $f'(x) \approx \frac{0-f(x_i)}{x_{i+1}-x_i}$

Das Verfahren ist wie geschaffen für imperative Programmierung:

also interessant, ob man sowas -- und zwar gut! -- funktional erledigen kann!

Wir erinnern uns:

Daher die offensichtliche Lösung:

 newton :: (Float->Float)->Float->Float

newton f x
|abs(f x) < 0.001 = x - Feierabend wenn gut genug
|otherwise = newton f (x - f x / diff f x) - weiter

Anwendung z.B. so:

 Main> newton (\x->x^2-2) 10  -loest x^2-2 = 0, d.h. Wurzel 2, Start bei 10

1.41454

Hat man erst eine Programmieraufgabe gelöst, so sollte man gleich fragen, ob sich die Lösung verallgemeinern läßt, d.h. gibt es hier eine Struktur, ein Muster, das mehrfach angewendet werden kann?

Bestandteile der Lösung sind:

Idee:

Mache aus dem Wiederholungsmechanismus eine Funktion, die die drei anderen Bestandteile als Parameter hat!

Daher definiere:

 until :: (a->Bool)->(a->a)->a->a

| | | |-- Ergebnis
| | |-- Startwert
| |-- Verbesserung
|-- Abbruchkriterium

Und natürlich a = Typvariable, d.h. egal, in welchem Wertebereich wir arbeiten, also polymorphe Funktion.

 repeat_until::(a->Bool)->(a->a)->a->a

repeat_until crit change x
|crit x = x -zufrieden
|otherwise = repeat_until crit change (change x) -weiter

Einfaches Anwendungsbeispiel:

 Main> repeat_until even pred 10

10
Main> repeat_until even pred 11
10

Wobei die Standardfunktionen

 even :: Int -> Bool     - "ist gerade"

pred :: Int -> Int - "Vorgänger"

vorhanden sind.

Jetzt damit zurück zu Newton:

 newton :: (Float->Float)->Float->Float

newton f x = repeat_until n_crit n_change x
where n_crit x = abs(f x) < 0.001
n_change x = x - f x / diff f x

Anwendung für Quadratwurzelberechnung:

 Main> newton (\x->x^2-2) 10

1.41454
Main> newton (\x->x^2-25) 10
5.0
Main> newton (\x->x^2-80) 10
8.94427

usw.

Beachte:

Anwendung der Newton-Iteration hat ihre mathematischen Grenzen, und man muß sich für wirklich gute Ergebnisse auch noch in der numerischen Mathematik auskennen und Sorgfalt hinsichtlich Startwerten, Abbruchkriterien, genaue Formulierungen des Iterationsschritts ... walten lassen!


next up previous contents
Next: Auswertung von Ausdrücken Up: Grundlegende Sprachelemente Previous: Operatoren
Ronald Blaschke
1998-04-19