Suche Quellcode Übersetzung

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
anonym19

Hallo Leute,

ich bin auf der Suche nach jemanden der mir den im Anhang beiliegenden Code "übersetzen" könnte.
Biete 15€ per Paypal.
Damit meine ich Stichpunkthaltig was passiert in Zeile xy, was macht dieser Operator etc.
z.B rechts daneben am Rand

Es geht hierbei um eine Iterationsmethode mit dem Trapez und dem Simpsonverfahren.

Diese sollen am Ende gegenübergestellt werden und das Konvergenzverhalten soll dokumentiert werden.
Ziel ist es das der Leser neben den Quellcode eine Übersetzung daneben liegen hat, bei der er nachvollziehen kann was dort genau geschieht und programmiert wird!

Die Screenshots hab ich in einen Dropbox Ordner gepackt :)

https://1drv.ms/u/s!Av3mnwAi2mF0kyJnAFmR65sThvoU?e=ePGOvP

https://1drv.ms/u/s!Av3mnwAi2mF0kyJnAFm ... U?e=ePGOvP



Vielen Dank
Benutzeravatar
__blackjack__
User
Beiträge: 13113
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@rectosh99: Wenn Du Quelltext zeigen möchtest, dann bitte als Text hier in einem Beitrag, nicht als Bilder vom Editor bei einem externen Cloud-Hoster.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
__deets__
User
Beiträge: 14543
Registriert: Mittwoch 14. Oktober 2015, 14:29

Aber dann kann doch der Dozent/Lehrer/Prof die Loesung googeln....
anonym19

@__blackjack__
Verzeihung!

import numpy as np
import pylab as pl
#--------------------------------------------
def fu(x):
#--------------------------------------------
#return np.exp(-x**2)
return np.sin(x)/(x+1)+0.2
#return 2*x**2-x+1 # hier liefert Sipson den korr Wert!!

#--------------------------------------------
def IntTrapez(a, b, n):
#--------------------------------------------
sr = []
X = []
Y = []
X.append(a)
Y.append(fu(a))

dx = (b-a)/n
s = (fu(a) + fu(b))/2
xi=a
for i in range(2,n+1,1):
xi += dx
s += fu(xi)

cs = " Trapez: i=%2d x=%6.2f f(x)=%6.2f summe=%8.5f" % (i, xi, fu(xi), s*dx)
X.append(xi)
Y.append(fu(xi))
sr.append(cs)
s *= dx
X.append(b)
Y.append(fu(b))
return (s, sr, X, Y)


#--------------------------------------------
def IntSimpson(a, b, n):
#--------------------------------------------
sr = []
if (n % 2 != 0):
sr.append("Simpson: n muss gerade sein.")
return (0, sr)
dx = (b - a) / n
s = fu(a) + fu(b)
xi = a
for i in range(1,n,1):
xi = xi + dx
if (i % 2 == 0 ):
s += 2 * fu(xi)
else:
s += 4 * fu(xi)
cs = " Simpson: i=%2d x=%6.2f f(x)=%6.2f summe=%8.5f" % (i, xi, fu(xi), s*dx/3)
sr.append(cs)
return (s*dx/3 , sr)

#--------------------------------------------
def IntGauss3(a, b):
#--------------------------------------------
sr = []
xsi =[-0.774596669241483, 0, 0.774596669241483]
alpha =[0.555555555555556, 0.888888888888889, 0.555555555555556]
s = 0
for i in range(0,3,1):
xi = (a + b) / 2 + xsi * (b - a) / 2
Wi = alpha * (b - a) / 2
s += Wi * fu(xi)
cs = " Gauss3: i=%2d xi=%6.4f Wi=%6.4f f(xi)= %6.2f summe=%8.5f" % (i, xi, Wi, fu(xi), s)
sr.append(cs)
return (s, sr)

#--------------------------------------------
def SubsequCallToAllMethods(a,b,n):
#--------------------------------------------
# unsere Ergebnisse:
(sTr,srT,Xi,Yi) = IntTrapez(a, b, n)
(sSi,srS) = IntSimpson(a, b, n)
(sGs,srG) = IntGauss3(a, b)

