Skript hängt an willkürlicher Stelle! Threadproblem?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

gurke111 hat geschrieben:`drei` wurde aber auf zwei verschiedene Weisen versucht zu ändern:

Code: Alles auswählen

    drei.append(3)
    drei = [4, 5, 6]
Die erste der beiden Zeilen hat offenbar Wirkung gehabt "nach außen", die zweite nicht. Dann hängt es also auch noch von der Art der Veränderung ab, ob ein Objekt mutable oder immutable ist?
Deswegen habe ich auch die zwei Arten aufgeführt. Bei der ersten wird das Objekt verändert (wenn du `id(drei)` davor und danach aufrufst, wirst du sehen dass das das gleiche Objekt ist -> gleiche ID). Bei der zweiten wird an drei ein *neues* Objekt gebunden, d.h. das Objekt was vorher an drei gebunden war, wird gar nicht geändert. Nun ist also im Funktions-Scope drei an ein neues Objekt gebunden. Außerhalb der Funktion hat aber `drei` noch das alte Objekt.

Heißt also: `=` ändert keine Objekte. Nie. Die Objektmethoden ändern Objekte, aber auch nicht immer (bei immutablen Objekten ändern die Objekte sich nach der Erstellung nie, siehe `vier`).
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
BlackJack

@gurke111: Meine Aufteilung bzw. Zusammenfassung auf die beiden Funktionen bringt einen kleinen Geschwindigkeitsvorteil, wahrscheinlich hauptsächlich weil Funktionsaufrufe gespart werden. Deine Originalfunktionen ohne GUI haben hier 1 Minute 35 Sekunden ohne Psyco und 17 Sekunden mit Psyco gebraucht.

Die Neuaufteilung war schnell gemacht, ich habe einfach alle Formeln eingesetzt und dann war das neue `f()` ein offensichtlicher Teil, den man als eigene Funktion dort herausziehen konnte. So sieht das "Gesamtkunstwerk" aus:

Code: Alles auswählen

               /           2    /     |     3 |     \   \             /   2    /     |     5 |     \       \
              |       5 * H  * |  E - | n - - | * H  |   |           |   H  * |  E - | n - - | * H  |       |
              |                 \     |     2 |     /    |           |         \     |     2 |     /        |
  2 * PSI   * |  1 - ----------------------------------  | - PSI   * |  ------------------------------ + 1  |
         -1    \                     6                  /       -2    \               6                    /
 -------------------------------------------------------------------------------------------------------------
                                        2    /     |     1 |     \
                                       H  * |  E - | n - - | * H  |
                                             \     |     2 |     /
                                      ------------------------------ + 1
                                                    6
Du kannst `psyco` so benutzen:

Code: Alles auswählen

try:
    import psyco
    psyco.full()
except ImportError:
    pass
Wenn das Modul nicht importiert werden kann, läuft das Programm halt ohne "Turbo". :-)
gurke111
User
Beiträge: 28
Registriert: Freitag 26. Oktober 2007, 22:55

BlackJack hat geschrieben: Die Einrückung ist jetzt wenigstens konsequent "falsch". ;-)

Da wollte ich nochmal nachfragen.. Sollte ich Deiner Meinung nach lieber 4-spaces Einrückung haben? Ich habe mir jetzt gerade vor kurzem die 2-spaces angewöhnt, weil es bei arg verschachtelten Schleifen/Abfragen sonst schnell richtig richtig abgeht... naja :)

Womit hast Du die Formel so ascii-Bild-mäßig formatiert? Das ist ne coole Sache :>
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

gurke111 hat geschrieben:
BlackJack hat geschrieben: Die Einrückung ist jetzt wenigstens konsequent "falsch". ;-)

Da wollte ich nochmal nachfragen.. Sollte ich Deiner Meinung nach lieber 4-spaces Einrückung haben?
PEP 8 sagt 4 Spaces.
gurke111 hat geschrieben: Womit hast Du die Formel so ascii-Bild-mäßig formatiert? Das ist ne coole Sache :>
aamath, pretty printer, gibt bestimmt noch massig andere..
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Trundle hat geschrieben:
gurke111 hat geschrieben: Womit hast Du die Formel so ascii-Bild-mäßig formatiert? Das ist ne coole Sache :>
aamath, pretty printer, gibt bestimmt noch massig andere..
Vielleicht hat BlackJack ja auch Maxima benutzt.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
BlackJack

@gurke111: Wenn die Einrückungen zu tief werden, ist das für gewöhnlich ein Zeichen dafür, dass man die Funktion in mehrere Funktionen aufteilen sollte.

Die Formel ist mit Jave gesetzt. Ich hätte auch die Ausgabe von Maxima nehmen können, aber da muss man bei wxMaxima erst auf Textdarstellung umschalten und die gefällt mir nicht so gut wie die von Jave.

