Wie kann ich eine Integralberechnung programmieren?
Ich soll von einer Funktion das Integral berechnen. Ich habe es so gemacht:
def funktion(x):
return x**3 - 2 * x**2 + x - 3
print(funktion(0)) # Beispielberechnung von Funktionswert an Stelle x = 0
def integrate(start, end, step):
fläche = 0
while start < end:
fläche += funktion(start) * step
start += step
return fläche
def adaptive_anpassung(toleranz):
tolernaz = 0.01
ergebnis = integrate(start, end, step)
neues_ergebnis = integrate(start, end, step / 2)
while abs(ergebnis - neues_ergebnis) > tolernaz:
neues_ergebnis = integrate(start, end, step / 2)
#Beispielaufruf
start = 0
end = 2
step = 0.001
print(integrate(start, end, step))
Zusätzlich soll ich eine Funktion implementieren, die schrittweise den Wert step verkleinert, bis die Veränderungen des Ergebnisses der integrate-Funktion kleiner als 0.01 ist. Ich habe die Funktion adaptive_anpassung genannt, aber irgendwie will es nicht. Kann mir jemand helfen?
1 Antwort
Ich würde ja ergebnis auch mal aktualisieren.
while abs (ergebnis-neues_ergebnis)>tolernaz:
ergebnis=neues_ergebnis
neues_ergebnis=integrate(start,end,step/2)
Du willst ja sichergehen, daß das Delta der Integrationsergerbnisse unter den Grenzwert fällt, um zuzusichern, daß das numerische Ergebnis ausreichend genau ist.
Und natürlich müßtest Du die Funktion dann auch mal aufrufen.
Vielleicht verstehst Du es so:
>>> print("\n".join(f'{1/x:.4f}: {integrate(1,20,1/x):.4f}' for x in range(1,25)))
1.0000: 31293.0000
0.5000: 33027.9375
0.3333: 36022.2963
0.2500: 33912.9219
0.2000: 35534.7200
0.1667: 34210.5116
0.1429: 35326.7755
0.1250: 34359.7930
0.1111: 35211.5144
0.1000: 34449.5175
0.0909: 34482.1736
0.0833: 35110.8154
0.0769: 35087.5976
0.0714: 34552.2028
0.0667: 35050.4652
0.0625: 34584.3232
0.0588: 35022.0830
0.0556: 34609.3161
0.0526: 34619.8421
0.0500: 34629.3169
0.0476: 34981.5571
0.0455: 34645.6854
0.0435: 34966.5860
0.0417: 34659.3288
Erkennst Du das Grundproblem?
Ich zitiere derweil aus der Frage:
Zusätzlich soll ich eine Funktion implementieren, die schrittweise den Wert step verkleinert, bis die Veränderungen des Ergebnisses der integrate-Funktion kleiner als 0.01 ist.
Der Knackpunkt ist hier die Veränderung.
Und so könnte dasdann zum Beispiel aussehen:
def adaptive_anpassung(start,end,step,epsilon):
ergebnis = integrate(start, end, step)
neues_ergebnis = integrate(start, end, step / 2)
while abs(ergebnis - neues_ergebnis) > epsilon:
step=step/2
ergebnis=neues_ergebnis
neues_ergebnis = integrate(start, end, step / 2)
return neues_ergebnis
Das ließe sich auch schöner formulieren, aber seis drum.
ich glaube net das ich versthe was du meinst
Dann ist da noch ein weiteres Hindernis: Mit einem so großen Wert wie 0.01 für epsilon bzw. toleranz ist abs(ergebnis - neues_ergebnis) von Beginn an nicht > sondern < als epsilon. Die Schleife beginnt darum gar nicht erst zu laufen und die adaptive Anpassung findet nicht statt.
Wenn das Delta eben kleiner als der angegebene Wert ist, dann klar, wird direkt das Ergebnis des halben Steppings genommen, weil das Stepping offensichtlich klein genug war.
Ein anderes Grundproblem bei der Nutzugn von Floats ist die nicht homogene Präzision über den Zahlenbereich - sidn meine Werte groß genug, dann kann es passieren, daß die Differenz nie unter die Schranke fällt. Insofern wäre es vielleicht schlauer sowas wie Decimal zu nutzen.
eins verstehe ich immer noch nicht warum diese Zeile:step=step/2
in meinen letzen beiden zeilen sage ich ja ergbnis ist jetzt neues ergebnis das wiederum ist die funktion integrate wo aber schon die step halbierung mit beinhaletet ist.Wenn dort doch bereits step jedes mal halbiert wieder wieso brauch ich das extra noch mal in der zeile step=step/2
Geh es doch einfach mal Schritt für Schritt durch. Bedenke, daß ein step/2 beim Aufruf sich nicht auf step selbst auswirkt.
das mit dem ergebnis aktualisieren versteh ich nicht waruk ergebis=neues ergebnis?