print("Trapez =", sTr)
for c in srT :
print(c)
print("Simpson =", sSi)
for c in srS :
print(c)
print("Gauss3 =", sGs)
for c in srG :
print(c)

# Plot:
X = np.linspace(a,b,100)
Y = fu(X)


ax=pl.gca()
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data',0))

clabel =("f(x)")
pl.plot( X, Y, 'b', label=clabel)

clabel =("Trapez = %8.6f") % (sTr)
pl.plot( Xi, Yi, 'g', label=clabel)



#pl.scatter(X, Y)
pl.xlabel("x")
pl.ylabel("f(x)")
pl.legend ()
pl.show()
#--------------------------------------------
def Konvergenztester(a,b):
#--------------------------------------------
results_n1 =[]
results_n2 =[]
results_Trapez = []
results_Simpson = []
err_Trapez = []
err_Simpson = []
quitAtRoudOffErrPerc = 0.005
(errp1, errp2) = (1e100,1e100)
happy = False
iTest1, iTest2 = 0,0
for n in range(4,1000,2):

(intTrapez,srT,Xi,Yi) = IntTrapez(a, b, n)
(intSimpson,srS) = IntSimpson(a, b, n)
if(len(results_Trapez) > 0 and len(results_Simpson) > 0):

errp1 = abs((results_Trapez[-1] - intTrapez)/intTrapez) * 100
errp2 = abs((results_Simpson[-1] - intSimpson)/intSimpson) * 100

if(errp1 > quitAtRoudOffErrPerc or len(results_n1) == 0):
iTest1 += 1
results_n1.append(n)
err_Trapez.append(errp1)

if(errp2 > quitAtRoudOffErrPerc or len(results_n2) == 0):
iTest2 += 1
results_n2.append(n)
err_Simpson.append(errp2)

results_Trapez.append(intTrapez)
results_Simpson.append(intSimpson)

if(errp1 <= quitAtRoudOffErrPerc and errp2 <= quitAtRoudOffErrPerc):
happy = True
break
if(not happy):
print("Keine Konvergenz nach", n , "Schritten")

clabel = "Trapezregel %s intervals, err=%6.2f %% after %d steps" % (results_n1[-1],err_Trapez[-1],iTest1)
pl.plot( results_n1, err_Trapez, 'b', label="%s" % clabel)
clabel = "Simpson %s intervals, err=%6.2f %% after %d steps" % (results_n2[-1],err_Simpson[-1],iTest2)
pl.plot( results_n2, err_Simpson, 'g', label="%s" % clabel)

pl.xlabel(r'$intervals$')
pl.ylabel(r'$est. err. [\%] $')
pl.legend ()
pl.show()


#--------------------------------------------
def main():
#--------------------------------------------
# Eingabe:
inpStr = input("Integrationsformeln\nGib a= b= n= (mit , getrennt)")
nSeps = inpStr.count(',')
if (nSeps != 2):
print("error: you have to define a,b,n separated by exactly two commas such as 0,1,10")
return False

(a,b,n) = inpStr.split(",")

if (a.isnumeric() == False or b.isnumeric() == False or n.isnumeric() == False):
print("error: a,b,n have to be numbers")
return False

(a,b,n) = [float(a), float(b), int(n)]
print("a=",a,"b=",b,"n=",n)


SubsequCallToAllMethods(a,b,n)

Konvergenztester(a,b)



#input("...press any key to continue")


#--------------------------------------------
#--------------------------------------------
if __name__ == "__main__":
main()
anonym19

Kurz noch zum Hintergrund: Ich bin Bauingenieur, tätig in der Tragwerksplanung.
Zu meiner Studiumszeit haben wir ausschließlich VBA Programmierung behandelt.

Das Verständnis für die verschiedenen Integrationsmethoden habe ich noch:

Ich soll meinen Cousin etwas helfen, oben genannten Quellcode besser zu verstehen.