Edit: Hab nur mal so aus Neugier noch eine Pyrex-Variante ausprobiert:

Code: Alles auswählen

cdef extern from "math.h":
    double fabs(double x)


cdef double f(double a, double n, double E, double H):
    return (H * H * (E - fabs(n - a) * H)) / 6.0;


def NumerovUpdate(double E, object PSI, double H):
    cdef int n
    cdef double newPsi, p1, p2
    n = len(PSI)
    p1 = PSI[-1]
    p2 = PSI[-2]
    newPsi = ((2 * p1 * (1 - 5 * f(1.5, n, E, H))
               - p2 * (f(2.5, n, E, H) + 1))
              / (f(0.5, n, E, H) + 1))
    PSI.append(newPsi)
    return newPsi
Die liegt mit 19 Sekunden Laufzeit zwischen Psyco und reinem Python. Interessant, dass Psyco hier besser ist.
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Leonidas hat geschrieben: Vielleicht hat BlackJack ja auch Maxima benutzt.
Oder Maple, oder Mathematica, ... so ziemlich jedes größere CAS hat einen Textkonsolenmodus.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
BlackJack

Mir ist aufgefallen, das die Liste PSI eigentlich gar nicht benutzt wird, bzw. immer nur die letzten beiden Elemente. Dazu braucht man dann aber keine Liste, sondern nur zwei Namen für die beiden Elemente:

Code: Alles auswählen

def f(a, n, E, H):
    return (H * H * (E - abs(n - a) * H)) / 6.0;


def NumerovUpdate(E, n, psi_1, psi_2, H):
  newPsi = ((2 * psi_1 * (1 - 5 * f(1.5, n, E, H))
             - psi_2 * (f(2.5, n, E, H) + 1))
            / (f(0.5, n, E, H) + 1))
  return newPsi


def NumerovInt(sgn, E):
    if sgn == 1:
        psi_2, psi_1 = 0, 1
    else:
        psi_2, psi_1 = -H, H
    for n in xrange(2, int(N) + 2):
        psi_2, psi_1 = psi_1, NumerovUpdate(E, n, psi_1, psi_2, H)
#         if abs(psi_1) < PSICUT and n % 200 == 0:
#             window.Point((n * BREITE / N), psi_1, 2)
        if abs(psi_1) > PSIMAX:
            logit ("... abgebrochen (PSIMAX ueberschritten)")
            return psi_1 > 0
`psi_1` ist das jeweils letzte berechnete psi und `psi_2` das Vorletzte.

Mit den beiden ersten Funktionen in Pyrex ist die Laufzeit auf 13 Sekunden runter, mit Pyrex + Psyco sogar auf 6 Sekunden! Hier der Pyrex-Code:

Code: Alles auswählen

cdef extern from "math.h":
    double fabs(double x)


cdef double f(double a, int n, double E, double H):
    return (H * H * (E - fabs(n - a) * H)) / 6.0;


def NumerovUpdate(double E, int n, double psi_1, double psi_2, double H):
    newPsi = ((2 * psi_1 * (1 - 5 * f(1.5, n, E, H))
               - psi_2 * (f(2.5, n, E, H) + 1))
              / (f(0.5, n, E, H) + 1))
    return newPsi
BlackJack

Hm, mir fiel eben auf, dass `n` nie kleiner als 2 ist, also ist nur eines der drei `abs()` nötig. Das führt dann letztendlich zu folgender "Gesamtfunktion":

Code: Alles auswählen

  //           3        2     \        /             3         2     \     \
- |\|2 n - 5| H  - 2 E H  - 12/ psi  + \(20 n - 30) H  - 20 E H  + 24/ psi |
  \                                2                                      1/
----------------------------------------------------------------------------
                                    3        2
                         (2 n - 1) H  - 2 E H  - 12
Oder in Code:

Code: Alles auswählen

cdef extern from "math.h":
    double fabs(double x)

def NumerovUpdate(double E, int n, double psi_1, double psi_2, double H):
    return (-((fabs(2*n-5)*H*H*H-2*E*H*H-12)*psi_2
              +((20*n-30)*H*H*H-20*E*H*H+24)*psi_1)
            / ((2*n-1)*H*H*H-2*E*H*H-12))
Nochmal fast eine halbe Sekunde gespart. So, nun höre ich aber auf. :-D
gurke111
User
Beiträge: 28
Registriert: Freitag 26. Oktober 2007, 22:55

Du bist ein Freak, dankeschön :-)

Habe die Sache aber schon am Sonntag "abgegeben" :)
Also kann ich Deine extravaganten Vorschläge nicht mehr verarbeiten. Werd sie aber als Anregung definitiv im Gedächtnis behalten. Und dem Forum nach meinem Debut hier bestimmt auch treu bleiben. Super Leute!
Antworten