Verzögerte Evaluation und Streams
Aus ProgrammingWiki
Archivierte Version vom 2009-05-11T19:29:10+00:00. Aktuelle Version
Hinweis: Stellen Sie zunächst alle wesentlichen Prozeduren zur Arbeit mit Streams aus der Datei streams.ss bereit. Desweiteren sind folgende Definitionen als Hilfestellung gegeben: ( define integer - stream - maker
( lambda ( from )
( stream - cons from ( integer - stream - maker (+ from 1)))))( define integers ( integer - stream - maker 0)) Aufgaben
1. Machen Sie sich mit den Sprachelementen delay und force vertraut. Diskutieren
Sie zu zweit darüber, warum streams in Scheme als Paar dargestellt werden und
die Verbindung zu den eben genannten Sprachelementen.
2. Schreiben Sie eine Prozedur stream+, welche zwei streams mit Zahlen als Parame-
ter nimmt und deren Werte paarweise bis zum n-ten Element addiert und als Liste
zurückgibt.
Aufrufbeispiel:
> (print-stream (stream+ integers integers) 5)
0, 2, 4, 6, 8, ...
3. In den folgenden Aufgaben wird es um Zahlenfolgen gehen. Folgende zwei Zahlen-
folgen sind gegeben:
Die roten Hervorhebungen zeigen den “Fortschritt” der Zahlenfolgen. Versuchen
Sie das Erzeugungsmuster nachzuvollziehen.
Hinweis: aus eigener Erfahrung weiß ich, dass es oft hilfreich ist beim Programmieren einen Zettel und einen Stift parat zu haben, um sich einige Gedankengänge zu notieren (es kommt manchmal vor, dass man eine gute Idee hat und eine Minute später wieder vergessen hat)!
4. Implementieren Sie nun die beiden Zahlenfolgen von oben in Scheme mit Hilfe von
Streams und Rekursion.
Aufrufbeispiel für (an ):
> (define an (an-stream-maker 0)))
> (print-stream an 5)
0.7071067811865475, 0.6077812620656623, 0.6192477250610301,
0.6178907764054561, 0.6180508933676908, ...
Aufrufbeispiel für (bn ):
> (define bn (bn-stream-maker 0)))
> (print-stream bn 5)
1, 1/2, 2/3, 3/5, 5/8, ...5. Schreiben Sie eine Prozedur grenzwert, die den Grenzwert einer Zahlenfolge bestimmt. Diese soll wie folgt aussehen:
( grenzwert stm eps max )
Genauer gesagt soll diese Prozedur den Grenzwert einer als Stream repräsentierten
Zahlenfolge stm zurückgeben, wenn dieser innerhalb einer hinreichend kleinen ε-
Umgebung (eps) liegt. Falls nicht max Folgenglieder in dieser ε-Umgebung liegen,
wird Divergenz vermutet und #f zurückgegeben.
Ermitteln und vergleichen Sie die Grenzwerte der Zahlenfolgen (an ) und (bn ).
Testen Sie ihre Grenzwert-Prozedur wenigstens mit folgenden Aufrufbeispielen.
(Dabei wird nicht erwartet, dass Sie die Definition von tf wirklich verstehen):
( define tf
( let make (( start 0))
( stream - cons (/ start (1+ start )) ( make (1+ start )))))
> (grenzwert tf 1/110 10)
9/10
> (grenzwert tf 1/110 9)
#f
> (grenzwert tf 1/111 11)
10/11
> (grenzwert tf 1/111 10)
#f6. Implementieren Sie die Zahlenfolge
1 1 1 1 1
, , , , ...,
(en ) =
0! 1! 2! 3! n!
Def
Hinweis: 0! = 1
Aufrufbeispiel für(en ):
> (define en (en-stream-maker 0)))
> (print-stream en 5)
11, 1, 1/2, 1/6, 1/24, ...
Schreiben Sie anschließend eine Prozedur pasu-stream, die eine Zahlenfolge als
Stream nimmt und die zu dieser Zahlenfolge gehörende Partialsummenfolge als
Stream zurückgibt. Falls diese Partialsummenfolge konvergiert, entspricht ihr
Grenzwert der Summe der unendlichen Reihe
∞
1 1 1 1
1
= + + + + ...
i! 0! 1! 2! 3!
i=0
Aufrufbeispiel:
> (print-stream (pasu-stream en) 5)
1, 2, 5/2, 8/3, 65/24, ...
Mit Hilfe der Prozeduren grenzwert und pasu-stream kann nun die Summe einer
Reihe ermittelt werden.
Aufrufbeispiele:
> (grenzwert (pasu-stream en) 1/10 10)
2
23
> (grenzwert (pasu-stream en) 1/100 10)
2 17
24
> (grenzwert (pasu-stream en) 1/1000 10)
2 517
720