pythonmathsympynonlinear-equation

How to solve a system of nonlinear equations with Python?


I'm trying to solve this system of nonlinear equations with Python:

2y3 + y2 - y5 - x4 + 2x3 - x2 = 0
(-4x3 + 6x2 - 2x) / (5y4 - 6y2 - 2y) = 1

Here's my code:

from sympy import symbols, Eq, solve
x, y = symbols('x y')
eq1 = Eq(2*y**3 + y**2 - y**5 - x**4 + 2*x**3 - x**2, 0)
eq2 = Eq((-4*x**3 + 6*x**2 - 2*x)/(5*y**4 - 6*y**2 - 2*y), 1)
points = solve([eq1, eq2], [x,y])

I know that this system of equations have 5 solutions, however I get none with this code. Someone know how I can proceed instead?

By the way, the second equation is the derivative dy/dx of the first one, so basically I'm trying to find all the points in the curbe eq1 where the slope of the tangent is 1. The graph of the first equation is this.

Graph of equation 1

I have already solve this problem with Geogebra and got 5 answers. I'm experimenting with Python and want to see if I can solve it using any Python library.

Solution using Geogebra


Solution

  • By rewriting the second equation such that there is no denominator, and using nonlinsolve we can find all solutions (on this particular example):

    from sympy import symbols, Eq, solve, fraction, nonlinsolve
    x, y = symbols('x y')
    eq1 = Eq(2*y**3 + y**2 - y**5 - x**4 + 2*x**3 - x**2, 0)
    eq2 = Eq((-4*x**3 + 6*x**2 - 2*x)/(5*y**4 - 6*y**2 - 2*y), 1)
    n, d = fraction(eq2.lhs)
    eq2 = Eq(n, d)
    sol = nonlinsolve([eq1, eq2], [x, y])
    print(len(sol))
    
    # 11
    

    After a few seconds (or minutes, depending on your machine), nonlinsolve found 11 solutions. Turns out that 6 of them are complex solutions. One way to extract the real solutions is:

    xcoords, ycoords = [], []
    for s in sol:
        t1, t2 = s
        if t1.is_real and t2.is_real:
            t1 = t1.n()
            t2 = t2.n()
            xcoords.append(t1)
            ycoords.append(t2.n())
            print("(%s, %s)" % (t1, t2))
    
    # (0, 0)
    # (1.00000000000000, 0)
    # (1.10625265404821, -0.573060136806016)
    # (0.226655046617082, -0.502774766639858)
    # (-0.757531019709684, 1.45262440731163)
    

    Bonus tip. If you use this plotting module you can quickly visualize what you are computing:

    from spb import *
    graphics(
        implicit_2d(eq1, (x, -2, 2), (y, -3, 3), n=1000),
        implicit_2d(eq2, (x, -2, 2), (y, -3, 3), n=1000),
        list_2d(xcoords, ycoords, scatter=True),
        xlabel="x", ylabel="y"
    )
    

    enter image description here