2016-01-17 3 views
5

Sto solo imparando come usare sympy e ho provato una semplice integrazione di una funzione sin. Quando l'argomento di sin() ha una fase di costante costante l'uscita del integrate() dà lo stesso valore di tutto ciò che è la fase: 0Sympy: integrated() output strano

from sympy import * 
w = 0.01 
phi = 0.3 
k1 = integrate(sin(w*x), (x, 0.0, 10.0)) 
k2 = integrate(sin(w*x + 0.13), (x, 0.0, 10.0)) 
k3 = integrate(sin(w*x + phi),(x, 0.0, 10.0)) 
k1, k2, k3 

(0.499583472197429, 0, 0) 

Qualcuno può spiegarmi perché?

+0

Come hai definito 'x'? –

+2

Posso riprodurlo per una varietà di 'w' e' phi', anche per gli integrali indefiniti. Ad esempio, 'integra (sin (0.7 * x + 0.1), x)' dà '0'. Sembra un bug per me! – TheBamf

+0

Sembra avere un sacco di bug integrali. (https://github.com/sympy/sympy/labels/integrals) Ancora si integra correttamente se 'w' è impostato come' symbol' – Lol4t0

risposta

0

Sembra un bug. Una soluzione soluzione potrebbe essere quella di ottenere un'espressione simbolica del primo integrale (che sembra funzionare bene), quindi valutare per ogni set di parametri nella parte superiore e limite inferiore e calcolare la differenza:

import sympy as sp 
x, w, phi = sp.symbols('x w phi') 

# integrate function symbolically 
func = sp.integrate(sp.sin(w * x + phi), x) 

# define your parameters 
para = [{'w': 0.01, 'phi': 0., 'lb': 0., 'ub': 10., 'res': 0.}, 
     {'w': 0.01, 'phi': 0.13, 'lb': 0., 'ub': 10., 'res': 0.}, 
     {'w': 0.01, 'phi': 0.3, 'lb': 0., 'ub': 10., 'res': 0.}] 

# evaluate your function for all parameters using the function subs 
for parai in para: 
    parai['res'] = func.subs({w: parai['w'], phi: parai['phi'], x: parai['ub']}) 
    -func.subs({w: parai['w'], phi: parai['phi'], x: parai['lb']}) 

Dopo questo , para sembra quindi come segue:

[{'lb': 0.0, 'phi': 0.0, 'res': 0.499583472197429, 'ub': 10.0, 'w': 0.01}, 
{'lb': 0.0, 'phi': 0.13, 'res': 1.78954987094131, 'ub': 10.0, 'w': 0.01}, 
{'lb': 0.0, 'phi': 0.3, 'res': 3.42754951227208, 'ub': 10.0, 'w': 0.01}] 

che sembra dare risultati ragionevoli per l'integrazione, che sono memorizzati in res

+0

Grazie per la soluzione, ho verificato che lo sviluppo delle espressioni in sin() e cos() simbolicamente e la valutazione alla fine funzionavano bene, ma sono rimasto davvero sorpreso da tale comportamento e non ho capito il motivo. – user1259970

+0

Ok, sì, capisco la confusione. Come dice asmeurer qui sotto, sembra accadere solo in Python 2 e il bug verrà corretto nella prossima versione. Grazie per aver segnalato questo bug; Uso sympy di volta in volta e ora sarà più attento. – Cleb

0

ho appena eseguito il codice nella versione di sviluppo di SymPy e ho ottenuto (0.499583472197429, 1.78954987094131, 3.42754951227208). Quindi sembra che il bug verrà corretto nella prossima versione.

Sembra che questo bug sia solo in Python 2. Quando uso Python 3, anche con l'ultima versione stabile (0.7.6.1) ottengo la stessa risposta.

+0

Grazie asmeuser. Non sono sicuro che sia un bug o meno perché ho controllato e verificato che sto usando Python 3.4.4 (su Anaconda 2.1.0) e la versione di sympy è 0.7.6.1 secondo init_session(). Ho provato il sistema interattivo "SymPy Live Shell" sul [sito Web SymPy] (http://docs.sympy.org/dev/tutorial/printing.html) e ancora una volta ho ottenuto lo stesso risultato: (0.499583472197429 , 0,0) – user1259970

+0

Puoi provare la versione sympy di GitHub? – asmeurer

+0

Sì, la versione di sympy di GitHub (SymPy 0.7.7.dev) risolve il problema. Grazie !! – user1259970

0

Posso consigliare l'utilizzo di numpy per l'integrazione numerica?

>>> import numpy as np 
>>> w = 0.01 
>>> phi = 0.3 
>>> dt = 0.01 
>>> t = 2*np.pi*np.arange(0,1,dt) 
>>> np.sum(np.sin(t)*dt) 
-1.0733601507606494e-17 
>>> np.sum(np.sin(t+ phi)*dt) 
2.5153490401663703e-17 

Questi numeri sono praticamente vicino a 0. Il numero esatto è un artefatto della nostra scelta di maglia dt ed innestare phi (così come la precisione dei np.sin)

di essere più coerente con il tuo esempio :

>>> t = np.arange(0,10,dt) 
>>> w = 0.01 
>>> phi = 0.3 
>>> np.sum(np.sin(w*t)*dt) 
0.4990843046978698 
>>> np.sum(np.sin(w*t + phi)*dt) 
3.4270800187375658 
>>> np.sum(np.sin(w*t + 0.13)*dt) 
1.7890581525454512 

Come citato in Integrating in Python using Sympyè una cattiva idea quella di utilizzare una libreria simbolico per il lavoro numerica

+0

Grazie, hai ragione, non è mia intenzione usare sympy per risolvere problemi numerici solo per imparare come usare sympy e l'esempio è così innocente che sono davvero sorpreso. – user1259970