C Board  

Go Back   C Board > General Programming Boards > C Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 11-08-2005, 08:26 PM   #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.
mr_glass is offline   Reply With Quote
Old 11-09-2005, 05:10 AM   #2
SSDD
 
Join Date: Jan 2005
Posts: 369
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?

treenef is offline   Reply With Quote
Old 11-09-2005, 10:30 AM   #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.
mr_glass is offline   Reply With Quote
Old 11-10-2005, 09:10 AM   #4
SSDD
 
Join Date: Jan 2005
Posts: 369
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?
treenef is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Forum Jump

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


All times are GMT -6. The time now is 02:36 AM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.0 RC2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22