Thread: Bisection Method function value at root incorrect

  1. #1
    Registered User
    Join Date
    Nov 2005
    Posts
    5

    Bisection Method function value at root incorrect

    Hello, I have written this code for class that says to find the root of three different functions. I have done this. The root that is returned is correct but when I try to get thefunction value at the root , the output is not what is expected.
    Code:
    v_root = func_1(root);
    This is the only problem with my program I am having. Here is the program in it's entirety. To get the drift of the switch statement, you just need to read the first case and it's cases.

    Code:
     
    /* Program finds the roots of a function using the bisection method */
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    
    /* Function prototypes */
    double func_1(double x);
    double func_2(double x);
    double func_3(double x);
    double bisect(double func(double), double a, double b, double epsilon);
    
    /** Main function */
    int main(void) {
    
      int f_choice, // Choice for user to make on deciding which function to use
          i_choice; // Choice for user to make on deciding which interval to use
      double epsilon, // the error tolerance
          a, // left endpoint
          b, // right endpoint
          root, // the root of the fuction
          v_root; // value of the function with specified root
    
      printf("Which function you want to choose (1, 2, 3): ");
      scanf("%d", & f_choice);
    
     /*Nested switch statment to figure which function and then which interval to use. For each
      * outter-case there are two inner-cases for the interval. After the error tolerance has been
      * recieved from the user the bisection method is invoked then the method to find the value of
      *  of the function at the computed root *************************************************** */
      switch (f_choice) {
        case (1):
          printf("Which interval you want to choose (1, 2): ");
          scanf("%d", & i_choice);
          switch (i_choice) {
            case (1):
              printf("What error is accepted (epsilon): ");
              scanf("%lf", & epsilon);
              a = -1.0;
              b = 0.0;
              root = bisect(func_1, a, b, epsilon);
              printf("The root of the function 1 in the interval 1 is %g\n", root);
              v_root = func_1(root);
              printf("The function value at the root is %g\n", v_root);
              break;
            case (2):
              printf("What error is accepted (epsilon): ");
              scanf("%lf", & epsilon);
              a = 0.0;
              b = 0.5;
              root = bisect(func_1, a, b, epsilon);
              printf("The root of the function 1 in the interval 2 is %g\n", root);
              v_root = func_1(root);
              printf("The function value at the root is %g\n", v_root);
              break;
            default:
              ;
              break;
          }
          break;
        case (2):
          printf("Which interval you want to choose (1, 2): ");
          scanf("%d", & i_choice);
          switch (i_choice) {
            case (1):
              printf("What error is accepted (epsilon): ");
              scanf("%lf", & epsilon);
              a = -4.0;
              b = -2.0;
              root = bisect(func_2, a, b, epsilon);
              printf("The root of the function 2 in the interval 1 is %g\n", root);
              v_root = func_2(root);
              printf("The function value at the root is %g\n", v_root);
              break;
            case (2):
              printf("What error is accepted (epsilon): ");
              scanf("%lf", & epsilon);
              a = 2.0;
              b = 4.0;
              root = bisect(func_2, a, b, epsilon);
              printf("The root of the function 2 in the interval 2 is %g\n", root);
              v_root = func_2(root);
              printf("The function value at the root is %g\n", v_root);
              break;
            default:
              ;
              break;
          }
          break;
        case (3):
          printf("Which interval you want to choose (1, 2): ");
          scanf("%d", & i_choice);
          switch (i_choice) {
            case (1):
              printf("What error is accepted (epsilon): ");
              scanf("%lf", & epsilon);
              a = 0.0;
              b = 1.0;
              root = bisect(func_3, a, b, epsilon);
              printf("The root of the function 3 in the interval 1 is %g\n", root);
              v_root = func_3(root);
              printf("The function value at the root is %g\n", v_root);
              break;
            case (2):
              printf("What error is accepted (epsilon): ");
              scanf("%lf", & epsilon);
              a = 1.0;
              b = 2.0;
              root = bisect(func_3, a, b, epsilon);
              printf("The root of the function 3 in the interval 2 is %g\n", root);
              v_root = func_3(root);
              printf("The function value at the root is %g\n", v_root);
              break;
            default:
              ;
              break;
          }
        default:
          ;
          break;
      }
      return 0;
    }
    
    /** Returns the polynomial 3x^3 - 3x^2 + 2 */
    double func_1(double x) {
      return (3.0 * pow(x, 3.0) - 3.0 * pow(x, 2.0) + 0.2);
    }
    
    /** Returns the polynomial x^4 - 3x^2 - 8 */
    double func_2(double x) {
      return (pow(x, 4.0) - 3.0 * pow(x, 2.0) - 8.0);
    }
    
    /** Returns the trig function 2sin(2x)-3cos(3x) */
    double func_3(double x) {
      return (2.0 * sin(2.0 * x) - 3.0 * cos(3.0 * x));
    }
    
    /** Figures out the root */
    double bisect(double func(double), double a, double b, double epsilon) {
      double f_a = func(a);
      double f_b = func(b);
    
      if (f_a * f_b > 0) {
        return 0;
      }
      else if (f_a == 0) {
        return a;
      }
      else if (f_b == 0) {
        return b;
      }
    
      /* f_a * f_b < 0 */
      double m;
      while ( fabs(b - a) > epsilon) {
        m = (a + b) / 2.0;
        double f_mid = func(m);
    
        /* Replace a or b? */
        if (f_mid == 0.0) {
          break; /* exit while loop */
        }
        else if (f_mid * f_a < 0.0) {
          b = m;
        }
        else
        /* f_mid * f_a < 0.0 */
        {
          a = m;
        }
      }
      return m; // return the value of the new m which is now the root
    }
    I am sorry if it was unneccessary to include the entire code just did not want to leave anything out.
    Last edited by mr_glass; 11-09-2005 at 10:32 AM.

  2. #2
    Super Moderater.
    Join Date
    Jan 2005
    Posts
    374
    What are you expecting. It to be exactly 0. Or closer to zero than what you are getting? You realise it can't be exactly zero due to rounding errors. And it is plausible to get a -0.00002 answer.

    Code:
    /** Returns the polynomial 3x^3 - 3x^2 + 2 */
    double func_1(double x) {
      return (3.0 * pow(x, 3.0) - 3.0 * pow(x, 2.0) + 0.2);
    }
    Should that be 2.0 btw?


  3. #3
    Registered User
    Join Date
    Nov 2005
    Posts
    5
    Quote Originally Posted by treenef
    What are you expecting. It to be exactly 0. Or closer to zero than what you are getting? You realise it can't be exactly zero due to rounding errors. And it is plausible to get a -0.00002 answer.
    No, I'm sorry if I was not clear. I am fine with my results for the zero that I am recieving. The problem comes in when I try to plug the zero back into the equation and get it's value. I am not getting the correct answer.

    Quote Originally Posted by treenef
    Code:
    /** Returns the polynomial 3x^3 - 3x^2 + 2 */
    double func_1(double x) {
      return (3.0 * pow(x, 3.0) - 3.0 * pow(x, 2.0) + 0.2);
    }
    Should that be 2.0 btw?

    And it should be 0.2 the comment is wrong not the equation.

  4. #4
    Super Moderater.
    Join Date
    Jan 2005
    Posts
    374
    Ok now you're confusing me.

    You do realise that to find the roots of the equation:-

    Code:
    3x^3 - 3x^2 + 2
    Would be equivalent of finding an appropriate value of 'x' which satisfies the equation:-

    Code:
    3x^3 - 3x^2 + 2 = 0
    So that if you found x to be -0.63, then if you plug that into the original equation you should be getting a value close to zero.

    i.e.

    Code:
     3(-0.63)^3 - 3(-0.63)^2 + 2 = zero
    This would prove the root is found when x is -0.63 since this is where it cuts the x axis.

    Now if you where to plug '0' into the equation (which is what I think you are suggesting), what do you think you will get:

    Code:
    3(0)^3 - 3(0)^2 +2 = ?
    The answer is of course, nothing useful. Is that any clearer?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Compiling sample DarkGDK Program
    By Phyxashun in forum Game Programming
    Replies: 6
    Last Post: 01-27-2009, 03:07 AM
  2. Callback function as class method
    By schifers in forum Windows Programming
    Replies: 39
    Last Post: 05-19-2008, 03:02 PM
  3. dllimport function not allowed
    By steve1_rm in forum C++ Programming
    Replies: 5
    Last Post: 03-11-2008, 03:33 AM
  4. We Got _DEBUG Errors
    By Tonto in forum Windows Programming
    Replies: 5
    Last Post: 12-22-2006, 05:45 PM
  5. c++ linking problem for x11
    By kron in forum Linux Programming
    Replies: 1
    Last Post: 11-19-2004, 10:18 AM