Equation roots: parameter doesn't get simplified - python

I am using Python with Sympy.
I need to solve the following equation, finding the 4 roots (omega is my unknown):
deter= 0.6*omega**4*cos(omega*t)**2 - 229.0*omega**2*cos(omega*t)**2 + 5880.0*cos(omega*t)**2
I tried to use solve:
eqcarr=solve(deter,omega,exclude=[t])
I get this output:
[-18.8143990830350, -5.26165884593044, 5.26165884593044, 18.8143990830350, 1.5707963267949/t, 4.71238898038469/t]
I only need the first 4 values, and not the values with the t coefficient. I expect the cos(omega*t)**2 to be simplified in solve, but this doesn't happen.

According to documentation solve will not solve for any of the free symbols passed in the exclude.
'exclude=[] (default)'
don't try to solve for any of the free symbols in exclude;
if expressions are given, the free symbols in them will
be extracted automatically.
It is not meant to filter solution.
You can solve your problem by doing this:
In [10]: from sympy import *
In [11]: from sympy.abc import omega, t
In [12]: deter= 0.6*omega**4*cos(omega*t)**2 - 229.0*omega**2*cos(omega*t)**2 + 5880.0*cos(omega*t)**2
In [13]: eqcarr=solve(deter,omega,exclude=[t])
In [14]: filtered = [i for i in eqcarr if not i.has(t)]
In [15]: filtered
Out[15]: [-18.8143990830350, -5.26165884593044, 5.26165884593044, 18.8143990830350]

Related

Reducing multiple inequalities to one in python

I have two equalities and an inequality relationship between them. I would like to simplify those to a single inequality (I do not need to solve the unknowns). Here is my code:
from sympy.abc import x,y
from sympy import reduce_inequalities
eq1 = np.multiply(array_1[0], (1-delta))+delta*Q[0]*[x,y]
eq2 = np.multiply(array_1[1], (1-delta)) + delta*Q[1]*[x,y]
print(reduce_inequalities(eq1, eq2))
array_1 is a 1x4 array I defined previously, and I only need one element (I choose the elements by slicing the array). Q is a 4x2 array I defined previously. The unknowns are x and y. The output I get is True.
Is there any way to simplify this with sympy or any other python library in such a way I could use the simplified version later on?
Edit: I forgot to mention delta is also defined previously.

How to solve implementation problem in sympy

I need to solve an equation, but spider returns me this error:
import sympy as sym
import sympy as sympy
Re=100
Epsilon=0.00000075
D=0.01
f=symbols('f')
eq=(((1/(-2* sympy.log((Epsilon/D/ 3.7)+( 2.51 / (Re*(f**0.5))), 10)))**2 -f),0)
sym.solve((eq), (f))
print(f)
NotImplementedError: could not solve -4*f*log(202702702702703/10000000000000000000 + 251/(10000*sqrt(f)))**2 + log(10)**2
The solve function is for finding analytic solutions but that isn't possible for your equation (not all equations have analytic solutions):
In [11]: eq[0]
Out[11]:
2
log (10)
-f + ──────────────────────────────────────────
2⎛ -0.5 ⎞
4⋅log ⎝0.0251⋅f + 2.02702702702703e-5⎠
You can find a numeric solution with nsolve:
In [12]: sym.nsolve(eq[0], f, 0.1)
Out[12]: 0.169438052045717
https://docs.sympy.org/latest/modules/solvers/solvers.html#sympy.solvers.solvers.nsolve
This can be represented in terms of the LambertW function, but it needs some help. SymPy doesn't recognize the inverted sqrt(f) in the log. If you replace that with 1/y and solve for y and transform the solutions for y back to f you can get a symbolic solution.
It's easier in this case to let SymPy work with symbols instead of Floats and substitute the values later. Your equation looks like this:
>>> from sympy import a,b,c
>>> seq = a**2/log(b/sqrt(f) + c)**2 - f
>>> reps = {a:log(10)/2, c:Epsilon/D/3.7, b:2.51/Re}
Replace that sqrt(f) with 1/y
>>> ysol = solve(seq.xreplace(sqrt(f), 1/y), y)
Calculate the corresponding solutions for f:
>>> fsol = [((1/i)**2) for i in ysol]
Substitute in your values -- or any values that you are interested in:
>>> [i.xreplace(reps).n(3) for i in fsol]
[0.00771 - 0.107*I, 0.169]
Testing in the original shows that the second solution is valid
>>> [eq.subs(f,i).n() for i in _]
[0.148289010493944 + 0.206688429851791*I, 6.05179945288758e-6]
So your symbolic solution is
>>> fsol[1]
(-c/b + LambertW(a*exp(a*c/b)/b)/a)**(-2)
The nice thing about this form is that you can substitute any values of a,b,c and get the corresponding value of f. Whether this is faster than using nsolve, you will have to see.