Programmieren darf/soll er dann andere Aufhaben selber! :)

Gruß
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Und was konkret verstehst Du daran nicht? Die mathematischen Formeln sind ja 1:1 in Python umgesetzt und damit selbsterklärend, wenn man die Mathematik verstanden hat.
anonym19

Ich verstehe da einiges nicht. Allein das Programmierungsprinzip ist mir völlig fremd.

Ich suche jemand der mir hilft, falls ja super, falls nicht dann nicht.

Irgendwelche Beiträge in denen ich meine schlechten Programmierkenntnisse erklären muss, möchte ich gerne abweisen.

Gruß
einfachTobi
User
Beiträge: 491
Registriert: Mittwoch 13. November 2019, 08:38

Sirius3 hat geschrieben: Mittwoch 6. Juli 2022, 09:22 Und was konkret verstehst Du daran nicht? (...)
rectosh99 hat geschrieben: Mittwoch 6. Juli 2022, 09:31 Ich verstehe da einiges nicht. (...)
Das ist wenig konkret. Ohne konkrete Frage kann man auch nicht richtig helfen; außer ebenso pauschal zu antworten: das "Programmierungsprinzip" ist hier erklärt https://docs.python.org/3/tutorial/index.html.
anonym19

"ich bin auf der Suche nach jemanden der mir den im Anhang beiliegenden Code "übersetzen" könnte."

"Damit meine ich Stichpunkthaltig was passiert in Zeile xy, was macht dieser Operator etc.
z.B rechts daneben am Rand"

Ich bin auf der Suche nach jemanden der Profi in dieser tollen Sache ist und für ihn ein leichtes Spiel ist. Natürlich könnte ich mir selbst alles erarbeiten, aber das ist hier nicht mein Gesuch in diesem Beitrag.

Wenn ich über eine Zeitunganzeige eine Reinigungskraft suche, bringen mir Anrufer die mir erzählen in welchem Supermarkt es das günstigste und beste Putzmittel gibt herzlich wenig.
Trotzdem Danke.

Wie vorhin gesagt, wenn sich jemand findet super, wenn nicht dann nicht! :)

Gruß
einfachTobi
User
Beiträge: 491
Registriert: Mittwoch 13. November 2019, 08:38

Wenn ich über eine Zeitungsanzeige eine Reinigungskraft suchte, beschriebe ich die Aufgaben aber auch detaillierter als "Es muss geputzt werden.". Wenn du nicht konkreter werden willst, sondern pauschal alles kommentiert haben möchtest, bin ich raus. Viel Erfolg.
Benutzeravatar
__blackjack__
User
Beiträge: 13113
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@rectosh99: Wenn man den Quelltext in Code-Tags setzt im Beitrag, dann bleiben die Einrückungen erhalten, die bei Python ja wichtiger Bestandteil der Syntax sind:

Code: Alles auswählen

import numpy as np
import pylab as pl 
#--------------------------------------------
def fu(x):
#--------------------------------------------
    #return np.exp(-x**2)
    return np.sin(x)/(x+1)+0.2
    #return 2*x**2-x+1  # hier liefert Sipson den korr Wert!!

#--------------------------------------------
def IntTrapez(a, b, n):
#--------------------------------------------
    sr = []
    X = []
    Y = []
    X.append(a)
    Y.append(fu(a))
     
    dx = (b-a)/n
    s = (fu(a) + fu(b))/2
    xi=a
    for i in range(2,n+1,1):
        xi += dx
        s += fu(xi)

        cs = "   Trapez: i=%2d x=%6.2f f(x)=%6.2f summe=%8.5f" % (i, xi, fu(xi), s*dx)
        X.append(xi)
        Y.append(fu(xi))
        sr.append(cs)
    s *= dx
    X.append(b)
    Y.append(fu(b))
    return (s, sr, X, Y)


