Newton raphson in C

I implemented the Newton raphson algorithm for finding roots in C. I want to infer the most accurate approximation of the root without going into the nano of the earth. My strategy for this is while (!(isnan(x0)) { dostuff(); } But this continues to print the result several times. Ideally, I would like to adjust the range so that the difference between each computed x capture approximation stops when the previous one is current is less than a certain range of .000001 in my case. I have a possible implementation below. When I enter 2.999 Only one step is required, but when I enter 3.0, it takes 20 steps, it seems to me wrong.

(When I enter 3.0)

  λ newton_raphson 3
 2,500,000
 2.250000
 2.125000
 2.062500
 2.031250
 2.015625
 2.007812
 2.003906
 2.001953
 2.000977
 2.000488
 2.000244
 2.000122
 2.000061
 2.000031
 2.000015
 2.000008
 2.000004
 2.000002
 2.000001
 Took 20 operation (s) to approximate a proper root of 2.000002
 within a range of 0.000001

(When I enter 2.999)

  λ newton_raphson 2.999
 Took 1 operation (s) to approximate a proper root of 2.000000
 within a range of 0.000001

My code is:

 #include <stdio.h> #include <stdlib.h> #include <math.h> #define RANGE 0.000001 double absolute(double number) { if (number < 0) return -number; else return number; } double newton_raphson(double (*func)(double), double (*derivative)(double), double x0){ int count; double temp; count = 0; while (!isnan(x0)) { temp = x0; x0 = (x0 - (func(x0)/derivative(x0))); if (!isnan(x0)) printf("%f\n", x0); count++; if (absolute(temp - x0) < RANGE && count > 1) break; } printf("Took %d operation(s) to approximate a proper root of %6f\nwithin a range of 0.000001\n", count, temp); return x0; } /* (x-2)^2 */ double func(double x){ return pow(x-2.0, 2.0); } /* 2x-4 */ double derivative(double x){ return 2.0*x - 4.0; } int main(int argc, char ** argv) { double x0 = atof(argv[1]); double (*funcPtr)(double) = &func; /* this is a user defined function */ double (*derivativePtr)(double) = &derivative; /* this is the derivative of that function */ double result = newton_raphson(funcPtr, derivativePtr, x0); return 0; } 
+4
source share
2 answers

You call trunc(x0) , which turns 2.999 into 2.0 . Naturally, when you start with the correct answer, no iteration is required! In other words, although you used 2.999 as your starting value, you actually used 2.0 .

Just remove the trunc() call.

+2
source

It is worth noting: taking 20 steps to converge is also abnormal; because you converge to several roots, the convergence is linear, not the typical quadratic convergence that Newton-Raphson gives in the general case. You can see this in the fact that your error is halved with each iteration (with normal quadratic convergence, you will get twice as many correct digits at each iteration and converge much faster).

+1
source

Source: https://habr.com/ru/post/1445805/


All Articles