Solving equation using sympy

Given U(x) = ((x^2-1)^2- x^2) / ( x*(x^2-1)) , I'm trying to solve this equation :
U(x)- 1/U(x) = x using sympy and this is my code :
from sympy import *
x=symbols('x')
P,Q=x**2-1,x
t=(P**2-Q**2)/(P*Q)
print(solve(Eq(t-1/t,x),x))
I got a very long list (squeezed text with 1394 lines ) which is wrong comparing to the right solution i have got on wolfram alpha ( this is the right list : l3=[-0.507713305942872,0.507713305942872,-0.777861913430206,0.777861913430206,-1.46190220008154,1.46190220008154]
How can i get the same result in python using sympy ?
If you consider the numeric solutions
[-0.507713305942872,0.507713305942872,-0.777861913430206,0.777861913430206,-1.46190220008154,1.46190220008154]
to be correct, solve is probably not the right tool to use. These solutions are not actually "correct" they are just very very close. solve is trying to find an analytic i.e. 100% perfect solution. If you are fine with a little error you should use nsolve (numeric solve) instead of solve.
Also it seems you have an error in your equation code. I let sympy nsolve them, got a solution that wasn't among the WA ones. So I rewrote the equation and got nsolve to give me one of WA's solutions:
from sympy import *
x=symbols('x')
U = ((x**2-1)**2- x**2) / (x*(x**2-1))
eqn = U - 1/U - x
nsolve(eqn,x,0.1)
This yields 0.507713305942872. Which is the closest solution to the start value of 0.1.
As Oscar Benjamin has pointed out in the comments you can get all numeric solutions with
from sympy import *
x=symbols('x')
U = ((x**2-1)**2- x**2) / (x*(x**2-1))
eqn = U - 1/U - x
Poly(eqn.as_numer_denom()[0]).nroots()
By default nroots calculates 50 decimal places but you can specify how many you want by giving a keyword argument like so .nroots(n=decimal_places)

Converting expression involving tranpose of vector to numerical function with lambdify

I have written a script in python that uses sympy to compute a couple of vector/matrix formulas. However, when I try to convert those to functions that I can evaluate with sympy.lambdify, I get a
SyntaxError : EOL while scanning string literal
Here's some code with the same error, so that you can see what I mean.
import sympy
x = sympy.MatrixSymbol('x',3,1)
f = sympy.lambdify(x, x.T*x)
So, the syntax error has to do with the expression "x'.dot(x)" and the conversion of ".T" to '.
How can I work around this to correctly define f from the above lambdify?
Found a work around, although not the cleanest looking solution... but it works.
Use the implemented_function() method from sympy to define your function. Read full documentation here: http://docs.sympy.org/latest/modules/utilities/lambdify.html
Here is the code:
import sympy
import numpy as np
from sympy.utilities.lambdify import implemented_function
x = sympy.MatrixSymbol('x',3,1)
f = implemented_function(sympy.Function('f'), lambda x: x.T*x)
lam_f= sympy.lambdify(x, f(x))
Hope this solves your problem :)
It has been solved in sympy version >= 1.1
Edit:
Example
when u define this
x = sympy.MatrixSymbol('x',3,1)
you are creating a matrix,
you can check its indexing and shape using
print(sympy.Matrix(x))
Now that you want to multiply Transpose of x to x, you will have to give x a matrix of same shape that you have defined before
here try this:
from sympy import MatrixSymbol, lambdify, Matrix
x = MatrixSymbol('x', 3, 1)
f = lambdify(x, x.T*x)
a = Matrix([[1], [2], [3]])
print(f(a))
you can check this link out to understand lambdify better:
http://docs.sympy.org/latest/modules/utilities/lambdify.html

Derivative on index symbols in sympy

I am trying to do symbolical calculations (derivatives mostly) on time-indexed variables using sympy.
Using indexed symbols like r[t] below produces an error:
from sympy import *
t = Idx('t',10)
r = IndexedBase('r')
diff(r[t],r[t])
diff(r,r)
ValueError:
Can't differentiate wrt the variable: r[t], 1
Could the reason be that something went wrong here:
In [15]: r[t].indices
Out[15]: (t,)
The comma after the index t looks suspicious to me, but I have no idea what went wrong.
Does anyone know how to do this in sympy?
You can differentiate wrt symbols, functions and derivatives. Will this work:
>>> t = Idx('t',10)
>>> r=Function('r')
>>> r(t).diff(r(t))
1
>>> var('t')
t
>>> r(t).diff(t)
Derivative(r(t), t)

Categories