I'm trying to solve the following equation.
(x * x) - 1 = 0
The result should be +1 or -1. But when I try to solve it via sympy, the result is an empty output.
import sympy as sy
x = sy.Symbol('x')
sy.solve((x**2)-1, 0)
# sy.solve((x * x)-1, 0) and sy.solve((x * x), 1) returns the same result
>>> []
What am I doing wrong here?
You should use,
sy.solve((x**2)-1,x)
Instead of,
sy.solve((x**2)-1,0)
The second argument x suggests that the equation should be solved for x. You are solving the equation for 0 which makes no sense.
Carefully read the documentation in the future :)
It is supposed to be
>>> from sympy.solvers import solve
>>> from sympy import Symbol
>>> x = Symbol('x')
>>> solve(x**2 - 1, x)
Read the documentation for the function here
Either do
sp.solve((x**2)-1, x)
or
sp.solve((x**2) - 1)
For further information, you can check out https://docs.sympy.org/latest/modules/solvers/solvers.html
In nsolve the second argument is an initial guess for the value of the variable that will make the univariate expression equal to zero:
>>> nsolve(x**2-1, 0)
1.00000000000000
>>> nsolve(x**2-1, -3)
-1.00000000000000
In solve, however, an initial guess is not needed since the equation will be solved symbolically:
>>> nsolve(x**2-1)
[-1, 1]
But solve can also handle multivariate expressions and in that case the second argument is used to indicate which variable you want to solve for.
>>> solve(x**2-c)
[{c: x**2}]
>>> solve(x**2-c, x)
[-sqrt(c), sqrt(c)]
But you can solve for anything that appears in the expression, even numbers. That's why an error is not raised in your case (though perhaps zero should raise an error). Here are examples of solving for a number:
>>> solve(3*x**2-c, 3)
[c/x**2]
>>> solve(3*x**4-c, 4)
[log(c/3)/log(x)]
>>> solve(2*x**2-c, 2)
[LambertW(c*log(x))/log(x)]
Related
according to this graph: desmos
print(solve('x**2 + x - 1/x'))
# [-1/3 + (-1/2 - sqrt(3)*I/2)*(sqrt(69)/18 + 25/54)**(1/3) + 1/(9*(-1/2 - sqrt(3)*I/2)*(sqrt(69)/18 + 25/54)**(1/3)), -1/3 + 1/(9*(-1/2 + sqrt(3)*I/2)*(sqrt(69)/18 + 25/54)**(1/3)) + (-1/2 + sqrt(3)*I/2)*(sqrt(69)/18 + 25/54)**(1/3), -1/3 + 1/(9*(sqrt(69)/18 + 25/54)**(1/3)) + (sqrt(69)/18 + 25/54)**(1/3)]
I was expecting [0.755, 0.57], but, I got something I cannot use in my future program. I desire to get a list of floats as result, so refer to this post, I did following, but I got some even more weird:
def solver(solved, rit=3):
res = []
for val in solved:
if isinstance(val, core.numbers.Add):
flt = val.as_two_terms()[0]
flt = round(flt, rit)
else:
flt = round(val, rit)
if not isinstance(flt, core.numbers.Add):
res.append(flt)
return res
print(solver(solve('x**2 + x - 1/x')))
# [-0.333, -0.333, -0.333]
Now I am really disappointed with sympy, I wonder if there is an accurate way to get a list of floats as result, or I will code my own gradient descent algorithm to find the roots and intersection.
sym.solve solves an equation for the independent variable. If you provide an expression, it'll assume the equation sym.Eq(expr, 0). But this only gives you the x values. You have to substitute said solutions to find the y value.
Your equation has 3 solutions. A conjugate pair of complex solutions and a real one. The latter is where your two graphs meet.
import sympy as sym
x = sym.Symbol('x')
# better to represent it like the equation it is
eq = sym.Eq(x**2, 1/x - x)
sol = sym.solve(eq)
for s in sol:
if s.is_real:
s = s.evalf()
print(s, eq.lhs.subs({x: s})) # eq.rhs works too
There are a variety of things you can do to get the solution. If you know the approximate root location and you want a numerical answer, nsolve is simplest since it has no requirements on the type of expression:
>>> from sympy import nsolve, symbols
>>> x = symbols('x')
>>> eq = x**2 + x - 1/x
>>> nsolve(eq, 1)
0.754877666246693
You can try a guess near 0.57 but it will go to the same solution. So is there really a second real roots? You can't use real_roots on this expression because it isn't in polynomial form. But if you split it into numerator and denominator you can check for the roots of the numerator:
>>> n, d = eq.as_numer_denom()
>>> from sympy import real_roots
>>> real_roots(n)
[CRootOf(x**3 + x**2 - 1, 0)]
So there is only one real root for that expression, the one that nroots gave you.
Note: the answer that solve gives is an exact solution to the cubic equation and it can't figure out definitively which ones are a solution to the equation so it returns all three. If you evaluate them you will find that only one of them is real. But since you don't need the symbolic solution, just stick to nroots.
My equation is ax = ln(ec-b/y)
How can I find what x*y equals in python? I've tried using SymPy.solve, but it doesn't allow me to solve for a term. Thanks in advance.
If you solve for y = f(x) then y*x = x*f(x). So these two steps in SymPy are:
>>> from sympy.abc import a,b,c,x,y
>>> from sympy import solve, Eq
>>> solve(Eq(a*x , ln(exp(c-b)/y)),y)
[exp(-a*x - b + c)]
>>> _[0]*x # == y*x
x*exp(-a*x - b + c)
You can solve for any subexpression, but when it is not a symbol, it will be interpreted literally as if you solved for u after replacing the sub-expression with u:
>>> solve(x*y - 1/x, x*y)
[1/x]
In your expression there is no x*y so that's why an attempt to naively solve for it fails.
Basically I'm trying to run the following code.
import sympy as sp
alpha = sp.Symbol(r'\alpha')
x = sp.Symbol('x')
sp.Q.is_true(alpha != -1)
sp.integrate(x**alpha, x)
This results in the following Piecewise function.
Since I specify global assumptions that alpha != -1, I expected it will simply give me the first expression. So two questions I have:
how do you properly define the assumptions so that the sp.integrate does not ignore them;
is there a way to access (extract) the first (or second) expression from the Piecewise function?
Thanks in advance!
PS. Defining conds='separate' in the sp.integrate only returns the first expression for some reason. So if I needed the second part of the piecewise function, I wouldn't be able to get it.
PPS. In case this matters, I have python 3.8.0 and sympy 1.4.
There is no way to give a specific value as an assumption for a symbol so it can be used in the integration. The best you can do is specify positive, negative, etc... But as for extracting the desired expression from the Piecewise, you can either get it as the particular argument or else feed in a dummy value for x that would extract it. Like the following:
>> from sympy.abc import x
>> from sympy import Piecewise, Dummy
>> eq = Piecewise((x + 1, x < 0), (1/x, True))
>> eq.args[0]
(x + 1, x < 0)
>> _.args[0]
x + 1
>> d = Dummy(negative=True)
>> eq.subs(x, d)
d + 1
>> _.subs(d, x)
x + 1
I am trying to solve simultaneous equations for x and y, I am not getting any result (code just keeps on running). I feel the error is related to using sqrt in the equations but not sure. Can someone help me figure this out?
from __future__ import division
from sympy import Symbol,sqrt,solve
x = Symbol('x')
y = Symbol('y')
z = Symbol('z')
a = Symbol('a')
b = Symbol('b')
c = Symbol('c')
d = Symbol('d')
e = Symbol('e')
f = Symbol('f')
g = Symbol('g')
h = Symbol('h')
print (solve((sqrt((c-a)**2+(d-b)**2)+sqrt((x-c)**2+(y-d)**2)-2*sqrt((x-a)**2+(y-b)**2),(y-b)*(e-a)-(x-a)*(f-b)) ,x,y))
This is a(nother) problem were you have to rely on the A of CAS and let SymPy assist you instead of relying on SymPy (in it's current state) to do all the work. The following assumes that eqs is a list of the two equations you want to solve as you gave in the OP.
Notice that the 2nd equation is linear in both symbols. Solve for y and substitute into the first equation.
>>> yis = solve(eqs[1], y)[0]
>>> eq0 = eqs[0].subs(y,yis)
This gives an expression that has a lot of symbols in it and that slows things down. It also has two terms with sqrt that depend on x. Replace those arguments of the sqrt with Dummy symbols and then unrad the expression to get it in polynomial form, restore replacements and factor:
>>> from sympy.solvers.solvers import unrad, S
>>> reps = {i.base:Dummy() for i in eq0.atoms(Pow) if i.has(x) and i.exp==S.Half}
>>> ireps = {v:k for k,v in reps.items()}
>>> poly = unrad(eq0.xreplace(reps), *reps.values())[0].xreplace(ireps).factor()
Using factor is an expensive process to always use, but if you know the problem is going to take a long time without it, it is worth a try. In this case a quartic reduces to a product of quadratics which are easy to solve and don't require checking or simplification:
>>> xis = solve(poly, x)
There are three solutions for x and each of these can be substituted into the expression for y to get the three solutions. The solutions are large enough so they are not shown here.
>>> count_ops(xis)
386
Given an expression in sympy, is there a way to find all discontinuities in a given interval? For instance, given 1/(x^2-1) from -2 to 2, it would return -1 and 1. It doesn't have to be symbolic. A numerical solution may actually work better for my purposes.
You can use the singularities module for this.
In [ ]: from sympy import *
In [ ]: init_printing()
In [ ]: x = symbols('x')
In [ ]: singularities(1/(x**2 - 1), x)
Out[ ]: (-1, 1) # A tuple of SymPy objects
Reference: http://docs.sympy.org/latest/modules/calculus/index.html#sympy.calculus.singularities.singularities
I don't think that there's any specific method in SymPy to do this; it might be very difficult to do in full generality (i.e. for any possible function, in any number of variables, including those with infinite discontinuities).
If you're working with relatively simple expressions in one real variable, such as the example in your question, then one approach could be to compute the expression as a ratio of two expressions and then solve the denominator expression.
>>> expr
1/(x**2 - 1)
>>> n, d = expr.as_numer_denom()
>>> sympy.solve(d)
[-1, 1]
Another small example:
>>> expr2 = 1/(sympy.sin(x)) + 4/(x**2 - 3)
>>> expr2
1/sin(x) + 4/(x - 3)
>>> n, d = expr2.as_numer_denom()
>>> sympy.solve(d)
[0, -sqrt(3), sqrt(3), pi]
Obviously in this case SymPy does not list every multiple of pi as a solution; you'll have to process the list to generate solutions that lie in your desired domain.