2017-01-24 4 views
1

Der Code ist ziemlich selbsterklärend:Warum kann ich eine Zusammenstellung von implementierten_Funktionen in SymPy nicht zu einem bestimmten Zeitpunkt auswerten?

>>> from sympy.utilities.lambdify import implemented_function 
>>> f = implemented_function('f', lambda x: x ** 2) 
>>> g = implemented_function('g', lambda x: 2 * x) 
>>> print(f( 2).evalf()) 
4.00000000000000 
>>> print( g(2) .evalf()) 
4.00000000000000 
>>> print(f(g(2)).evalf()) 
f(g(2)) 

Diese mich verrückt fährt. Warum wird der Ausdruck nicht ausgewertet und wie soll ich ihn beheben?

+0

Sie könnten 'lambdify' verwenden:' x = sympy.symbols ('x') '; 'sympy.lambdify (x, f (g (x))) (2)' ergibt 16. – unutbu

+0

@unutbu: Wird damit der Punkt der Verwendung von 'implementierte_funktion' nicht besiegt? Wenn ich mich auf einen generischen symbolischen Ausdruck verlassen könnte, würde ich ihn einfach normal manipulieren und eine Substitution vornehmen, anstatt "implementierte_funktion" zu durchlaufen. – Mehrdad

+0

Haben Sie versucht, 'f (g (2) .evalf()). Evalf()' oder 'f (g (2) .evalf())'? vielleicht ist es nicht das, wonach du gesucht hast. – pazitos10

Antwort

2

Ich würde dies als einen Fehler in SymPy betrachten. evalf ruft _imp_ rekursiv nicht auf. Ich habe an issue geöffnet.

In Bezug auf _imp_ vs. eval, das docstring von implemented_functionsays:

Beachten Sie, dass dies eine schnelle Abhilfe, nicht eine allgemeine Methode besondere symbolische Funktionen zu erstellen. Wenn Sie eine symbolische Funktion erstellen möchten, die von allen Maschinen von SymPy verwendet werden soll, sollten Sie die Function-Klasse ableiten.

Der Hauptzweck ist in _imp_ lambdify verwendet werden soll, eine numerische Umsetzung auf eine symbolische Funktion zu befestigen.

Wenn Sie daran interessiert ist nur in symbolischer Auswertung sind, oder Auswertung mit evalf, sollten Sie Function Unterklasse und eval oder _eval_evalf (jeweils) definieren.

+0

+1 Ahh, ich wusste nicht, dass es explizit für die numerische Auswertung gedacht war! Das erklärt einige Dinge. Okay, so eine Art Tangente, aber wenn ich es so mache, dann muss ich noch 'fdiff' überschreiben, um es differenzierbar zu machen, oder? Oder wird es automatisch den symbolischen Ausdruck unterscheiden, den ich zurückgebe?(obwohl ich denke, ich könnte es einfach tun und sehen) – Mehrdad

+0

Wenn Sie einen Ausdruck von 'eval' zurückgeben, wird dies sofort ausgewertet. So wird diff auf den Ausdruck ausgewertet, der zurückgegeben wird. Wenn Sie es unbewertet bleiben lassen (geben Sie 'None' von' eval' zurück), müssen Sie die Ableitung definieren. – asmeurer

+0

Klingt gut, danke !! Das macht mein Leben leichter in den Fällen, in denen ich einen Ausdruck habe, zurückzukehren. Vielen Dank! – Mehrdad

1

Ich kann Ihre Frage nicht direkt beantworten, und ich weiß nicht, was Ihr Gesamtziel ist. Aber ist dieser Ansatz von Nutzen?

>>> from sympy import * 
>>> class square(Function): 
...  @classmethod 
...  def eval(cls, x): 
...   if x.is_integer or x.is_real: 
...    return x**2 
... 
>>> class double(Function): 
...  @classmethod 
...  def eval(cls, x): 
...   if not x.is_integer or x.is_real: 
...    return 2*x 
... 
>>> double(square(3)) 
18 
>>> var('x') 
x 
>>> double(square(x)).subs(x,5) 
50 
+0

Ich habe keine Ahnung, was die Auswirkungen dieser Methode sind (Ich wusste nicht, 'Eval' existiert sogar). Wie unterscheidet sich das von '_imp_' oder' implementierter_funktion'? Ist das normal oder ist es ein Hack? – Mehrdad

+0

Definitiv kein Hack. AS Meurer hat es in einem seiner Antworten vor ein paar Tagen erwähnt. Ich habe keine Ahnung, wie es sich von den Codes unterscheidet, die Sie erwähnen. Ich stelle mir vor, das ist die Anordnung, um Sympy willkürliche Funktionen hinzuzufügen. –

+0

AAMOF siehe http://docs.sympy.org/latest/modules/functions/index.html. –

Verwandte Themen