#--------------------------------------------
def IntSimpson(a, b, n):
#--------------------------------------------
    sr = []
    if (n % 2 != 0):
        sr.append("Simpson: n muss gerade sein.")
        return (0, sr)
    dx = (b - a) / n
    s = fu(a) + fu(b)
    xi = a
    for i in range(1,n,1):
        xi = xi + dx
        if (i % 2 == 0 ):
            s += 2 * fu(xi)
        else:
            s += 4 * fu(xi)
        cs = "   Simpson: i=%2d x=%6.2f f(x)=%6.2f summe=%8.5f" % (i, xi, fu(xi), s*dx/3)
        sr.append(cs)
    return (s*dx/3 , sr)

#--------------------------------------------
def IntGauss3(a, b):
#--------------------------------------------
    sr = []
    xsi =[-0.774596669241483, 0, 0.774596669241483]
    alpha =[0.555555555555556, 0.888888888888889, 0.555555555555556]
    s = 0
    for i in range(0,3,1):
        xi = (a + b) / 2 + xsi[i] * (b - a) / 2
        Wi = alpha[i] * (b - a) / 2
        s += Wi * fu(xi)
        cs = "   Gauss3: i=%2d xi=%6.4f Wi=%6.4f f(xi)= %6.2f summe=%8.5f" % (i, xi, Wi, fu(xi), s)
        sr.append(cs)
    return (s, sr)

#--------------------------------------------
def SubsequCallToAllMethods(a,b,n):
#--------------------------------------------
    # unsere Ergebnisse:
    (sTr,srT,Xi,Yi) = IntTrapez(a, b, n)
    (sSi,srS) = IntSimpson(a, b, n)
    (sGs,srG) = IntGauss3(a, b)

    print("Trapez  =", sTr)
    for c in srT :
        print(c)
    print("Simpson =", sSi)
    for c in srS :
        print(c)
    print("Gauss3  =", sGs)
    for c in srG :
        print(c)
    
    # Plot:
    X = np.linspace(a,b,100)
    Y = fu(X)


    ax=pl.gca()
    ax.xaxis.set_ticks_position('bottom')
    ax.spines['bottom'].set_position(('data',0))

    clabel =("f(x)")
    pl.plot( X, Y, 'b', label=clabel)

    clabel =("Trapez = %8.6f") % (sTr)
    pl.plot( Xi, Yi, 'g', label=clabel)



    #pl.scatter(X, Y)
    pl.xlabel("x")
    pl.ylabel("f(x)")
    pl.legend ()
    pl.show()
#--------------------------------------------
def Konvergenztester(a,b):
#--------------------------------------------
    results_n1 =[]
    results_n2 =[]
    results_Trapez = []
    results_Simpson = []
    err_Trapez = []
    err_Simpson = []
    quitAtRoudOffErrPerc = 0.005
    (errp1, errp2) = (1e100,1e100)
    happy = False
    iTest1, iTest2 = 0,0
    for n in range(4,1000,2):
        
        (intTrapez,srT,Xi,Yi) = IntTrapez(a, b, n)
        (intSimpson,srS) = IntSimpson(a, b, n)
        if(len(results_Trapez) > 0 and len(results_Simpson) > 0):
            
            errp1 = abs((results_Trapez[-1] - intTrapez)/intTrapez) * 100
            errp2 = abs((results_Simpson[-1] - intSimpson)/intSimpson) * 100

            if(errp1 > quitAtRoudOffErrPerc or len(results_n1) == 0):
                iTest1 += 1
                results_n1.append(n)
                err_Trapez.append(errp1)

            if(errp2 > quitAtRoudOffErrPerc or len(results_n2) == 0):
                iTest2 += 1
                results_n2.append(n)
                err_Simpson.append(errp2)

        results_Trapez.append(intTrapez)
        results_Simpson.append(intSimpson)
        
        if(errp1 <= quitAtRoudOffErrPerc and errp2 <= quitAtRoudOffErrPerc):
            happy = True
            break
    if(not happy):
        print("Keine Konvergenz nach", n , "Schritten")

    clabel = "Trapezregel %s intervals, err=%6.2f %% after %d steps"  % (results_n1[-1],err_Trapez[-1],iTest1)
    pl.plot( results_n1, err_Trapez, 'b', label="%s" % clabel)
    clabel = "Simpson %s intervals, err=%6.2f %% after %d steps"  % (results_n2[-1],err_Simpson[-1],iTest2)
    pl.plot( results_n2, err_Simpson, 'g', label="%s" % clabel)
     
    pl.xlabel(r'$intervals$')
    pl.ylabel(r'$est. err. [\%] $')
    pl.legend ()
    pl.show()


