| tags |
|
|
|---|---|---|
| e_maxx_link | roots_newton |
This is an iterative method invented by Isaac Newton around 1664. However, this method is also sometimes called the Raphson method, since Raphson invented the same algorithm a few years after Newton, but his article was published much earlier.
The task is as follows. Given the following equation:
We want to solve the equation. More precisely, we want to find one of its roots (it is assumed that the root exists). It is assumed that
The input parameters of the algorithm consist of not only the function
Suppose we have already calculated
It is not difficult to obtain the following formula,
First, we calculate the slope
The tangent intersects with the x-axis at cordinate,
Now, solving the equation we get the value of
It is intuitively clear that if the function
The rate of convergence is quadratic, which, conditionally speaking, means that the number of exact digits in the approximate value
Let's use the calculation of square root as an example of Newton's method.
If we substitute
The first typical variant of the problem is when a rational number eps:
double sqrt_newton(double n) {
const double eps = 1E-15;
double x = 1;
for (;;) {
double nx = (x + n / x) / 2;
if (abs(x - nx) < eps)
break;
x = nx;
}
return x;
}Another common variant of the problem is when we need to calculate the integer root (for the given
int isqrt_newton(int n) {
int x = 1;
bool decreased = false;
for (;;) {
int nx = (x + n / x) >> 1;
if (x == nx || nx > x && decreased)
break;
decreased = nx < x;
x = nx;
}
return x;
}Finally, we are given the third variant - for the case of bignum arithmetic. Since the number
public static BigInteger isqrtNewton(BigInteger n) {
BigInteger a = BigInteger.ONE.shiftLeft(n.bitLength() / 2);
boolean p_dec = false;
for (;;) {
BigInteger b = n.divide(a).add(a).shiftRight(1);
if (a.compareTo(b) == 0 || a.compareTo(b) < 0 && p_dec)
break;
p_dec = a.compareTo(b) > 0;
a = b;
}
return a;
}For example, this code is executed in
