Python < Python < Programmiersprachen < Praxis < Informatik < Vorhilfe
|
Status: |
(Frage) beantwortet | Datum: | 18:56 Sa 20.11.2010 | Autor: | jumape |
Aufgabe | Implementieren Sie das Newtonverfahren |
Ich habe schon zwei Ansätze,
der eine ist ohne Stopmechanismus, macht also so lange weiter bis er die exakte nullstelle hat, was blöd ist wenn diese zu finden ewig dauert, der andere ist mit einer Angabe über die Anzahl der Iterationsschritte.
1.
def newton(g=(),x0):
x_n1=x0
while g(x_n1)!=0:
x_n1=x_n1-(g(x_n1)/dg(x_n1))
end
2.
def newton(x0, itmax, g=()):
x_n1=x0
for i in range (1, itmax):
x_n1=x_n1-(g(x_n1)/dg(x_n1))
end
x0 ist der Startwert, itmax die anzahl der Iterationen und g soll die Funktion sein, deren nullstelle ich bestimmen möchte. Mein Problem ist jetzt, dass ich nicht weiß wie man g in die erste zeile schreibt. Ich habe den Teil mal rot markiert.
Ich möchte das Verfahren allgemein haben, also einfach die Funktion g, x0 und itmax angeben können und dann das Ergebnis bekommen, weiß aber nicht wie man eine Funktion in Python schreibt.
Vielleicht kann mir jemand helfen.
Vielen Dank
jumape
|
|
|
|
Hallo!
wenn du g(x) definiert hast, dann ist g ein Pointer auf diese Funktion. Du kannst dann g einfach übergeben und in der Funktion benutzen.
Guckstdu:
1: | def g(x):
| 2: | return (x*x)
| 3: |
| 4: | def h(x,q):
| 5: | return q(x)
| 6: |
| 7: | print g
| 8: |
| 9: | for i in range(10):
| 10: | print "h(%d,g)= %d"%(i,h(i,g))
|
liefert die Ausgabe
1: | <function g at 0x7f4fd65c9500>
| 2: | h(0,g)= 0
| 3: | h(1,g)= 1
| 4: | h(2,g)= 4
| 5: | h(3,g)= 9
| 6: | h(4,g)= 16
| 7: | h(5,g)= 25
| 8: | h(6,g)= 36
| 9: | h(7,g)= 49
| 10: | h(8,g)= 64
| 11: | h(9,g)= 81 |
Du kannst also g auch per print ausgeben, und siehst, daß das ein Funktionspointer ist.
Das funktioniert für Klassen übrigens genauso, und z.B. bei Listen sowieso.
Jetzt ist natürlich noch die Frage, wie du das Problem mit der Ableitung löst. Du kannst natürlich auch die Ableitung vorgeben, oder du bastelst sie dir numerisch selbst.
Und: Der Abbruch nach ner gewissen Iterationszahl ist gut, besser wäre ein Abbruch, wenn sich das Resultat der Rechnung von Schritt zu Schritt nur noch wenig ändert.
Optimal wäre eine Kombination aus beidem, für den Fall, daß das Resultat nicht konvergiert.
|
|
|
|
|
Status: |
(Frage) beantwortet | Datum: | 17:35 So 21.11.2010 | Autor: | jumape |
hallo,
erstmal danke für die schnelle Antwort. ich hatte gehofft ich könnte das ganz allgemein machen mit der Funktion g, aber so ist ja auch ok, wenn man die nur am Anfang des Codes ändern muss.
Bei der Ableitung hatte ich ehrlich gesagt gehofft es gibt da schon welche in irgendwelchen Pythonpaketen die man runterladen kann. Bei Matlab war das zumindest so. Kannst du mir da was raten?
Ich habe es jetzt mal angepasst wie ich es mir vorstellen könnte:
def g(x):
return(x*x)
def newton(x0, itmax):
x_n1=x0
for i in range (itmax):
x_n1=x_n1-(g(x_n1)/dg(x_n1))
print g
print "newton(%x0,%itmax)=", x_n1
Da bekomme ich jetzt folgende Fehlermeldung:
<function g at 0x021D1B30>
newton(%x0,%itmax)=
Traceback (most recent call last):
File [mm] "C:\Python26\Newton", [/mm] line 10, in <module>
print "newton(%x0,%itmax)=", x_n1
NameError: name 'x_n1' is not defined
da beschwert er sich x_n1 sei nicht definiert, aber das habe, also liegt es wohl an dg, dass er nicht kennt. Oder?
|
|
|
|
|
Hallo!
Die numerische Ableitung an einer Stelle ist ganz einfach [mm] g'(x)=\frac{g(x+d)-g(x-d)}{2d}
[/mm]
und für d nimmst du irgendwas kleines. Wenn du jetzt sagst, daß das NICHT wie der Differenzenquotient aus der Schule aussieht, dann ist das korrekt. Aber sie liefert bessere Ergebnisse.
Also, das ist nicht schwer zu berechnen. Kann gut sein, daß es das schon irgendwo in Python gibt, aber ich wüßte nicht, wo. Wenn, dann vermutlich in extra Mathepaketen.
Und dein Code hat einen Syntaxfehler:
Ich habe sowas verwendet:
print "%d + %d = %d"%(1, 2, 3)
hinter einen String, der diese Formatierungen mit dem % enthält, kommt ein weiteres % gefolgt von einem tupel, welches die einzusetzenden Zahlen durch Kommas getrennt enthält.
Auch das kannst du übrigens jederzeit auf Strings anwenden, auch z.B. so:
>>> rechnung="%d + %d = %d"%(1, 2, 3)
>>> rechnung
"1 + 2 = 3"
Im Code oben sieht das zugegeben etwas kryptisch aus, daher der Fehler.
|
|
|
|
|
Status: |
(Frage) beantwortet | Datum: | 00:06 Mi 24.11.2010 | Autor: | jumape |
Erstmal Danke für die Antwort.
Den Differenzenquotienten kenne ich, ich dachte nur Python würde das analytisch machen, aber ist natürlich Schwachsinn. Ich habe die Ableitung jetzt in mein Programm integriert, das meldet jetzt auch keinen Fehler mehr, allerdings möchte ich eigentlich gerne, dass es mich nach dem Startwert, den Iterationsschritten und der Schrittweite für die Ableitung fragt.
Ich weiß ich habe das schonmal in einem Programm mit diesem print und input gemacht, aber jetzt funktioniert es irgendwie nicht, zumindest gibt es mir keinen Output wenn ich es laufen lasse.
Kannst du mir sagen woran das liegt?
Viele Grüße jumape
print "Startwert eingeben:"
d=input("Schrittweite für Ableitung eingeben:")
print "Anzahl Iterationen eingeben:"
x0=input("Startwert eingeben:")
print "Schrittweite für Ableitung eingeben:"
itmax=input("Anzahl Iterationen eingeben:")
def g(x):
return(x*x)
def dg(x,d):
(g(x+d)-g(x-d))/2*d
def newton(x0, itmax):
x_n1=x0
for i in range (itmax):
x_n1=x_n1-(g(x_n1)/dg(x_n1))
print "newton(%x0,%itmax)="%(x0,itmax), x_n1
|
|
|
|
|
Hallo!
Zwei Dinge:
1. Probier mal d=float(raw_input("bla")). Ich weiß nicht, was input() macht, es scheint aber was anderes zu sein, als das, was ich denke, was es macht...
2. Schreibe ERST die drei Funktionen, und dann den eigentlichen Code. Du schreibst deine Funktionen zwischen den Code, das kann nicht gut gehen.
(In C müßtest du ne main() schreiben, die gibts in Python nicht, da schreibt man einfach drauf los. Aber in einer main() würde man auch keine Funktionen definieren, der Compiler würde dir was husten)
|
|
|
|
|
Status: |
(Frage) beantwortet | Datum: | 15:21 Di 30.11.2010 | Autor: | jumape |
Danke nochmal.
Das Programm läuft jetzt gibt aber keinen output.
D.h.:
Ich habe folgendes Programm:
d=float(raw_input("Schrittweite für Ableitung eingeben:"))
x0=float(raw_input("Startwert eingeben:"))
itmax=int(raw_input("Anzahl Iterationen eingeben:"))
def g(x):
return(x*x)
def dg(x,d):
(g(x+d)-g(x-d))/2*d
def x_n1(x0, itmax, g, dg):
x_n1=x0
for i in range (itmax):
x_n1=x_n1-(g(x_n1)/dg(x_n1,d))
print "newton(%x0,%itmax)="%(x0,itmax),(x_n1)
und folgenden Output:
Schrittweite für Ableitung eingeben:0.005
Startwert eingeben:0.5
Anzahl Iterationen eingeben:2
newton(00,2tmax)= <function x_n1 at 0x0227E730>
wobei ich die Werte 0.005; 0.5 und 2 eingegeben habe.
Was habe ich denn da jetzt noch falsch gemacht. Ich muss doch nicht nochmal die ganzen Variablen aufzählen oder?
hat jedenfalls so wie ich es gemacht habe auch nicht funktioniert.
vielen Dank
|
|
|
|
|
Hallo!
Zunächst wäre es guter Stil, deine input-Zeilen auch unter die def-Zeilen zu packen, wo auch dein print steht.
dann
print "newton(%x0,%itmax)="%(x0,itmax),(x_n1)
Hier willst du eher:
print "newton(%.3f,%d)="%(x0,itmax), x_n1
denn in dem String gibst du das Format der Zahlen vor. x0 soll ne Fließkommazahl mit 3 Nachkommastellen sein, und itmax wird als ganze Zahl ausgegeben.
%x versucht nun z.B. eine hexadezimale Zahl raus zu geben... Das kann so nicht klappen.
Das Hauptproblem ist aber:
Deine Funktionen müssen den ermittelten Wert auch mit einem return zurück geben.
Das g(x) macht das z.B.
Und dann mußt du deine Funktion mit den zugehörigen Parametern aufrufen, also so:
x_n1(1,2,3,4)
und nicht nur
x_n1
Die zweite Version ist eine Referenz auf die Funktion, nur die erste gibt - sofern ein return drin vor kommt - einen Wert zurück.
|
|
|
|
|
Status: |
(Mitteilung) Reaktion unnötig | Datum: | 22:50 Do 02.12.2010 | Autor: | jumape |
Super, jetzt läuft es.
Vielen vielen Dank für diesen kleinen Pythonkurs.
|
|
|
|
|
Status: |
(Frage) beantwortet | Datum: | 23:00 Do 02.12.2010 | Autor: | jumape |
Naja ich dachte ich hätte keine Frage mehr, aber dann ist mir aufgefallen, dass das Verfahren für 2 oder 3 Schritte läuft aber nicht mehr für 5 oder 10.
Als Fehler bekomme ich:
Traceback (most recent call last):
File [mm] "C:\Python26\Newton", [/mm] line 15, in <module>
print "newton(%x0,%itmax)="%(x0,itmax), x_n1(x0, itmax, g, dg)
File [mm] "C:\Python26\Newton", [/mm] line 8, in x_n1
x_n1=x_n1-(g(x_n1)/dg(x_n1,d))
ZeroDivisionError: float division
Heißt das, dass ich schon so nahe an meiner Lösung bin, dass Python eine Null gerundet hat und nicht dadurch teilen will?
Oder was will er von mir?
|
|
|
|
|
Status: |
(Antwort) fertig | Datum: | 12:41 Fr 03.12.2010 | Autor: | leduart |
Hallo
du brauchst doch ein Abbruchkriterium, das sollte die letzten 2 x vergleichen, wenn sie etwa [mm] <10^{-10} [/mm] sind willst du aussteigen. damit vermeidest du auch durch 0 zu teilen.
Da du dein pr. nichtmehr aufgeschrieben hast, kann man nichts anderes sagen.
Beim Programmentwickeln sollte man genug Zwischenausgaben einbauen, also warum nicht x in jedem Schritt ausgeben?
wenn alles funktioniert, baut man die überflüssigen printbefehle wieder aus.
Gruss leduart
|
|
|
|
|
Status: |
(Frage) beantwortet | Datum: | 18:01 Do 09.12.2010 | Autor: | jumape |
ok danke,
habe ich jetzt gemacht, fühle mich aber nicht schlauer mit der Ausgabe eher noch verwirrter, weil er mir bei mehr Iterationen andere Werte ausgibt als bei 3 Iterationen.
def g(x):
return(x*x)
def dg(x,d):
return(g(x+d)-g(x-d))/2*d
def x_n1(x0, itmax, g, dg):
x_n1=x0
for i in range (itmax):
x_n1=x_n1-(g(x_n1)/dg(x_n1,d))
print x_n1
return (x_n1)
d=float(raw_input("Schrittweite für Ableitung eingeben:"))
x0=float(raw_input("Startwert eingeben:"))
itmax=int(raw_input("Anzahl Iterationen eingeben:"))
print "newton(%x0,%itmax)="%(x0,itmax), x_n1(x0, itmax, g, dg)
Schrittweite für Ableitung eingeben:0.005
Startwert eingeben:0.5
Anzahl Iterationen eingeben:3
newton(00,3tmax)= -9999.5
199980000.535
-3.99940804142e+12
-3.99940804142e+12
>>> ================================ RESTART ================================
>>>
Schrittweite für Ableitung eingeben:0.005
Startwert eingeben:0.5
Anzahl Iterationen eingeben:10
newton(00,10tmax)= -9999.5
199980000.535
-3.99940804142e+12
8.27557288425e+16
Traceback (most recent call last):
File [mm] "C:\Python26\Newton", [/mm] line 16, in <module>
print "newton(%x0,%itmax)="%(x0,itmax), x_n1(x0, itmax, g, dg)
File [mm] "C:\Python26\Newton", [/mm] line 8, in x_n1
x_n1=x_n1-(g(x_n1)/dg(x_n1,d))
ZeroDivisionError: float division
Dann habe ich es mit dem Abbruchkriterium versucht aber da sagt er mir ich hätte bei dem letzten print einen Syntaxfehler gemacht und das versteh ich nicht. Wo ist da der Syntaxfehler?
def betrag(zahl):
if zahl < 0:
return -zahl
else:
return zahl
def g(x):
return(x*x)
def dg(x,d):
return(g(x+d)-g(x-d))/2*d
def x_n1(x0, x_n2, g, dg):
x_n1=x0
while betrag(x_n1-x_n2)>maxerror:
x_n1=x_n2-(g(x_n2)/dg(x_n2,d))
print x_n1
else:
return(x_n1)
break
def x_n2(x_n1, x0):
x_n2=x0
while betrag(x_n1-x_n2)>maxerror:
x_n2=x_n1
else:
x_n2=x_n2
d=float(raw_input("Schrittweite für Ableitung eingeben:"))
x0=float(raw_input("Startwert eingeben:"))
maxerror=float(raw_input("Geben Sie die gewünschte Genauigkeit an")
print "newton(%x0,%maxerror)="%(x0,maxerror), x_n1(x0, x_n2, g, dg)
Das habe ich jetzt auch mal rot markiert, oder liegt das an dem, sicherlich noch sehr fehlerhaften, eigentlichen Programm?
Kann man das überhaupt so machen, oder muss man die Definitionen von x_n1 und x_n2 ineinander schachteln? Oder sollte man das lieber als Vektor (x_n1, x_n2) definieren?
Ich habe keine Ahnung. vielleicht kannst du mir nochmal helfen.
grüße
jumape
|
|
|
|
|
Hallo!
Oha, der Code ist aber sehr unübersichtlich geworden.
Du verwendest anscheinend x_n1 sowohl als Variable als auch als Funktion. Das würde ich tunlicht vermeiden.
Und denk dran, wenn eine Funktion einen Wert zurück liefern soll, so geht das mit return(wert). Um eine Funktion aufzurufen, mußt du ihr alle Parameter mit geben, und nicht blos den Funktionsnamen hinschreiben.
Dann: Der Betrag einer Zahl kann mit abs(zahl) berechnet werden.
Ein Fehler liegt hier:
def dg(x,d):
return(g(x+d)-g(x-d))/2*d
Hier steht [mm] \frac{g(x+d)-g(x-d)}{2}*d, [/mm] du willst aber [mm] \frac{g(x+d)-g(x-d)}{2d} [/mm] , und das geht so:
def dg(x,d):
return(g(x+d)-g(x-d))/(2*d)
Ich hab mal aufgeräumt:
1: | # -*- coding: utf-8 -*-
| 2: |
| 3: | def g(x):
| 4: | return(x*x)
| 5: |
| 6: |
| 7: | def dg(x,d):
| 8: | return(g(x+d)-g(x-d))/(2*d)
| 9: |
| 10: |
| 11: | def newton(x, d, maxError, maxN):
| 12: | c=0
| 13: | while(1):
| 14: | c=c+1
| 15: | print "Iteration ",c
| 16: | ableitung=dg(x, d)
| 17: | funktionswert=g(x)
| 18: |
| 19: | print " x=",x
| 20: | print " f(x)= ",funktionswert
| 21: | print " f'(x)=", ableitung
| 22: |
| 23: | xneu=x - funktionswert / ableitung
| 24: | print " xneu=", xneu
| 25: | print "xneu-x=", xneu-x
| 26: |
| 27: | if(abs(xneu-x)<maxError):
| 28: | print "Gewünschte Genauigkeit erreicht!"
| 29: | return(xneu)
| 30: | if(c==maxN):
| 31: | print "Maximale Iterationszahl erreicht!"
| 32: | return(xneu)
| 33: |
| 34: | print "" #leerzeile
| 35: | x=xneu
| 36: |
| 37: |
| 38: |
| 39: | d=float(raw_input("Schrittweite für Ableitung eingeben: "))
| 40: | x0=float(raw_input("Startwert eingeben: "))
| 41: | maxerror=float(raw_input("Geben Sie die gewünschte Genauigkeit an "))
| 42: | maxIter=float(raw_input("Geben Sie die maximale Anzahl an Schritten an "))
| 43: |
| 44: | #Weil Funktion newton auch Bildschirmausgaben macht, lieber einfacher
| 45: | #print "newton(%x0,%maxerror)="%(x0,maxerror), x_n1(x0, x_n2, g, dg)
| 46: |
| 47: | nullstelle=newton(x0, d, maxerror, maxIter)
| 48: |
| 49: |
| 50: | print "Ergebnis: Nullstelle bei ",nullstelle |
Den Code habe ich hier auch mal als Datei angehängt.
und das funktioniert gut:
1: | Schrittweite für Ableitung eingeben: 0.1
| 2: | Startwert eingeben: 4
| 3: | Geben Sie die gewünschte Genauigkeit an 0.01
| 4: | Geben Sie die maximale Anzahl an Schritten an 100
| 5: | Iteration 1
| 6: | x= 4.0
| 7: | f(x)= 16.0
| 8: | f'(x)= 8.0
| 9: | xneu= 2.0
| 10: | xneu-x= -2.0
| 11: |
| 12: | Iteration 2
| 13: | x= 2.0
| 14: | f(x)= 4.0
| 15: | f'(x)= 4.0
| 16: | xneu= 1.0
| 17: | xneu-x= -1.0
| 18: |
| 19: | Iteration 3
| 20: | x= 1.0
| 21: | f(x)= 1.0
| 22: | f'(x)= 2.0
| 23: | xneu= 0.5
| 24: | xneu-x= -0.5
| 25: |
| 26: | Iteration 4
| 27: | x= 0.5
| 28: | f(x)= 0.25
| 29: | f'(x)= 1.0
| 30: | xneu= 0.25
| 31: | xneu-x= -0.25
| 32: |
| 33: | Iteration 5
| 34: | x= 0.25
| 35: | f(x)= 0.0625
| 36: | f'(x)= 0.5
| 37: | xneu= 0.125
| 38: | xneu-x= -0.125
| 39: |
| 40: | Iteration 6
| 41: | x= 0.125
| 42: | f(x)= 0.015625
| 43: | f'(x)= 0.25
| 44: | xneu= 0.0625
| 45: | xneu-x= -0.0625
| 46: |
| 47: | Iteration 7
| 48: | x= 0.0625
| 49: | f(x)= 0.00390625
| 50: | f'(x)= 0.125
| 51: | xneu= 0.03125
| 52: | xneu-x= -0.03125
| 53: |
| 54: | Iteration 8
| 55: | x= 0.03125
| 56: | f(x)= 0.0009765625
| 57: | f'(x)= 0.0625
| 58: | xneu= 0.015625
| 59: | xneu-x= -0.015625
| 60: |
| 61: | Iteration 9
| 62: | x= 0.015625
| 63: | f(x)= 0.000244140625
| 64: | f'(x)= 0.03125
| 65: | xneu= 0.0078125
| 66: | xneu-x= -0.0078125
| 67: | Gewünschte Genauigkeit erreicht!
| 68: | Ergebnis: Nullstelle bei 0.0078125 |
Dateianhänge: Anhang Nr. 1 (Typ: py) [nicht öffentlich]
|
|
|
|
|
Status: |
(Frage) beantwortet | Datum: | 13:05 Mo 27.12.2010 | Autor: | jumape |
Aufgabe | Vielen vielen Dank. Das funktioniert ja super. |
Beim durchlesen habe ich auch alles verstanden bis auf
13: while(1):
Was bedeutet das?
Sorgt es dafür, dass das Programm nach der Ausgabe von max. Iterationszahl oder gewünschte Geauigkeit erreicht abbricht?
bzw. weiter macht solange dies nicht erericht ist.
Ich hätte gedacht man muss da schreiben:
while(abs(xneu-x)>maxError):
while(c<maxN):
geht das immer mit der 1?
|
|
|
|
|
Hallo!
Ich wollte in meinem Code noch eine Meldung ausgeben, welche der beiden Abbruchbedingungen eingetreten ist.
Normalerweise kann man die Schleife mit einem 'break' sofort verlassen, es wird dann der Code nach der Schleife ausgeführt.
Hier soll ja der Wert xneu zurückgegeben werden, daher habe ich das 'return(xneu)' benutzt. Denn damit wird die gesamte Funktion sofort verlassen, also auch die Schleife. (Denkbar wäre auch, gleich das ganze Programm mit 'sys.exit()' zu beenden.)
Generell kannst du das in jeder for- oder while-Schleife machen, um sie vorzeitig abzubrechen.
Mit dem 'while(1)' habe ich allerdings eine Endlosschleife geschaffen, die dann natürlich zwingend irgendwann durch das return oder ein break beendet werden muß.
Natürlich kannst du eine Abbruchbedingung auch in das while rein schreiben, dann würde ich allerdings eine do-while-Konstruktion nehmen. Um dann aber sagen zu können, ob die max. Anzahl der Iterationen erreicht wurde, oder ob die Genauigkeit erreicht wurde, müßtest du noch ein paar Zeilen extra schreiben. Da finde ich es so übersichtlicher.
|
|
|
|
|
Status: |
(Frage) beantwortet | Datum: | 11:52 Di 28.12.2010 | Autor: | jumape |
Aufgabe | Verstehe, vielen Dank.
Ich habe da noch eine Frage:
Bei der Arbeit mit Python tritt bei mir nach einiger Zeit immer ein sogenannter Socket error auf. Angeblich verweigert der zielcomputer die Vebindung. Aber das ist doch mein Computer und wenn ich ihn neu starte funktioniert es auch immer erstmal. |
habe ich mir irgendwie einen virus eingefangen oder so?
Vielen Dank
jumape
|
|
|
|
|
Hallo!
Hmh, das ist schwer zu sagen, was das sein könnte. Vielleicht gibst du mal die Fehlermeldung vollständig an?
Das mit den Sockets ist nicht ungewöhnlich. Viele Programme bestehen aus mehreren Komponenten, die miteinander kommunizieren (müssen). Das macht man z.B., wenn ein Programm mit Administratorrechten laufen muß, ein normaler Benutzer aber mit seinen eingeschränkten Rechten auf die Funktionen des Programms zugreifen muß. Die Bedienoberfläche kann sich dann übers Netzwerk mit dem eigentlichen Programm verbinden. Die Daten bleiben allerdings jederzeit auf dem PC, sie laufen über eine spezielle virtuelle Netzwerkkarte, das loopback-Interface.
Was da nun bei dir aber schief geht, ist schwer zu sagen.
|
|
|
|
|
Status: |
(Frage) überfällig | Datum: | 12:35 Mi 29.12.2010 | Autor: | jumape |
Aufgabe | Subprocess starting error |
IDLE's subprocess didn't make connection. Either IDLE can't start a subprocess or personal firewall software is blocking the connection.
IDLE Subprocess Error
Es konnte keine Verbindung hergestellt werden, da der Zielcomputer die VErbindung verweigert.
Zunächst funktioniert es einfach nicht mehr. Wenn ich ein Programm laufen lassen will erscheint in der GUI ein Restart aber die Eingabefrage erscheint nicht. Ich habe das dann auch mit Programmen ausprobiert von denen ich wusste dass sie funktionieren, weil sie vorher schon funktioniert haben und ich nichts daran geändert habe. Wenn ich dann die GUI neu öffne erscheint der obige Subprocess starting error.
Muss ich Python vielleicht einfach neu installieren?
viele Grüße
jumape
|
|
|
|
|
Status: |
(Mitteilung) Reaktion unnötig | Datum: | 13:20 Sa 29.01.2011 | Autor: | matux |
$MATUXTEXT(ueberfaellige_frage)
|
|
|
|
|
Status: |
(Frage) beantwortet | Datum: | 14:12 Di 19.07.2011 | Autor: | jumape |
Aufgabe | Noch eine Frage zu Newton: Ich möchte das Verfahren verallgemeinern, also nicht nur für x*x, sondern dass es mich nach der Funktion fragt.
Jetzt habe ich da ein bischen ausprobiert, bin aber auf keinen grünen Zweig gekommen. Beim nochmal nachdenken ist mir aufgefallen, dass man Funktionen ja definieren muss. Daher lautet meine Frage ob das überhaupt geht. |
Meine Ansätze waren:
def g(x) :
return ( raw_input ("Funktion eingeben:"))
(hier soll die Funktion über eien Eingabe definiert werden, das klappt aber nicht)
f= raw_input ("Funktion eingeben:")
def g (f):
return lambda x: eval (f)
#konvertiert String in eine Funktion
(hier gebe ich die Funktion erst als string ein und lasse sie dann konvertieren, klappt genauso wenig, wäre aber der ansatz der mir lieber wäre, da man es dann eher in mehrere Dimensionen übertragen kann)
Vielleicht kann mir jemand helfen.
|
|
|
|
|
Hallo!
> Meine Ansätze waren:
>
> def g(x) :
> return ( raw_input ("Funktion eingeben:"))
>
> (hier soll die Funktion über eien Eingabe definiert
> werden, das klappt aber nicht)
Naja, du fragst damit quasi einen String ab, der wird von deiner Funktion zurück gegeben.
>
> f= raw_input ("Funktion eingeben:")
> def g (f):
> return lambda x: eval (f)
> #konvertiert String in eine Funktion
>
> (hier gebe ich die Funktion erst als string ein und lasse
> sie dann konvertieren, klappt genauso wenig, wäre aber der
> ansatz der mir lieber wäre, da man es dann eher in mehrere
> Dimensionen übertragen kann)
Was gebau soll denn "return lambda x: eval (f)" sein? Außerdem sollte deine Funktion g dann ja zwei Parameter fressen: Einmal das x, und dann den String, in dem die eingegebene Funktion steht. Also so:
def f(x, func):
return eval(func) # im String func wird x automatisch durch den Wert der Variablen x ersetzt
myFunc=raw_input("Funktion eingeben:")
for i in range(1,11):
print f(i, myFunc)
Nachteilig ist, daß das eval jedes mal diesen String parsen muß, also die Funktion darin erkennen muß. Das macht die Sache relativ langsam, das wirst du merken, wenn die Anzahl der Schritte beim Newton-Verfahren hoch ist.
|
|
|
|
|
Status: |
(Frage) beantwortet | Datum: | 13:12 Mi 20.07.2011 | Autor: | jumape |
Aufgabe | Danke,
das klappt bei mir auch.
Du sagst das das Programm dann sehr lange braucht. Gibt es denn eine bessere Möglichkeit eine Funktion abzufragen? |
Ich dachte es müsste sowas wie float(raw_inpu(...)) auch für Funktionen geben, habe es aber leider ncht gefunden. Gibt es das?
|
|
|
|
|
Hallo!
Das Problem ist, daß das eval() bei jedem Aufruf erneut guckt, was da für ein String ist, und versucht, den als Formel zu interpretieren, und dieses Interpretieren kostet Zeit. Eine direkt im Quellcode vorhandene Formel wird dagegen von Anfang an in für den Rechner verständliche Arbeitsanweisungen umgesetzt, die der Rechner sehr schnell bearbeiten kann.
Abhilfe würde es hier schaffen, die Formel im Vorfeld in eine Liste von Arbeitsanweisungen umzuwandeln, aber das ist alles andere als einfach.
Außerdem fällt mir grade auf, daß du ja eh Python verwendest. Python selbst ist auch nur eine Scriptsprache, die nicht in ein echtes Computerprogramm kompiliert wird. Daher spielt das für dich vermutlich keine all zu große Rolle, wenn überhaupt.
Zu deinem
float(raw_input(...))
Ich weiß nicht so recht, was du meinst. Im Endeffekt meinst du doch grade
eval(raw_input(...))
Nur, wenn dein Newtonverfahren 100 schritte macht, mußt du dann auch eben 100 mal ein und die selbe Formel eingeben. Deshalb sollte die Formel erstmal in einem String landen.
|
|
|
|
|
Status: |
(Frage) beantwortet | Datum: | 13:55 Do 21.07.2011 | Autor: | jumape |
Aufgabe | danke,
jetzt habe ich das problem, dass ich die funktion im weiteren noch verwenden will. wie macht man das denn jetzt? |
Ich habe einfach überall, wo ich g verwende func in die variablen mit reingeschrieben. das sieht dann so aus:
def g (x,func):
return eval (func)
def dg(g, x, d, func):
return(g(x+d, func)-g(x-d, func))/(2*d)
def newton(g, func, x, d, maxError, maxN):
c=0
ableitung=dg(g,x,d,func)
funktionswert=g(x,func)
xneu=x-funktionswert/ableitung
while (abs(xneu-x)>maxError & c!=maxN) :
c=c+1
print "Iteration",c
print" x=",x
print" f(x)=",funktionswert
print" f´(x)=", ableitung
print"xneu=", xneu
print"xneu-x=", xneu-x
if(abs(xneu-x)<maxError):
print "Gewünschte Genauigkeit erreicht!"
return(xneu)
if(c==maxN):
print "Maximale Iterationszahl erreicht!"
return (xneu)
print "" #leerzeile
x=xneu
return(xneu)
f=raw_input("Funktion eingeben:")
d=float(raw_input("Schrittweite für Ableitung eingeben: "))
x0=float(raw_input("Startwert eingeben: "))
maxerror=float(raw_input("Geben Sie die gewünschte Genauigkeit an: "))
maxn=float(raw_input("Geben Sie die maximale Anzahl an Schritten an: "))
nullstelle=newton(g, f, x0, d, maxerror, maxn)
print "Ergebnis: Nullstelle bei", nullstelle
Aber das klappt nicht. Muss ich mir das erst drucken lassen,oder vielleicht die Funktion neu benennen?
Ich habe die Datei auch noch mal hier angehängt.
nullstelle=newton(g, f, x0, d, maxerror, maxn)
Dateianhänge: Anhang Nr. 1 (Typ: py) [nicht öffentlich]
|
|
|
|
|
Hallo jumape,
> danke,
> jetzt habe ich das problem, dass ich die funktion im
> weiteren noch verwenden will. wie macht man das denn
> jetzt?
>
> Ich habe einfach überall, wo ich g verwende func in die
> variablen mit reingeschrieben. das sieht dann so aus:
>
>
> def g (x,func):
> return eval (func)
>
>
Hier müssen die Leerzeichen zwischen Funktionsname
und öffnender runder Klammer entfernt werden.
def g(x,func):
return eval(func)
> def dg(g, x, d, func):
> return(g(x+d, func)-g(x-d, func))/(2*d)
>
> def newton(g, func, x, d, maxError, maxN):
> c=0
> ableitung=dg(g,x,d,func)
> funktionswert=g(x,func)
> xneu=x-funktionswert/ableitung
Diese Berechnung ist auch in der while-Schleife durchzuführen.
>
> while (abs(xneu-x)>maxError & c!=maxN) :
Hier sind keine binären Operatoren (hier:&) zu verwenden.
Vielmehr sind die logischen Operatoren zu verwenden.
Die Schleifenbedingung muß
(abs(xneu-x)>maxError or c<maxN)
lauten.
> c=c+1
> print "Iteration",c
> print" x=",x
> print" f(x)=",funktionswert
> print" f´(x)=", ableitung
> print"xneu=", xneu
> print"xneu-x=", xneu-x
>
> if(abs(xneu-x)<maxError):
> print "Gewünschte Genauigkeit erreicht!"
> return(xneu)
> if(c==maxN):
> print "Maximale Iterationszahl erreicht!"
> return (xneu)
>
> print "" #leerzeile
> x=xneu
> return(xneu)
>
> f=raw_input("Funktion eingeben:")
> d=float(raw_input("Schrittweite für Ableitung eingeben:
> "))
> x0=float(raw_input("Startwert eingeben: "))
> maxerror=float(raw_input("Geben Sie die gewünschte
> Genauigkeit an: "))
> maxn=float(raw_input("Geben Sie die maximale Anzahl an
> Schritten an: "))
>
>
> nullstelle=newton(g, f, x0, d, maxerror, maxn)
>
> print "Ergebnis: Nullstelle bei", nullstelle
>
> Aber das klappt nicht. Muss ich mir das erst drucken
> lassen,oder vielleicht die Funktion neu benennen?
>
Nein.
Mit den angebrachten Korrekturen sollte das klappen.
> Ich habe die Datei auch noch mal hier
> angehängt.
> nullstelle=newton(g, f, x0, d, maxerror, maxn)
>
Gruss
MathePower
|
|
|
|
|
Status: |
(Mitteilung) Reaktion unnötig | Datum: | 12:07 Mi 27.07.2011 | Autor: | jumape |
Danke für die Antwort,
allerdings meldet sich in diesem Fall der Fehler, dass xneu schon verwendet wird, bevor es definiert ist, ich habe mir daher so folgendes ausgedacht
> def dg(g, x, d, func):
> return(g(x+d, func)-g(x-d, func))/(2*d)
>
> def newton(g, func, x, d, maxError, maxN):
> c=0
> ableitung=dg(g,x,d,func)
> funktionswert=g(x,func)
> xneu=x-funktionswert/ableitung
Diese Berechnung ist auch in der while-Schleife durchzuführen.
Meine Idee:
def newton(g, func, x, d, maxError, maxN):
c=0
while (c<1 or (abs(xneu-x)>maxError & c!=maxN)):
c=c+1
ableitung=dg(g,x,d,func)
funktionswert=g(x,func)
xneu=x-funktionswert/ableitung
print "Iteration",c
print" x=",x
print" f(x)=",funktionswert
print" f´(x)=", ableitung
print"xneu=", xneu
print"xneu-x=", xneu-x
allerdings konvertiert das programm den string scheinbar nicht, da es den fehler ausspuckt, dass es strings nich voneinander abziehen kann.
def g(x,func):
return eval(func)
#konvertiert String in eine Funktion
Das ist meine Konvertierungsfunktion nochmal verbessert.
Ich bin inzwischen aber auch wieder auf das eingeben der Funktion in den Quellcode umgesiegen, da die Änderung der Funktion ja nun auch kein großer kraftaufwand ist, und das ganze dann gut funktioniert.
Aber vielen Dank für all die Hilfe die ich hier erhalten habe.
|
|
|
|