I apologize if this has been asked already.
I am just learning about SymPy and I'm wondering why it won't spit out a correct answer for what seems to be a simple equation.
from sympy.solvers import solve
from sympy import Symbol, simplify
from sympy.abc import x, alpha, sigma
alpha = Symbol('alpha')
x = Symbol('x')
sigma = Symbol('sigma')
solve((alpha - 0.5*(sigma**2))*((alpha + 0.5*(sigma**2)))**(-1)+ (1/7),sigma**2, simplify = True)
It spits out [2.0* alpha], which I know is incorrect. In fact, the answer should be [2.6666*alpha] or something like that. I'm assuming that SymPy is for some reason converting the number 2.666 to an integer string.
How can I fix this problem? Also, is there any way I could get the fractional form of the solution?
You're probably using Python 2.7, so 1/7 is giving you integer division:
>>> 1/7
0
>>> 1./7
0.14285714285714285
>>> solve((alpha - 0.5*(sigma**2))*((alpha + 0.5*(sigma**2)))**(-1)+ (1/7),sigma**2, simplify = True)
[2.0*alpha]
>>> solve((alpha - 0.5*(sigma**2))*((alpha + 0.5*(sigma**2)))**(-1)+ (1./7),sigma**2, simplify = True)
[2.66666666666667*alpha]
If you want the fractional answer, maybe something like
>>> from sympy import Rational
>>> solve((alpha - (sigma**2)/2)*((alpha + (sigma**2)/2))**(-1)+ Rational(1,7),sigma**2, simplify = True)
[8*alpha/3]
You can also use help(solve) to read the docstring of solve that tells how to use the rational keyword:
>>> solve(x-.3)
[0.300000000000000]
>>> solve(x-.3, rational=True)
[3/10]
Related
Hello I have this sympy expression 0.5*c**2*m*(v/c)**2.0 and I want to bring it automatically to this form: 0.5*m*v**2. I tried the sympy simplify function but that doesn't seem to work. What can I do? Thank you!
These two expressions are not equivalent, only equivalent if c is not equal to 0. So if you want to get 0.5*m*v**2, you need set c as a positive number:``
>>> import sympy
>>> c= sympy.symbols('c',positive=True)
>>> m,v = sympy.symbols('m v')
>>> sympy.powsimp(0.5*c**2*m*(v/c)**2.0)
0.5*m*v**2.0
Besides, although sympy.simplify will give you what you want, I think sympy.powsimp is better. Because actually we want to reduce expression by combining powers with similar bases and exponents.
I'ld like my SymPy results to be displayed as precise results and not as decimal results. I looked through the SymPy documentation, but couldn't find anything helpful.
To illustrate the problem, here is some example code:
from sympy import *
u = symbols("u")
integrate((1+u)**(1/2), (u, 0, 1))
Output:
1.21895141649746
Expected result:
(4/3)*sqrt(2)-(2/3)
The problem is that SymPy will simplify expressions containing floats and so removes those symbolic expressions. Although the expression doesn't look like a float, the division 1/2 is done with standard Python, internally represented as 0.5.
The solution is to first convert one of the parts of the fraction to a SymPy object. The easiest way is with the function S, as in:
from sympy import *
u = symbols("u")
print(integrate((1+u)**(S(1)/2), (u, 0, 1)))
which outputs the desired -2/3 + 4*sqrt(2)/3.
The gotcha section of the documentation tries to explain this behavior.
I am trying to apart Exponential function in python.
import sympy as sym
from sympy.abc import t
from sympy import exp
u = (3*(exp(4*t) - 1)*exp(-4*t))/4
apart = sym.apart(u, t)
print(apart)
But i get the error:
exp(4*t) contains an element of the set of generators
it looks like exp() is confusing it. For a workaround
import sympy as sym
from sympy.abc import t,z
from sympy import exp
u = (3*(exp(4*t) - 1)*exp(-4*t))/4
expr = sym.apart(u.subs(exp(t),z), z)
expr = expr.subs(z,exp(t))
Which gives
Out[3]: 3/4 - 3*exp(-4*t)/4
Using 3.7 on conda
Your expression is a univariate, rational function in terms of exp(t):
>>> u.subs(exp(t),y)
3*(y**4 - 1)/(4*y**4)
>>> apart(_)
3/4 - 3/(4*y**4)
>>> _.subs(y, exp(t))
3/4 - 3*exp(-4*t)/4
But SymPy can handle such non-symbol generators so for such an expression sym.apart(u) would have given the same result as shown above. When you said the generator was t it detected the exp(t) and raised the error since an expression like t + exp(t) has two generators that depend on t.
How to correctly add or subtract using floats?
For example how to perform:
2.4e-07 - 1e-8
so that it returns 2.3e-7 instead of 2.2999999999999997e-07.
Converting to int first yields unexpected results, the below returns 2.2e-07:
int(2.4e-07 * 1e8 - 1) * 1e-8
Similarly,
(2.4e-07 * 1e8 - 1) * 1e-8
returns 2.2999999999999997e-07.
How to perform subtraction and addition of numbers with 8 decimal point precision?
2.2999999999999997e-07 is not sufficient as the number is used as a lookup in a dictionary, and the key is 2.3e-7. This means that any value other than 2.3e-7 results in an incorrect lookup.
I suggest using the decimal data type (it is present in the stardard installation of Python), because it uses fixed precision to avoid just the differences you are talking about.
>>> from decimal import Decimal
>>> x = Decimal('2.4e-7')
>>> x
Decimal('2.4E-7')
>>> y = Decimal('1e-8')
>>> y
Decimal('1E-8')
>>> x - y
Decimal('2.3E-7')
It's really just a way of skirting around the issue of floating point arithmetic, but I suggest using the decimal package from the standard library. It lets you do exact floating point math.
Using your example,
$ from decimal import Decimal
$ x = Decimal('2.4e-7')
$ y = Decimal('1e-8')
$ x-y
Decimal('2.3E-7')
It's worth noting that Decimal objects are different than the float built-in, but they are mostly interchangeable.
I do not know if it is what you are looking for but you can try that kind of thing:
a = 0.555555555
a = float("{0:.2f}".format(a))
>>> 0.56
I hope it will help you!
Adrien
Trying to compute the following lines I'm getting a realy complex result.
from sympy import *
s = symbols("s")
t = symbols("t")
h = 1/(s**3 + s**2/5 + s)
inverse_laplace_transform(h,s,t)
The result is the following:
(-(I*exp(-t/10)*sin(3*sqrt(11)*t/10) - exp(-t/10)*cos(3*sqrt(11)*t/10))*gamma(-3*sqrt(11)*I/5)*gamma(-1/10 - 3*sqrt(11)*I/10)/(gamma(9/10 - 3*sqrt(11)*I/10)*gamma(1 - 3*sqrt(11)*I/5)) + (I*exp(-t/10)*sin(3*sqrt(11)*t/10) + exp(-t/10)*cos(3*sqrt(11)*t/10))*gamma(3*sqrt(11)*I/5)*gamma(-1/10 + 3*sqrt(11)*I/10)/(gamma(9/10 + 3*sqrt(11)*I/10)*gamma(1 + 3*sqrt(11)*I/5)) + gamma(1/10 - 3*sqrt(11)*I/10)*gamma(1/10 + 3*sqrt(11)*I/10)/(gamma(11/10 - 3*sqrt(11)*I/10)*gamma(11/10 + 3*sqrt(11)*I/10)))*Heaviside(t)
However the answer should be simpler, Wolframalpha proves it.
Is there any way to simplify this result?
I tried a bit with this one and the way I could find a simpler solution is using something like:
from sympy import *
s = symbols("s")
t = symbols("t", positive=True)
h = 1/(s**3 + s**2/5 + s)
inverse_laplace_transform(h,s,t).evalf().simplify()
Notice that I define t as a positive variable, otherwise the sympy function returns a large term followed by the Heaviaside function. The result still contains many gamma functions that I could not reduce to the expression returned by Wolfram. Using evalf() some of those are converted to their numeric value and then after simplification you get a expression similar like the one in Wolfram but with floating numbers.
Unfortunately this part of Sympy is not quite mature. I also tried with Maxima and the result is quite close to the one in Wolfram. So it seems that Wolfram is not doing anything really special there.