How to select a component of a sympy equation? - python

I would like to know if it is possible to select the compotent of a given term of an equation. For example in the photo below. I got that result for a tensor component and I wanna know if it is possible for me to get only the coefficient of the term that accompanies the (e-1)^4 (without having to copy it by hand).

Use the coeff method:
>>> eq = 3*y*(1 - x)**4 + 2*y*(1 - x)
>>> eq.coeff((1-x)**4)
3*y

Related

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)

How to check if `sympy.dsolve` can solve differential equation in explicit form?

I'm testing dsolve method of sympy package in order to check if any differential can be solved and return solution if it is. Trying to solve equation of this kind
from sympy import dsolve
t = symbols('t')
x = Function('x')
dsolve(x(t).diff(t) - x(t)**2 + t**2)
returns an answer:
The last term of this expression tells me that an equation doesn't have explicit solution. How can I check if equation has an explicit solution using sympy?
I hope something like this:
is_solution_explicit(x(t).diff(t) - x(t)**2 + t**2) returns False
is_solution_explicit(2*x(t)/(1+t) + (1+t)**3) returns True

How to return a finite (float) value with nonlinsolve in SymPy?

I am very new to programming, and had to use sympy for a school project.
I think I get that using nonlinsolve to return an angle gives an ImageSet with the angle + 2n*pi. However I want it to return only the value of the angle (in the interval [0,pi/2]), and as one value and not an interval.
from sympy import nonlinsolve, symbols,cos
x=symbols('x')
print(nonlinsolve([cos(x)-1],[x]).args[0][0])
I want the result to be 0 and not 2*n*pi.
Clarification : I know that the result is correct, but I only want one value, that I can use algebraically, and I don't know how Sympy works (how to manipulate ImageSets)
So I might be wrong because i dont use sympy, but the solution that solvers return seems to be corect to me.
ImageSet(Lambda(_n, 2*_n*pi), Integers)
From what I understand solver returned lambda function. Cosinus is a cyclic function which means it reapeats it's value every 2PI. So the solver says first solution (_n = 0) is 0, second (_n = 1) is 2pi and so on.
look at the function plot and it will hopefully make sense:
Wolfram Alpha - (cos(x) - 1)
EDIT: I think you need to use intersect method of imageset like this( note that intersect returns all the intersections, here i selected just the first one):
from sympy import nonlinsolve, symbols,cos, Interval
import math
x = symbols('x')
f = nonlinsolve([cos(x)-1], [x]).args[0][0]
sol = f.intersect(Interval(0, math.pi/2)).args[0]
print(sol)

Evaluate parametric derivative of a symbolic function in Python

I'm a beginner with Python (v 3.7) and I am trying to evaluate numerically a derivative of a symbolic function that contains parameters but I can't feed the values in a successful way.
I've tried different combinations getting inspiration from reading this question and something also from here.
Here is a minimal example that replicates my problem:
import sympy as sym
from sympy import*
x, y, a = sym.var('x, y, a')
def f(x,y):
return a*x**2 + x*y**2
fprime = sym.diff(f(x,y),x)
print(f(1,1))
print(fprime.evalf(subs={x: 1, y: 1}))
As expected the output of the first print is a+1 but the issue arrives with the second print because the output I get is 2.0*a*x + y**2 while I wish to obtain 2*a+1.
How shall I amend my code? I've also tried defining fprime separately and run the following:
def fprime(x,y):
return sym.diff(f(x,y),x)
print(fprime(x,1))
but still I can't make any progress. Thanks!
Just use substitution. Use evalf when you are trying to get a number from an expression that is a number. Your, containing unevaluated a is not yet a number so evaluation rejects it.
>>> fprime.subs({x: 1, y: 1})
2*a + 1

Categories