Seite 1 von 1

Problem mit der Fehlerfortpflanzung

Verfasst: Freitag 31. Oktober 2014, 19:47
von Hummelchen
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:

Re: Problem mit der Fehlerfortpflanzung

Verfasst: Freitag 31. Oktober 2014, 20:02
von 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?

Re: Problem mit der Fehlerfortpflanzung

Verfasst: Freitag 31. Oktober 2014, 20:18
von Hummelchen
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 :?

Re: Problem mit der Fehlerfortpflanzung

Verfasst: Freitag 31. Oktober 2014, 20:40
von 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.

Re: Problem mit der Fehlerfortpflanzung

Verfasst: Freitag 31. Oktober 2014, 20:41
von EyDu
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

Re: Problem mit der Fehlerfortpflanzung

Verfasst: Samstag 1. November 2014, 12:15
von Hummelchen
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}))

Re: Problem mit der Fehlerfortpflanzung

Verfasst: Samstag 1. November 2014, 13:02
von 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.