#--------------------------------------------
def main():
#--------------------------------------------
    # Eingabe:
    inpStr = input("Integrationsformeln\nGib a=  b=  n= (mit , getrennt)")
    nSeps = inpStr.count(',')
    if (nSeps != 2):
        print("error: you have to define a,b,n separated by exactly two commas such as 0,1,10")
        return False

    (a,b,n) = inpStr.split(",")

    if (a.isnumeric() == False or b.isnumeric() == False or n.isnumeric() == False):
        print("error: a,b,n have to be numbers")
        return False
      
    (a,b,n) = [float(a), float(b), int(n)]
    print("a=",a,"b=",b,"n=",n)


    SubsequCallToAllMethods(a,b,n)

    Konvergenztester(a,b)



    #input("...press any key to continue")


#--------------------------------------------
#--------------------------------------------
if __name__ == "__main__":
    main()
Was meinst Di mit „Programmierungsprinzip“? Ich sehe da Funktionen mit prozeduralem Code als Inhalt, also nichts was sich jetzt wesentlich von Basic/VBA unterscheiden würde. Du hast da sogar ein bisschen Glück, dass da scheinbar nichts verwendet wird, was zu weit von VBA abweicht. Die Funktion hätte man beispielsweise als Argument übergeben können/sollen, statt da eine hart kodierte `fu()`-Funktion in den verschiedenen Integrationsvarianten aufzurufen. Funktionen sind in Python nämlich auch Werte.

Wo genau liegen denn die Verständnisprobleme? Was sind die Fragen die nach dem Durcharbeiten vom Grundlagentutorial in der Python-Dokumentation nicht geklärt sind? Was verstehst Du konkret nicht? Weicht irgendwo ein (Zwischen)Ergebnis von dem ab was Du erwartest? Was hättest Du da erwartet und was bekommst Du?

Hilfreich wäre vielleicht wenn Du das Programm etwas überarbeitest. Ich habe jetzt raus was die *Werte* von `sr` und `cs` bedeuten, aber nicht wirklich was die *Namen* bedeuten. Wenn man da sinnvolle Namen verwendet, wird es schon verständlicher. Im allgemeinden sollte man keine kryptischen Abkürzungen in Namen verwenden, und schon gar keine Namen die nur daraus bestehen. Denn der Zweck von Namen ist ja dem Leser die Bedeutung der Werte dahinter zu vermitteln.

Ich würde übrigens sagen, dass das Programm fehlerhaft ist, denn die Schrittweite ``dx = (b-a)/n`` berechnen und dann in jedem Schritt `dx` aufaddieren ist bei Gleitkommazahlen eine schlechte Idee, denn die sind nicht exakt und bei jeder Addition kann es dadurch ungenauer werden. An einer Stelle beim Plotten wird ja bereits `numpy.linspace()` verwendet. Insgesamt würde es vielleicht Sinn machen wenn man `numpy` mehr verwenden würde in dem Programm.

Das scheint auch nicht von einem Python-Programmierer zu sein. Es wird sich an einige Konventionen aus dem Style Guide for Python Code nicht gehalten. Zum Beispiel das Namen klein_mit_unterstrichen geschrieben werden, und was Leerzeichen- und Zeilensetzung angeht um die Lesbarkeit zu erhöhen. Dann gibt es unnötige Klammern um Bedingungen bei ``if`` & Co und den Defaultwert 1 für die Schrittweite bei `range()` gibt man auch nicht an. ”Linien”-Kommentare sind auch unüblich.

