Nasser
Nasser

Reputation: 13131

How to tell sympy to keep exact numbers as exact in integrate?

When I typed

>python
> from sympy import *
> x=symbols('x')
> integrate(1/4/sin(1/3*x),x)

The output was

0.375*log(cos(0.333333333333333*x) - 1) - 0.375*log(cos(0.333333333333333*x) + 1)

What should one do to tell sympy not to convert exact input to floating point? I know I could type the following instead

integrate(S('1/4')/sin(S('1/3')*x),x)

And now the result is

 3*log(cos(x/3) - 1)/8 - 3*log(cos(x/3) + 1)/8

But I'd like to get this result, without having to wrap each number with S('') as in the above.

Is there an option or module one needs to import for this?

Using

>conda list sympy
sympy                     1.0                      py36_0 

On linux.

Upvotes: 2

Views: 1111

Answers (2)

asmeurer
asmeurer

Reputation: 91500

One option is to use isympy -i as your interpreter. This will start an interactive SymPy session where integers are automatically wrapped using S, so that you don't need to worry about dividing integers. But note that this only works interactively. If you want to write code using SymPy in a file, it is recommend to wrap divided integers with S or use Rational.

By the way, you can usually avoid this issue by writing your expression in such a way that you don't have integer/integer. For instance, instead of 1/4/sin(1/3*x) you could write 1/(4*sin(x/3)) (or 1/sin(x/3)/4). You only really need to use S when you have a rational number by itself, like S(1)/2 + x.

Upvotes: 2

user6655984
user6655984

Reputation:

without having to wrap each number with S('')

This can be avoided by wrapping the entire expression in S(''):

integrate(S('1/4/sin(1/3*x)'), x)

tell sympy not to convert exact input to floating point

It's not SymPy who evaluates 1/3 as a floating point number; it's Python. In sin(1/3*x), the division 1/3 occurs on Python level before SymPy objects such as x get involved.


Aside: with a more mathematically natural way of expressing the same formula,

integrate(1/(4*sin(x/3)), x)

one does not need S() at all, since there is no division of scalars here. Indeed, 1/(4*sin(x/3)) parses as

Mul(Rational(1, 4), Pow(sin(Mul(Rational(1, 3), Symbol('x'))), Integer(-1)))

while 1/4/sin(1/3*x) parses as

Mul(Float('0.25', prec=15), Pow(sin(Mul(Float('0.33333333333333331', prec=15), Symbol('x'))), Integer(-1)))

Upvotes: 3

Related Questions