Integralberechnung in Dr. Racket: Welcher Wert wird bei plusdx eingesetzt?

1 Antwort

Ich würde es erst einmal an einem viel einfacheren Beispiel zeigen.

Hier hast du drei Prozeduren:

(define (calculate operation numberOne numberTwo)
  (operation numberOne numberTwo)
)
(define (add numberOne numberTwo) (+ numberOne numberTwo))
(define (subtract numberOne numberTwo) (- numberOne numberTwo))

Die Prozedur add berechnet die Summe von zwei Werten und die Prozedur subtract eine Differenz.

Die Prozedur calculate wiederum hat einen Parameter operation, in den später bei Aufruf eine Prozedur hineingereicht wird. Die wird im Prozedurkörper dann auch aufgerufen.

In der Praxis wären also folgende Aufrufe möglich:

(display (calculate add 4 3)) ;7
(display (calculate sub 4 3)) ;1

In deinem Fall wird die Prozedur plusdx als lokale Prozedur im Prozedurkörper von integral definiert und später als Argument an die Prozedur summe übergeben.

(summe f (+ a (/ dx 2.0)) plusdx b)

Dort wird sie dem dritten Parameter (naechster) zugewiesen. Wenn der Wert des vierten Parameters (b) größer ist, als der Wert des zweiten Parameters (a), hast du im Prinzip diesen Aufruf:

(+ (quadrat a) (summe quadrat (plusdx a) plusdx b))

Wenn du den gesamten Programmverlauf einmal durchgehen möchtest, würde ich dir empfehlen, konkrete (kleine) Werte für die Argumente einzusetzen und dann Schritt für Schritt die einzelnen Anweisungen aufzulösen. Das sollte dabei helfen, die Funktionsweise des Programms besser zu verstehen.

Beispiel:

a = 1
b = 2
dx = 1

1 > 2 => nicht wahr
(+ 1 (summe quadrat 2 plusdx 2))

  2 > 2 => nicht wahr
  (+ 4 (summe quadrat 3 plusdx 2))

    3 > 2 => 0

  (+ 4 0) = 4
(+ 1 4) = 5

Mach das am besten mit Stift und Papier / in einem Texteditor / o.ä. und schreibe die Schritte so, wie sie für dich am verständlichsten sind.

Interessant ist zu guter Letzt noch die Definition von plusdx.

(define (plusdx x) (+ x dx))

Wie du siehst, addiert sie ihr übergebenes Argument mit dx. Die Variable dx kommt aus integral (dort ist es ein Parameter) und plusdx hat sich diesen Wert gemerkt.

Man spricht hierbei von einem Closure. Ein Closure ist eine Prozedur, die sich Werte aus der Umgebung, in der sie definiert wurde, merken kann. Immer wenn sie aufgerufen wird, kann sie auf diese gemerkten Werte wieder zurückgreifen.


RedDevil1982 
Fragesteller
 14.11.2022, 21:26

Soweit Danke!. Durch deine Erklärung wurde es schon etwas verständlicher.

Ich setzte jetzt mal die Anfangs-Werte von (integral quadrat 0 10 0.1) ein,

dann steht da

(define (integral quadrat 0 10 0.1)

(define plusdx....)

(* (summe quadrat (+ 0 0.1/2.0) plusdx 10) dx)

Jetzt werden diese Parameter an die Funktion summe, die andersweitig def. wurde übergeben

(define (summe quadrat 0.05 plusdx 10)

(if (> 0 10) 0

(+ (quadrat 0.05) (summe quadrat (0.05 + 0.1) plusdx 10)

D. h. quadrat 0.05 wird nach oben zurückgegeben wodurch oben steht

(* 0.05² 0.1) = 1/4000

Unser Prof hat auch gesagt, dass er am Anfang für dx 1 einsetzt,

Allerdings wird doch per (integral quadrat 0 10 0.1) für dx 0.1 übergeben und nicht 1 ????

Er hat dann gerechnet 0,5² * dx (wobei dx 1 sein soll) + 1,5² * dx + 2,5² * dx usw.

dx war immer 1???? Wie komme ich auf 0,5²?

0
regex9  15.11.2022, 04:48
@RedDevil1982

Da das letzte Argument für die integral-Prozedur 0.1 ist, ist dx auch 0.1.

Aufruf:
(integral quadrat 0 10 0.1)

plusdx:
(define (plusdx x) (+ x 0.1))

Interner Aufruf:
(* (summe quadrat (+ 0 (/ 0.1 2.0)) plusdx 10) 0.1) =
(* (summe quadrat 0.05 plusdx 10))

Bei der Summenberechnung sollte auffällig werden, dass bei jedem rekursiven Aufruf a (durch die plusdx-Prozedur) um 0.1 erhöht und dazu noch das Quadrat des aktuellen a-Werts berechnet wird:

a = 0.05  quadrat = 0.0025000000000000005
a = 0.15  quadrat = 0.022500000000000006
a = 0.25  quadrat = 0.0625
etc. ...

Das passiert so lange, bis a > 10.

Es genügt daher, die Quadratzahlen von 0.05 bis ~9.95 (inklusiv) zu berechnen. Es kann sein, dass die folgenden Werte minimale Rundungsfehler beinhalten.

0.0025000000000000005
0.022500000000000006
0.0625
0.12249999999999998
0.20249999999999996
0.30249999999999994
0.4224999999999999
0.5624999999999999
0.7224999999999998
0.9024999999999997
1.1024999999999996
1.3224999999999998
1.5625
1.8225000000000002
2.1025000000000005
2.4025000000000007
2.722500000000001
3.0625000000000018
3.422500000000002
3.8025000000000024
4.202500000000003
4.622500000000003
5.062500000000004
5.522500000000004
6.002500000000005
6.502500000000006
7.022500000000006
7.562500000000007
8.122500000000008
8.70250000000001
9.302500000000009
9.92250000000001
10.562500000000012
11.222500000000013
11.902500000000014
12.602500000000015
13.322500000000016
14.062500000000016
14.822500000000018
15.602500000000019
16.40250000000002
17.222500000000018
18.062500000000014
18.922500000000014
19.80250000000001
20.702500000000008
21.622500000000002
22.5625
23.522499999999997
24.502499999999994
25.50249999999999
26.522499999999987
27.562499999999982
28.622499999999977
29.702499999999972
30.80249999999997
31.922499999999964
33.06249999999996
34.222499999999954
35.40249999999995
36.60249999999994
37.82249999999994
39.062499999999936
40.32249999999993
41.60249999999992
42.90249999999992
44.22249999999991
45.56249999999991
46.9224999999999
48.30249999999989
49.70249999999989
51.12249999999988
52.56249999999987
54.022499999999866
55.502499999999856
57.00249999999985
58.522499999999845
60.06249999999984
61.622499999999825
63.202499999999816
64.80249999999981
66.4224999999998
68.0624999999998
69.72249999999978
71.40249999999978
73.10249999999976
74.82249999999976
76.56249999999976
78.32249999999974
80.10249999999974
81.90249999999972
83.72249999999971
85.5624999999997
87.4224999999997
89.30249999999968
91.20249999999967
93.12249999999966
95.06249999999966
97.02249999999964
99.00249999999963

Diese Werte werden anschließend miteinander addiert:

3333.2499999999923

Somit lässt sich der innere Aufruf in integral vollständig auflösen.

(* 3333.2499999999923 0.1)

Das ergibt dann ~333.325. Also denselben Wert, aufgerundet, wie er auch auf deinem ersten Bild steht.

0