user1259970
user1259970

Reputation: 343

Sympy: integrate() strange output

I'm just learning how to use sympy and I have tried a simple integration of a sin function. When the argument of sin() has a constant phase constant the output of integrate() gives the same value whatever is the phase: 0

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)

Can somebody explain me why ?

Upvotes: 6

Views: 916

Answers (3)

john mangual
john mangual

Reputation: 8172

Can I recommend using numpy for numerical integration?

>>> 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

These numbers are basically close to 0. The exact number is an artifact of our choice of mesh dt and shift phi (as well as the accuracy of np.sin)

To be more consistent with your example:

>>> 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

As quoted in Integrating in Python using Sympy it's a bad idea to use a symbolic library for numerical work

Upvotes: 0

asmeurer
asmeurer

Reputation: 91660

I just ran your code in the development version of SymPy and I got (0.499583472197429, 1.78954987094131, 3.42754951227208). So it seems the bug will be fixed in the next version.

It also looks like this bug is in Python 2 only. When I use Python 3, even with the latest stable version (0.7.6.1) I get the same answer.

Upvotes: 0

Cleb
Cleb

Reputation: 26039

That seems to be a bug. A workaround solution could be to get a symbolic expression of your integral first (which seems to work fine), then evaluate it for each set of parameters at the upper and lower bound and calculate the difference:

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']})

After this, para looks then as follows:

[{'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}]

which seems to give reasonable results for the integration which are stored in res

Upvotes: 1

Related Questions