Problem mit der Fehlerfortpflanzung

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.
Antworten
Hummelchen
User
Beiträge: 3
Registriert: Freitag 31. Oktober 2014, 19:38

Hallo an alle,

ich bin neu in diesem Forum und ich hoffe man darf hier einfach so fragen (ich hoffe meine Frage wurde nicht schonmal gestellt, ich habe auf jeden Fall nichts gefunden :) )

mit der Gaußen Fehlerfortplanzung möchte ich den Fehler der Funktion w bestimmen. meine Eingabe sieht so aus:

Code: Alles auswählen

import numpy as np
from sympy import Symbol, diff

a=Symbol('a')
A=Symbol('A')
b=Symbol('b')
B=Symbol('B')
c=Symbol('c')
d=Symbol('d')
D=Symbol('D')
e=Symbol('e')
E=Symbol('E')
f=Symbol('f')
F=Symbol('F')
g=Symbol('g')
G=Symbol('G')

a=0.5122
A=0.00020488
b=0.05076
B=0.0034424
c=0.000225
d=0.00487
D=0.0002024
e=0.554
E=0.0002024
f=18.4753
F=0.00029
e=0.0001993
E=0.00000137877

w=(128 * np.pi * (0.1 * a * b**2 + c)*(d+e))/(f**2 * g**4)

v=(( ((w.diff(a))*A)**2+((w.diff(b))*B)**2+((w.diff(d))*D)**2+((w.diff(e))*E)**2+((w.diff(f))*F)**2+((w.diff(g))*G)**2)**(1/2))

print(v)
leider wird mir ein kryptische Fehler ausgegeben. (ich hätte gerne einfach eine Zahl als Ergebnis)
da ich aber ein blutiger Anfänger bin, kann ich damit leider nicht viel anfangen :?

Danke schonmal für eure Hilfe :wink:
Zuletzt geändert von Anonymous am Freitag 31. Oktober 2014, 19:51, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Code-Tags gesetzt.
BlackJack

@Hummelchen: Fehlermeldungen am besten auch verraten, damit wir nicht raten müssen. Es ist also wahrscheinlich diese hier:

Code: Alles auswählen

Traceback (most recent call last):
  File "forum5.py", line 35, in <module>
    v=(( ((w.diff(a))*A)**2+((w.diff(b))*B)**2+((w.diff(d))*D)**2+((w.diff(e))*E)**2+((w.diff(f))*F)**2+((w.diff(g))*G)**2)**(1/2))
  File "/usr/lib/python2.7/dist-packages/sympy/core/expr.py", line 1834, in diff
    return Derivative(self, *new_symbols, **assumptions)
  File "/usr/lib/python2.7/dist-packages/sympy/core/function.py", line 658, in __new__
    raise ValueError('Derivative expects Symbol [, Integer] args but got %s, %s' % (s, count))
ValueError: Derivative expects Symbol [, Integer] args but got 0.512200000000000, 1
Und die ist relativ eindeutig. Die `diff()`-Methode möchte gerne ein `Symbol` und keine Gleitkommazahl als Argument haben. Man kann halt nicht nach einer konkreten Zahl ableiten sondern nur nach einer Variablen. Du bindest am Anfang einen Haufen Namen an `Symbol`-Objekte um dann gleich danach fast alle diese Namen an Gleitkommazahlen zu binden. Was soll das? Die ersten Zuweisungen an diese Namen sind damit vollkommen sinnlos. Das betrifft zum Beispiel auch `a`, was hier wenn man sich die Werte aus der Fehlermeldung ansieht, offenbar betroffen ist. Was hättest Du bei ``w.diff(0.5122)`` denn als Ergebnis erwartet?
Hummelchen
User
Beiträge: 3
Registriert: Freitag 31. Oktober 2014, 19:38

Danke erstmal :)
ok, das klingt sinnvoll! :idea:
das man nicht nach einer Zahl ableiten kann, ist mir auch eigentlich klar,
es fällt mir nur etwas schwer, das was aus ausgerechnet haben möchte in ein Programm umzuformen..

also wenn ich den Abschnitt mit den ganzen Zahlen rausnehme, bekomme ich keine Fehlermeldung, und den Ausdruck den ich eigentlich benötige, aber wie kann ich dann Zahlen für meine Variablen einsetzen?

liebe Grüße :)

achso: ich benutze git bash als Komandozeile und da kann man leider keine Fehlermeldungen oder sonstirgendwas rauskopieren :?
BlackJack

@Hummelchen: Du musst erst soweit symbolisch arbeiten bis Du die gewünschte Formel hast, und da kannst Du dann Deine Werte einsetzen. Wahrscheinlich möchtest Du so etwas hier machen:

Code: Alles auswählen

from __future__ import absolute_import, division, print_function
from sympy import Integer, pi as PI, pretty_print, symbols

a, b, c, d, e, f, g = symbols('a b c d e f g')
A, B, C, D, E, F, G = symbols('A B C D E F G')