Man muss auch nicht jedes kleine Zwischenergebnis an einen Namen binden. Insbesondere wenn der Name dann auch noch kryptisch ist, macht dass das lesen/verstehen eher schwerer als einfacher.

Bei der `main()` machen die ``return False`` keinen Sinn, weil es nirgends ein ``return True`` gibt. Die Funktion gibt also entweder `False` oder `None` zurück.

Man vergleicht auch nicht mit literalen Wahrheitswerten. Da kommt ja nur wieder ein Wahrheitswert bei heraus. Also hätte man auch gleich den Wert nehmen können mit dem man vergleicht, beziehungsweise dessen negation. Also statt:

Code: Alles auswählen

    if (
        a.isnumeric() == False
        or b.isnumeric() == False
        or n.isnumeric() == False
    ):
        print("error: a,b,n have to be numbers")

# besser

    if not a.isnumeric() or not b.isnumeric() or not n.isnumeric():
        print("error: a,b,n have to be numbers")

# beziehungsweise

    if not (a.isnumeric() and b.isnumeric() and n.isnumeric()):
        print("error: a,b,n have to be numbers")
Diese Tests sind aber ein bisschen ”unpythonisch”. Man würde einfach die Umwandlung machen und auf den `ValueError` reagieren der dabei ausgelöst werden kann. Da Zuweisung an mehrere Namen auch mit einem `ValueError` fehl schlägt, wenn die Anzahl der Werte nicht passt, kann man das gleich mit berücksichtigen.

Den ``%``-Operator für Zeichenkettenformatierung benutzt man eigentlich schon lange nicht mehr ohne einen guten Grund. Dafür gibt es f-Zeichenkettenliterale.

Bei `konvergenztester()` sind viele schlechte Namen, die man besser sprechender wählen würde.

`iTest1` und `iTest2` sind überflüssig, weil das die Längen der dazugehörigen Listen sind, die man einfach mit `len()` abfragen kann.

Das ganze in einem ersten Überarbeitungsschritt (ungetestet) etwas „pythonischer“ und lesbarer:

Code: Alles auswählen

#!/usr/bin/env python3
import numpy as np
import pylab as pl


def funktion(x):
    # return np.exp(-x ** 2)
    return np.sin(x) / (x + 1) + 0.2
    # return 2 * x ** 2 - x + 1  # hier liefert Simpson den korrekten Wert!


def trapez_integration(a, b, n):
    summe = (funktion(a) + funktion(b)) / 2
    texte = []
    xs = [a]
    ys = [funktion(a)]

    x_i = a
    d_x = (b - a) / n
    for i in range(2, n + 1):
        x_i += d_x
        summe += funktion(x_i)

        xs.append(x_i)
        ys.append(funktion(x_i))
        texte.append(
            f"Trapez: i={i:2d} x={x_i:6.2f} f(x)={funktion(x_i):6.2f}"
            f" summe={summe * d_x:8.5f}"
        )

    xs.append(b)
    ys.append(funktion(b))
    return (summe * d_x, texte, xs, ys)


def simpson_integration(a, b, n):
    if n % 2 != 0:
        return (0, ["Simpson: n muss gerade sein."])

    summe = funktion(a) + funktion(b)
    texte = []
    x_i = a
    d_x = (b - a) / n
    for i in range(1, n):
        x_i += d_x
        summe += (2 if i % 2 == 0 else 4) * funktion(x_i)
        texte.append(
            f"Simpson: i={i:2d} x={x_i:6.2f} f(x)={funktion(x_i):6.2f}"
            f" summe={summe * d_x / 3:8.5f}"
        )

    return (summe * d_x / 3, texte)


def gauss3_integration(a, b):
    xsis = [-0.774596669241483, 0, 0.774596669241483]
    alphas = [0.555555555555556, 0.888888888888889, 0.555555555555556]
    summe = 0
    texte = []
    for i, (xsi, alpha) in enumerate(zip(xsis, alphas)):
        x_i = (a + b) / 2 + xsi * (b - a) / 2
        w_i = alpha * (b - a) / 2
        summe += w_i * funktion(x_i)
        texte.append(
            f"Gauss3: i={i:2d} xi={x_i:6.4f} Wi={w_i:6.4f}"
            f" f(xi)={funktion(x_i):6.2f} summe={summe:8.5f}"
        )

    return (summe, texte)


