Typically numerical optimization is performed using binary 64 bit IEEE 754 floating point numbers (becuase modern processors offer good performance/precision characteristics for this data type). By using a math library which supports arbitrary precision we can achive higher precision (larger number of significant digits). By using pyneqsys we only need to write our equations once. We will be using mpmath as our backend library for arbitrary precision.
In [ ]:
import sympy as sp
from pyneqsys.symbolic import SymbolicSys
sp.init_printing()
In [ ]:
def f(x):
return [x[0]**2 + x[1],
5*x[0]**2 - 3*x[0] + 2*x[1] - 3]
neqsys = SymbolicSys.from_callback(f, 2)
neqsys.exprs
Let us now find the roots for this system numerically, if we read the documentation of that library we will see that they recommend that the starting guess is obtained using a conventional solver.
So we will do just that: we will first solve the problem using SciPy's default solver and then we will perform a "refinement" by solving it using mpmath's solver
In [ ]:
x, sol = neqsys.solve([100, 100])
sol, f(sol['x'])
In [ ]:
mp_neqsys = SymbolicSys.from_callback(f, 2, module='mpmath')
mp_x, mp_sol = mp_neqsys.solve(x, solver='mpmath', dps=50)
mp_sol, f(mp_sol['x'])
So that gave us, as requested, close to 50 significant digits‒nifty!