-
Notifications
You must be signed in to change notification settings - Fork 1
Initial Estimate
In many instances, known brackets for a root are not tight, but an initial estimate for the root may be known. For example, if many similar equations must be solved in sequence, it may be possible to estimate each solution by the previous solution.
solver(f, x1, x2, x=initial_estimate)The super square root of a is given by the solution to the equation
xx = a, where a ≥ e-1/e and x ≥ 1/e
It is simple enough to bound the solution by 1/e and a. An estimate of the solution may be given by log( 1 + a ).
from math import e as E
from math import log
from pyroot import solver
inf = float("inf")
def ssqrt(a):
def f(x):
try:
return x ** x - a
except OverflowError:
return inf
return solver(f, 1 / E, a, x=log(1+a))
for i in range(1, 10):
print(f"ssqrt(1e{i}) = {ssqrt(10.0 ** i)}")Out:
ssqrt(1e1) = 2.5061841455887692
ssqrt(1e2) = 3.597285023540418
ssqrt(1e3) = 4.555535705195128
ssqrt(1e4) = 5.4385826960183055
ssqrt(1e5) = 6.270919555562045
ssqrt(1e6) = 7.065796728299621
ssqrt(1e7) = 7.831389511591177
ssqrt(1e8) = 8.573184508037382
ssqrt(1e9) = 9.29508690037622
The Bring radical of a is given by the root of the following function:
f ( x ) = x5 + x + a
The unique root may be easily bounded by 0 and -a. An initial estimate of -a1/5 may be used when | a | > 1, otherwise an initial estimate of a5 - a may be used.
Note that f ( x ) is written using Horner's method. This is useful to ensure evaluation at infinite is accurate.
from pyroot import sign, solver
def bring_radical(a):
def f(x):
return (x*x*x*x + 1) * x + a
if abs(a) > 1:
x = -sign(a) * abs(a) ** 0.2
else:
x = (a*a*a*a - 1) * a
return solver(f, 0, -a, x=x)
print(bring_radical(3))Out:
-1.1329975658850653