def subsequent_call_to_all_methods(a, b, n):
    trapez_summe, trapez_texte, trapez_xs, trapez_ys = trapez_integration(
        a, b, n
    )
    simpson_summe, simpson_texte = simpson_integration(a, b, n)
    gauss_summe, gauss_texte = gauss3_integration(a, b)

    for methoden_name, summe, texte in [
        ("Trapez", trapez_summe, trapez_texte),
        ("Simpson", simpson_summe, simpson_texte),
        ("Gauss3", gauss_summe, gauss_texte),
    ]:
        print(methoden_name, "=", summe)
        for text in texte:
            print("  ", text)

    ax = pl.gca()
    ax.xaxis.set_ticks_position("bottom")
    ax.spines["bottom"].set_position(("data", 0))

    xs = np.linspace(a, b, 100)
    pl.plot(xs, funktion(xs), "b", label="f(x)")

    pl.plot(trapez_xs, trapez_ys, "g", label=f"Trapez = {trapez_summe:8.6f}")

    pl.xlabel("x")
    pl.ylabel("f(x)")
    pl.legend()
    pl.show()


def konvergenztester(a, b):
    max_allowed_error = 0.005

    trapez_ns = []
    trapez_results = []
    trapez_errors = []

    simpson_ns = []
    simpson_results = []
    simpson_errors = []

    trapez_error = simpson_error = np.Infinity

    for n in range(4, 1000, 2):
        trapez_summe, _, _, _ = trapez_integration(a, b, n)
        simpson_summe, _ = simpson_integration(a, b, n)

        if trapez_results and simpson_results:
            trapez_error = (
                abs((trapez_results[-1] - trapez_summe) / trapez_summe) * 100
            )
            simpson_error = (
                abs((simpson_results[-1] - simpson_summe) / simpson_summe)
                * 100
            )

            if trapez_error > max_allowed_error or not trapez_ns:
                trapez_ns.append(n)
                trapez_errors.append(trapez_error)

            if simpson_error > max_allowed_error or not simpson_ns:
                simpson_ns.append(n)
                simpson_errors.append(simpson_error)

        trapez_results.append(trapez_summe)
        simpson_results.append(simpson_summe)

        if (
            trapez_error <= max_allowed_error
            and simpson_error <= max_allowed_error
        ):
            break
    else:
        print("Keine Konvergenz nach", n, "Schritten")

    for methoden_name, ns, errors, colour in [
        ("Trapezregel", trapez_ns, trapez_errors, "b"),
        ("Simpson", simpson_ns, simpson_errors, "g"),
    ]:
        pl.plot(
            ns,
            errors,
            colour,
            label=(
                f"{methoden_name} {ns[-1]} intervals,"
                f" err={errors[-1]:6.2f} % after {len(ns)} steps"
            ),
        )

    pl.xlabel(R"$intervals$")
    pl.ylabel(R"$est. err. [\%] $")
    pl.legend()
    pl.show()


def main():
    input_text = input(
        "Integrationsformeln\n" "Gib a=  b=  n= (mit , getrennt)"
    )
    try:
        a, b, n = map(int, input_text.split())
    except ValueError:
        print(
            "error: a,b,n must be numbers and separatet by exactly two commas."
        )
    else:
        print("a=", a, "b=", b, "n=", n)

        subsequent_call_to_all_methods(a, b, n)
        konvergenztester(a, b)


if __name__ == "__main__":
    main()
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
anonym19

@__blackjack__

Für deine verbesserung bedanke mich sehr! Wäre nicht nötig gewesen... Aber ganz großes Engagement! Danke!
Offiziell ist dieser Quellcode die Lösung eines Dozenten. Ich habe mich etwas in Phyton eingelesen und versuche es meinem Cousin einigermaßen verständlich zu erklären.

