Sympy.real_roots выводит что-то не то
Пытаюсь решить уравнение методом sympy.real_roots(), при больших коэффициентах вместо списка корней на вывод получаю следующее:
[2*CRootOf(109*x**5 - 4157*x**4 + 50498*x**3 - 184552*x**2 - 527136*x + 3507840, 0), 2*CRootOf(109*x**5 - 4157*x**4 + 50498*x**3 - 184552*x**2 - 527136*x + 3507840, 1), 2*CRootOf(109*x**5 - 4157*x**4 + 50498*x**3 - 184552*x**2 - 527136*x + 3507840, 2), 2*CRootOf(109*x**5 - 4157*x**4 + 50498*x**3 - 184552*x**2 - 527136*x + 3507840, 3), 2*CRootOf(109*x**5 - 4157*x**4 + 50498*x**3 - 184552*x**2 - 527136*x + 3507840, 4)]
Как получить корни? Код:
import sympy as sp x = sp.Symbol('x') roots = sp.real_roots(-109*x**5/3870720+4157*x**4/1935360-3607*x**3/69120+23069*x**2/60480+5491*x/2520+38-67, x) print(roots)
Difficulty in using sympy solver in python
[2*CRootOf(109*x**5 — 4157*x**4 + 50498*x**3 — 184552*x**2 — 527136*x + 3507840, 0), 2*CRootOf(109*x**5 — 4157*x**4 + 50498*x**3 — 184552*x**2 — 527136*x + 3507840, 1), 2*CRootOf(109*x**5 — 4157*x**4 + 50498*x**3 — 184552*x**2 — 527136*x + 3507840, 2), 2*CRootOf(109*x**5 — 4157*x**4 + 50498*x**3 — 184552*x**2 — 527136*x + 3507840, 3), 2*CRootOf(109*x**5 — 4157*x**4 + 50498*x**3 — 184552*x**2 — 527136*x + 3507840, 4)]
Can someone explain what the answer represent and how to get the output in conventional form i.e. say if the answer is 0.1,0.2,0.3,0.1,0.4 sympy usually outputs the answer as [0.1,0.2,0.3,0.1,0.4]
Python sub_post примеры использования
Python sub_post — 6 примеров найдено. Это лучшие примеры Python кода для sympy.simplify.cse_opts.sub_post, полученные из open source проектов. Вы можете ставить оценку каждому примеру, чтобы помочь нам улучшить качество примеров.
Related in langs
def test_issue_6169(): from sympy import CRootOf r = CRootOf(x**6 - 4*x**5 - 2, 1) assert cse(r) == ([], [r]) # and a check that the right thing is done with the new # mechanism assert sub_post(sub_pre((-x - y)*z - x - y)) == -z*(x + y) - x - y
def signsimp(expr, evaluate=None): """Make all Add sub-expressions canonical wrt sign. If an Add subexpression, ``a``, can have a sign extracted, as determined by could_extract_minus_sign, it is replaced with Mul(-1, a, evaluate=False). This allows signs to be extracted from powers and products. Examples ======== >>> from sympy import signsimp, exp, symbols >>> from sympy.abc import x, y >>> i = symbols('i', odd=True) >>> n = -1 + 1/x >>> n/x/(-n)**2 - 1/n/x (-1 + 1/x)/(x*(1 - 1/x)**2) - 1/(x*(-1 + 1/x)) >>> signsimp(_) 0 >>> x*n + x*-n x*(-1 + 1/x) + x*(1 - 1/x) >>> signsimp(_) 0 Since powers automatically handle leading signs >>> (-2)**i -2**i signsimp can be used to put the base of a power with an integer exponent into canonical form: >>> n**i (-1 + 1/x)**i By default, signsimp doesn't leave behind any hollow simplification: if making an Add canonical wrt sign didn't change the expression, the original Add is restored. If this is not desired then the keyword ``evaluate`` can be set to False: >>> e = exp(y - x) >>> signsimp(e) == e True >>> signsimp(e, evaluate=False) exp(-(x - y)) """ if evaluate is None: evaluate = global_evaluate[0] expr = sympify(expr) if not isinstance(expr, Expr) or expr.is_Atom: return expr e = sub_post(sub_pre(expr)) if not isinstance(e, Expr) or e.is_Atom: return e if e.is_Add: return e.func(*[signsimp(a) for a in e.args]) if evaluate: e = e.xreplace(dict([(m, -(-m)) for m in e.atoms(Mul) if -(-m) != m])) return e
def signsimp(expr, evaluate=None): """Make all Add sub-expressions canonical wrt sign. If an Add subexpression, ``a``, can have a sign extracted, as determined by could_extract_minus_sign, it is replaced with Mul(-1, a, evaluate=False). This allows signs to be extracted from powers and products. Examples ======== >>> from sympy import signsimp, exp, symbols >>> from sympy.abc import x, y >>> i = symbols('i', odd=True) >>> n = -1 + 1/x >>> n/x/(-n)**2 - 1/n/x (-1 + 1/x)/(x*(1 - 1/x)**2) - 1/(x*(-1 + 1/x)) >>> signsimp(_) 0 >>> x*n + x*-n x*(-1 + 1/x) + x*(1 - 1/x) >>> signsimp(_) 0 Since powers automatically handle leading signs >>> (-2)**i -2**i signsimp can be used to put the base of a power with an integer exponent into canonical form: >>> n**i (-1 + 1/x)**i By default, signsimp doesn't leave behind any hollow simplification: if making an Add canonical wrt sign didn't change the expression, the original Add is restored. If this is not desired then the keyword ``evaluate`` can be set to False: >>> e = exp(y - x) >>> signsimp(e) == e True >>> signsimp(e, evaluate=False) exp(-(x - y)) """ if evaluate is None: evaluate = global_evaluate[0] expr = sympify(expr) if not isinstance(expr, Expr) or expr.is_Atom: return expr e = sub_post(sub_pre(expr)) if not isinstance(e, Expr) or e.is_Atom: return e if e.is_Add: return e.func(*[signsimp(a, evaluate) for a in e.args]) if evaluate: e = e.xreplace() return e
def test_issue_6169(): from sympy import CRootOf r = CRootOf(x**6 - 4*x**5 - 2, 1) assert cse(r) == ([], [r]) # and a check that the right thing is done with the new # mechanism assert sub_post(sub_pre((-x - y)*z - x - y)) == -z*(x + y) - x - y
def test_issue_3070(): r = RootOf(x**6 - 4 * x**5 - 2, 1) assert cse(r) == ([], [r]) # and a check that the right thing is done with the new # mechanism assert sub_post(sub_pre((-x - y) * z - x - y)) == -z * (x + y) - x - y
Solving Guidance#
The vast majority of arbitrary nonlinear equations have no closed-form solution. The classes of equations that are solvable are basically:
- Linear equations
- Polynomials, except where limited by the Abel-Ruffini theorem (learn more about solving polynomials using a GroebnerBasis )
- Equations that can be solved by inverting some transcendental functions
- Problems that can be transformed into the cases above (e.g., by turning trigonometric functions into polynomials)
- A few other special cases that can be solved with something like the Lambert W function
- Equations that you can decompose() via any of the above
SymPy may reflect that your equation has no solutions that can be expressed algebraically (symbolically), or that SymPy lacks an algorithm to find a closed-form solution that does exist, by returning an error such as NotImplementedError :
>>> from sympy import solve, cos >>> from sympy.abc import x >>> solve(cos(x) - x, x, dict=True) Traceback (most recent call last): . NotImplementedError: multiple generators [x, cos(x)] No algorithms are implemented to solve equation -x + cos(x)
so you may have to solve your equation numerically instead, for example using nsolve()
>>> from sympy import nsolve, cos >>> from sympy.abc import x >>> nsolve(cos(x) - x, x, 2) 0.739085133215161
If you receive non-closed-form solutions such as CRootOf() (which represents an indexed complex root of a polynomial), you can evaluate them numerically using evalf() :
>>> from sympy import solve >>> from sympy.abc import x >>> solutions = solve(x**5 - x - 1, x, dict=True) >>> solutions [, , , , ] >>> [solution[x].evalf(3) for solution in solutions] [1.17, -0.765 - 0.352*I, -0.765 + 0.352*I, 0.181 - 1.08*I, 0.181 + 1.08*I]
When You Might Prefer a Numeric Solution#
Even if your problem has a closed-form solution, you might prefer a numeric solution.
Solving functions such as solve() and solveset() will not try to find a numeric solution, only a mathematically-exact symbolic solution. So if you want a numeric solution, consider nsolve() .
In some situations, even though a closed-form solution is available, it may be too cumbersome to be desirable. In that case, you can use evalf() instead if a numerical solution is acceptable. For example, the following solution set contains more than 40 terms total when expressed exactly (scroll horizontally in the code block below if you want to view them all), compared to eight when expressed numerically:
>>> from sympy import symbols, solve >>> x = symbols('x') >>> solutions = solve(x**4 + 10*x**2 + x + 1, x, dict=True) >>> solutions [, , , ] >>> for solution in solutions: . solution[x].evalf() -0.0509758447494279 + 0.313552108895239*I 0.0509758447494279 + 3.14751999969868*I 0.0509758447494279 - 3.14751999969868*I -0.0509758447494279 - 0.313552108895239*I
In other situations, even if the exact solution has few terms, you may want a numeric solution so you know its approximate numerical value. For example, it may be difficult to estimate that \(\sqrt e^<\pi>/2\) is approximately \(16\) :
>>> from sympy import pi, sqrt, exp, solve, evalf >>> shorter = solve(sqrt(2)*x - exp(pi), x, dict=True) >>> shorter [] >>> [solution[x].evalf(3) for solution in shorter] [16.4]
Use Exact Values#
If you want to preserve the exact mathematical values of symbols such as transcendental numbers and square roots , define them so that SymPy can interpret them symbolically, for example use SymPy’s Pi :
>>> from sympy import symbols, solve, pi >>> x = symbols('x') >>> solve(x**2 - pi, x, dict=True) [, ]
If you use the standard Python math version of \(\pi\) , Python will pass that inexact value to SymPy, leading to an inexact, numerical solution:
>>> from sympy import symbols, solve >>> from math import pi >>> x = symbols('x') >>> solve(x**2 - pi, x, dict=True) [, ]
To use exact values for numbers such as \(6.2\) or \(1/2\) , refer to Python numbers vs. SymPy Numbers .
In certain cases, using an inexact value will prevent SymPy from finding a result. For example, this exact equation can be solved:
>>> from sympy import symbols, solve, sqrt >>> x = symbols('x') >>> eq = x**sqrt(2) - 2 >>> solve(eq, x, dict=True) []
but if you use the inexact equation eq = x**1.4142135623730951 — 2 , SymPy will not return a result despite attempting for a long time.
Include the Variable to be Solved for in the Function Call#
We recommend you include the variable to be solved for as the second argument for solving functions including solve() and solveset() . While this is optional for univariate equations, it is a good practice because it ensures SymPy will solve for the desired symbol. For example, you might be interested in a solution for \(x\) , but SymPy solves for \(y\) :
>>> from sympy.abc import x, y >>> from sympy import solve >>> solve(x**2 - y, dict=True) []
Specifying the variable to solve for ensures that SymPy solves for it:
>>> from sympy.abc import x, y >>> from sympy import solve >>> solve(x**2 - y, x, dict=True) [, ]
Ensure Consistent Formatting From solve() #
solve() produces a variety of output as explained in Solve Output by Type . Using dict=True will give a consistent output format which is especially important when extracting information about the solution programmatically.
To extract the solutions, you can iterate through the list of dictionaries:
>>> from sympy import parse_expr, solve, solveset >>> from sympy.abc import x >>> expr = «x^2 = y» >>> parsed = parse_expr(expr, transformations=«all») >>> parsed Eq(x**2, y) >>> solutions = solve(parsed, x, dict=True) >>> [solution[x] for solution in solutions] [-sqrt(y), sqrt(y)] >>> solveset(parsed, x)
Options That Can Speed up solve() #
Include Solutions Making Any Denominator Zero#
Normally, solve() checks whether any solutions make any denominator zero, and automatically excludes them. If you want to include those solutions, and speed up solve() (at the risk of obtaining invalid solutions), set check=False :
>>> from sympy import Symbol, sin, solve >>> x = Symbol("x") >>> solve(sin(x)/x, x, dict=True) # 0 is excluded [] >>> solve(sin(x)/x, x, dict=True, check=False) # 0 is not excluded [, ]
Do Not Simplify Solutions#
Normally, solve() simplifies many results before returning them and (if check is not False) uses the general simplify() function on the solutions and the expression obtained when they are substituted into the function which should be zero. If you do not want the solutions simplified, and want to speed up solve() , use simplify=False .
>>> from sympy import solve >>> from sympy.abc import x, y >>> expr = x**2 - (y**5 - 3*y**3 + y**2 - 3) >>> solve(expr, x, dict=True) [, ] >>> solve(expr, x, dict=True, simplify=False) [, ]
Parse a String Representing the Equation#
If you are creating the expression yourself, we advise against using string parsing to create expressions. But if you are programmatically reading in a string, this approach is convenient.
You can parse a string representing the equation into a form that SymPy can understand (for example, Eq form), then solve the parsed expression. Parsing an equation from a string requires you to use transformations for SymPy to
- interpret equals signs
- create symbols from your variables
- use more mathematical (rather than standard Python) notation, for example the exponent operator can be parsed from ^ rather than having to use Python’s ** .
If you already have the equation in Eq (equation) form, you can parse that string:
>>> from sympy import parse_expr, solve, solveset >>> from sympy.abc import x >>> expr = "Eq(x^2, y)" >>> parsed = parse_expr(expr, transformations="all") >>> parsed Eq(x**2, y)
SymPy can also parse LaTeX into expressions using parse_latex() .
Report a Bug#
If you find a bug with these commands, please post the problem on the SymPy mailing list.