sympy
sympy copied to clipboard
Nonlinsolve wrong solution
Hello,
I would like to automatise the resolution of this kind of equations (and increase litle by litle the number of variables) :
a*exp(-b*90)=33
a*exp(-b*92)=66
I first tried this with one equation and it worked:
import sympy as sym
from sympy import solveset, S
from sympy.abc import x
from sympy import Symbol
a = symbols('a')
eq=sym.Eq(sym.exp(a*90),33)
solveset(eq,a,domain=S.Reals)
Then I tried this but it didn’t work :
a,b = symbols('a,b')
eq1 = sym.Eq(a*sym.exp(-b*90),33)
eq2 = sym.Eq(a*sym.exp(-b*92),66)
result=sym.solveset([eq1,eq2],(a,b),domain=S.Reals)
I get the following error, I guess the exponential is the problem?
ValueError Traceback (most recent call last)
Input In [59], in <cell line: 9>()
7 eq1 = sym.Eq(a*sym.exp(-b*90),33)
8 eq2 = sym.Eq(a*sym.exp(-b*92),66)
----> 9 result=sym.solveset([eq1,eq2],(a,b),domain=S.Reals)
File C:\ProgramData\Anaconda\lib\site-packages\sympy\solvers\solveset.py:2178, in solveset(f, symbol, domain)
2175 return S.EmptySet
2177 if not isinstance(f, (Expr, Relational, Number)):
-> 2178 raise ValueError("%s is not a valid SymPy expression" % f)
2180 if not isinstance(symbol, (Expr, Relational)) and symbol is not None:
2181 raise ValueError("%s is not a valid SymPy symbol" % (symbol,))
ValueError: [Eq(a*exp(-90*b), 33), Eq(a*exp(-92*b), 66)] is not a valid SymPy expression
Then I tried :
import sympy as sym
from sympy import symbols, nonlinsolve
a, b = symbols('a, b', real=True)
eq1 = sym.Eq(a*sym.exp(-b*90),33)
eq2 = sym.Eq(a*sym.exp(-b*92),66)
sol = nonlinsolve([eq1,eq2],[a,b])
print(sol)
I get
{(NaN, NaN),(33𝑒90𝑖(2𝑛𝜋+𝜋)35184372088832, {𝑖(2𝑛𝜋+𝜋)+log(2⎯⎯√2)|||||𝑛∈ℤ}),(33𝑒180𝑛𝑖𝜋35184372088832, {2𝑛𝑖𝜋+log(2⎯⎯√2)|||||𝑛∈ℤ})}
However I want real solutions and if I solve if by hand, i get a= 33*2**(-45) and b= -ln(2)/2. I don't understand why I don't get this solution when computed.
I checked if the manual solution belongs to the computed solution but I get false
.
sol_byhand=(33*2**(-45),-sym.log(2)/2)
sol_byhand in sol
Is it normal? It was suggested here to raise an issue.
Thanks for reading
An answer was suggested at the issue. Note that
- on your second attempt you misused
solveset
. - The output of
nonlinsolve
is probably fine but you have to select values ofn
that give you the real solution.
- Thank you for your answer. But by indicating
real=True
in the definition of a and b, shouldn't lead to only the real solutions? - I am sorry but I am not sure of what is wrong in my second attempt of solveset? that I wrote
sym.solveset
wheareas I could only writesolveset
?
I tried 2 ways to extract the real solution from the set :
-
sol=nonlinsolve([eq1,eq2],[a,b]) & sym.Reals**2
but it leads toEmptySet
. -
sol_real=[(a,b) for (a,b) in sol if (np.imag(a)==0 and np.imag(b)==0)] print (f"only real solution : {sol_real}")
but I getonly real solution : []
So it seams that the real solution that I fond manually is not inside the set?
- not sure of what is wrong in my second attempt of solveset
You passed a list ([eq1,eq2]
), not an expression or relational, for f
:
I do not know how to work well with the sets/imagesets. But here is one way:
I do not know how to work well with the sets/imagesets. But here is one way:
Thank you for that, I will keep that as I keep on working with my problem
For at least the parts of the solution which are ImageSet
s, you can also get the real solutions by finding the intersection of the ImageSet
with S.Reals
(with evaluate =True
). The evaluation of the intersection doesn't seem to always work, but it works for the ImageSet
s in this case:
>>> from sympy import *
>>> a, b = symbols('a, b', real=True)
>>> eq1 = Eq(a*exp(-b*90),33)
>>> eq2 = Eq(a*exp(-b*92),66)
>>> result = nonlinsolve([eq1, eq2], [a, b])
>>> sol1 = result.args[1] # ignore the NaN solution
>>> b_sol = sol1[1]
>>> b_sol
ImageSet(Lambda(_n, 2*_n*I*pi + log(sqrt(2)/2)), Integers)
>>> real_sol = Intersection(b_sol, S.Reals, evaluate=True)
>>> real_sol
{log(sqrt(2)/2)}
@NikhilSDate thank you !