Gruß
Benutzeravatar
__blackjack__
User
Beiträge: 13113
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@rectosh99: Ich dachte es ist vielleicht leichter verständlich wenn bessere Namen verwendet werden und ein paar unnütze Sachen einfach wegfallen.

Kannst Du Dir das mit Deinem Cousin nicht gemeinsam erarbeiten? Die Grundlagen muss *er* ja schliesslich drauf haben, also was ein Operator bedeutet, was eine Liste an Operationen erlaubt und so weiter. Wobei das IMHO auch nicht wirklich „rocket science“ ist, denn so wirklich exotisches wird da ja gar nicht verwendet. Und Python selbst ist von der Syntax her ja auch relativ leichtgewichtig und das meiste auch ohne tiefergehende Kenntnisse verständlich.

Bei den Operatoren haben die meisten die normale mathematische Bedeutung. Aus der Reihe fallen ``**`` für Potenz, also ``x ** 3`` ist x³. Und ``%`` wenn man das nicht von Sprachen aus der C-Familie kennt: Modulo. Wäre in VBA ``MOD`` soweit ich weiss. War es jedenfalls in älteren Microsoft-BASIC-Dialekten.

Ansonsten hat die Dokumentation einen Index wo man nach Operatoren und Funktions- und Methodennamen schauen kann.

`trapez_results` und `simpson_results` könnte man auch noch vereinfachen, denn das müssten gar keine Listen sein, weil da immer nur auf das letzte Element zugegriffen wird. Alles davor interessiert nicht.

Dass das wiederholte aufaddieren von einem Gleitkommadeltawert von einem Dozenten kommt, ist IMHO ein bisschen beängstigend. Dozenten sollten doch wissen, dass man das nicht macht.

Last but not least: Man kann in Python, wie in den guten alten BASIC-Implementierungen, auch einfach eine interaktive Python-Shell starten und einfach mal sachen ”live” ausprobieren um sie Sprache oder Bibliotheken zu erforschen. Entweder einfach python als Programm in einer Konsole aufrufen, oder eine Shell mit mehr Funktionalität wie IPython in der Konsole oder per JupyterLab im Browser verwenden.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Idealerweise würde man ja bei der Trapez-Methode nicht jeden Funktionswert dreimal berechnen, sondern alles einmal vorberechnen. Die Summe ist etwas daneben, weil nicht wirklich Trapeze aufaddiert werden.

Code: Alles auswählen

def trapez_integration(a, b, n):
    xs = np.linspace(a, b, n + 1)
    ys = funktion(xs)
    d_x = xs[1] - xs[0]
    texte = []
    summe = ys[0] / 2
    for i, (x_i, y_i) in enumerate(zip(xs[1:-1], ys[1:-1]), 2):
        summe += y_i
        texte.append(
            f"Trapez: i={i:2d} x={x_i:6.2f} f(x)={y_i:6.2f}"
            f" summe={summe * d_x:8.5f}"
        )
    summe += ys[-1] / 2
    return (summe * d_x, texte, xs, ys)
Bei der Simpson-Interation gilt im Wesentlichen das selbe:

Code: Alles auswählen

def simpson_integration(a, b, n):
    if n % 2 != 0:
        return (0, ["Simpson: n muss gerade sein."])

    xs = np.linspace(a, b, n + 1)
    ys = funktion(xs)
    # factors are 1 4 2 4 ... 4 2 4 1
    factors = np.arange(n + 1) % 2 * 2 + 2
    factors[[0,-1]] = 1
    factors = factors / 3

    summe = 0
    d_x = xs[1] - xs[0]
    texte = []
    for i, (factor, x_i, y_i) in enumerate(zip(factors, xs, ys), 1):
        summe += factor * y_i
        texte.append(
            f"Simpson: i={i:2d} x={x_i:6.2f} f(x)={y_i:6.2f}"
            f" summe={summe * d_x:8.5f}"
        )
    return (summe * d_x, texte)
Antworten