ONE = Integer(1)

w = (128 * PI * (ONE / 10 * a * b**2 + c) * (d + e)) / (f**2 * g**4)
pretty_print(w)

v = (
      (w.diff(a) * A)**2
    + (w.diff(b) * B)**2
    + (w.diff(d) * D)**2
    + (w.diff(e) * E)**2
    + (w.diff(f) * F)**2
    + (w.diff(g) * G)**2
)**(ONE / 2)

values = {
    a: 0.5122,
    A: 0.00020488,
    b: 0.05076,
    B: 0.0034424,
    c: 0.000225,
    d: 0.00487,
    D: 0.0002024,
    e: 0.554,
    E: 0.0002024,
    f: 18.4753,
    F: 0.00029,
    e: 0.0001993,
    E: 0.00000137877,
}

print('-' * 75)
pretty_print(v.subs(values).evalf())
Ausgabe:

Code: Alles auswählen

              ⎛   2    ⎞
              ⎜a⋅b     ⎟
128⋅π⋅(d + e)⋅⎜──── + c⎟
              ⎝ 10     ⎠
────────────────────────
          2  4          
         f ⋅g           
---------------------------------------------------------------------------
                                                0.5
⎛                      2                       ⎞   
⎜7.27174605279189e-11⋅G    1.86731210104737e-14⎟   
⎜─────────────────────── + ────────────────────⎟   
⎜           10                       8         ⎟   
⎝          g                        g          ⎠
Eine konkrete Zahl kannst Du natürlich nicht bekommen solange nicht auch `g` und `G` durch konkrete Werte ersetzt werden.

Bist Du sicher das man aus dem Shell-Fenster nichts kopieren kann? Zum Beispiel über das Kontextmenü das man beim Fenstericon in der Fensterleiste bekommt? Falls das tatsächlich nicht geht, ist diese Shell IMHO ungeeignet um damit zu arbeiten.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Das Erstellen der Symbole geht viel einfacher:

Code: Alles auswählen

import sympy as sp
a, A, b, B = sp.symbols("a A b B")
Oder gleich:

Code: Alles auswählen

from sympy.abc import a, A, b, B
Und wegen der Berechnung:

Code: Alles auswählen

>>> f = a*b
>>> f.subs({a:42, b:23})
>>> f = a*b
>>> f.subs({a:42, b:23})
Oder ab auch:

Code: Alles auswählen

>>> f.evalf(subs={a:42, b:23})
966.000000000000
Das Leben ist wie ein Tennisball.
Hummelchen
User
Beiträge: 3
Registriert: Freitag 31. Oktober 2014, 19:38

Danke an euch, ich hab mir jetzt was zusammengebastelt, sodass es klappt ( ist vielleicht nicht am elegantesten, aber egal :) )
für den Fall, dass jemand das gleiche Problem hat, lade ich da mal hoch :)

Code: Alles auswählen

import numpy as np
from sympy import Symbol, diff

a=Symbol('a')
A=Symbol('A')
b=Symbol('b')
B=Symbol('B')
c=Symbol('c')
d=Symbol('d')
D=Symbol('D')
e=Symbol('e')
E=Symbol('E')
f=Symbol('f')
F=Symbol('F')
g=Symbol('g')
G=Symbol('G')



w=(128 * np.pi * (0.1 * a * b**2 + c)*(d+e))/(f**2 * g**4)


v=(( ((w.diff(a))*A)**2+((w.diff(b))*B)**2+((w.diff(d))*D)**2+((w.diff(e))*E)**2+((w.diff(f))*F)**2+((w.diff(g))*G)**2)**(0.5))


print(v.evalf(subs={a:0.5122, A:0.00020488, b:0.05076, B:0.0034424, c:0.000225, d:0.00487, D:0.0002024, e:0.554, E:0.0002024, f:18.4753, F:0.00029, g:0.0001993, G:0.00000137877}))
Zuletzt geändert von Anonymous am Samstag 1. November 2014, 12:46, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Code-Tags gesetzt.
BlackJack

@Hummelchen: Ich habe keine Ahnung was Du da inhaltlich machst, aber da dort etwas mit Fehlern steht, die ja durch die Ungenauigkeit von Gleitkommaoperationen zustande kommen, würde ich ja so lange es geht symbolisch arbeiten. Also nicht `np.pi` oder 0.1 in die Rechnung bringen. Dein `w` hier sieht ja schon ”ungenau” aus, verglichen mit dem `w` von meinem Beispiel weiter oben:

Code: Alles auswählen

        ⎛                    2                     ⎞
(d + e)·⎝40.2123859659494·a·b  + 402.123859659494·c⎠
────────────────────────────────────────────────────
                        2  4                        
                       f ·g
Kann natürlich sein, dass das für Deinen Fall keine Rolle spielt.

Edit: Die Differenz für die beiden Ergebnisse beträgt 0.00000095367431640625.
Antworten