/// This bisection method returns the best double approximation
 /// to a root of F.f.  Returns double.NaN if the F.f(a)*F.f(b) > 0.
 public static double Bisection(Function F, double a, double b)
 {
     if (F.f(a) == 0) {
     return a;
      }
      if (F.f(b) == 0) {
     return b;
      }
      if (Math.Sign(F.f (b)) == Math.Sign (F.f (a))) { //or F.f(a)*F.f(b)>0
     return double.NaN;
      }
      double c = (a + b) / 2;
      // If no f(c) is exactly 0, iterate until the smallest possible
      // double interval, when there is no distinct double midpoint.
      while (c != a && c != b) {
     Console.WriteLine ("a = {0}  b= {1}", a, b);
     if (F.f(c) == 0) {
        return c;
     }
     if (Math.Sign(F.f (c)) == Math.Sign (F.f (a)))
        a = c;
     else
        b = c;
     c = (a + b) / 2;
      }
      return c;
 }
        /// This is the basic bisection method.
        /// Ported straight from http://en.wikipedia.org/wiki/Bisection_method.
        /// Source: Burden, Richard L.; Faires, J. Douglas (1985), 
        ///   "2.1 The Bisection Algorithm",
        /// Numerical Analysis (3rd ed.), PWS Publishers
        public static double Bisection(Function F, double a, double b, 
                                     double tolerance, int iterations)
        {
            // check the preconditions for the method to work

             // a must be greater than b so we can do the interval search
             if (a >= b)
            return double.NaN;
             Console.WriteLine ("a >= b ok");
             bool ok = false;

             // The function must cross the x-axis between the endpoints,
             //   meaning its sign changes.
             if ((F.f(a) < 0 && F.f (b) > 0)) {
            Console.WriteLine ("Test 1 passed");
            ok = true;
             }
             if ((F.f(a) > 0 && F.f (b) < 0)) {
            Console.WriteLine ("Test 2 passed");
            ok = true;
             }
             if (!ok)
            return double.NaN;
             int n=0;
             while (n < iterations) {
            double c = (a + b) / 2;
            Console.WriteLine ("a = {0}  b={1}", a, b);
            if (F.f(c) == 0 || (b - a)/2 < tolerance)
               return c;
            if (Math.Sign(F.f (c)) == Math.Sign (F.f (a)))
               a = c;
            else
               b = c;
            n = n+1;

             }
             return double.NaN;
        }