1
\$\begingroup\$

The following is an implementation of Newton's method of finding root of a function.

using System;
using System.Drawing;
using ZedGraph;

//Newton's Method  
//https://www.youtube.com/watch?v=2GrfaB88w4M&t=350s
//https://stackoverflow.com/questions/12915317/how-to-find-derivative-of-a-function-using-c
//https://www.geeksforgeeks.org/program-for-newton-raphson-method/
namespace _1_22_Newton_Method_of_Root_Finding
{
    public delegate double MyFunction(double x);
    public class RootFinder
    {
        static double EPSILON = 0.01;
        static double h = 1.0e-6;

        public static double Derivative(MyFunction func, double x0)
        {
            double x1 = x0 - h;
            double x2 = x0 + h;
            double y1 = func(x1);
            double y2 = func(x2);
            double der = (y2 - y1) / (x2 - x1);//<==== i am not sure about this.

            return der;
        }

        private static double NextNewton(MyFunction func, double guess)
        {
            return guess - func(guess) / Derivative(func, guess); 
        }

        public static double Newton(MyFunction func, double init)
        {
            double x = init;
            double y = NextNewton(func, x);

            //for(int i=0 ; i < 10 ; i++)
            while(Math.Abs(y) >= EPSILON)
            //while(true)
            {
                y = NextNewton(func, x);

                if (x == y)
                {
                    break;
                }

                Console.WriteLine("Root = {0}", y);
                x = y;
            }

            return y;
        }
    }

Kindly, review the source code.

Does this source code have any pitfall?

\$\endgroup\$
1
\$\begingroup\$

Math.Abs(y) >= EPSILON

I think this condition is only satisfied for roots around zero on the x-axis. Maybe you confuse yourself by naming the next x as y? A better name would be x1.

The actual continue condition should be Math.Abs(x - x1) >= EPSILON and you then can skip the test if (x == y) break;


Your rather large value of EPSILON may result in imprecise roots now and then.


You can clean up the main algorithm to something like:

public static double Newton(MyFunction func, double init)
{
  double x;
  double x1 = init;

  do
  {
    x = x1;
    x1 = NextNewton(func, x);

    Console.WriteLine("Root = {0}", x1);
  } while (Math.Abs(x - x1) >= EPSILON);

  return x1;
}
| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$
double der = (y2 - y1) / (x2 - x1);//<==== i am not sure about this.

You got it right.


The function Derivative can return 0, in which case you'll end up dividing by 0 at the function NextNewton.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.