1. Limited time only! Sign up for a free 30min personal tutor trial with Chegg Tutors
    Dismiss Notice
Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Bisection Method in C

  1. Dec 12, 2011 #1
    Hi guys, I'm doing an assignment for working out a certain root of a given function, x^4+x^3-12x^2-2x+10, to a precision of 10-6. We are asked to give two limits of where we want to find a root between but i'm getting stuck. I was just wondering if any of you could look at my code and maybe point out where i'm going wrong, thanks.

    Here's my code:

    Code (Text):
    #include<stdio.h>
    #include<math.h>

    main()
    {double x1,x2,x,series,series1,d;

    printf("enter x1 and x2\n");
    scanf("%lf%lf",&x1,&x2);

    x=0;

     while(d>0.0001)
        {
          x=(x1+x2)/2;

          series=(pow(x,4))+(pow(x,3))-(12*(pow(x,2))-(2*x)+10);

         series1=(pow(x1,4))+(pow(x1,3))-(12*(pow(x1,2))-(2*x1)+10);

         d=fabs(series);

             if(series*series1 < 0)
                 x2=x;
             else
                 x1=x;
        }

    printf("%lf",x);

    return 0;
    }
     
     
  2. jcsd
  3. Dec 12, 2011 #2

    Borek

    User Avatar

    Staff: Mentor

    d should be not a value of the function, but width of the interval. I have just skimmed your code so could be I missed some other problems related to your bisection algorithm implementation.

    There is one thing that cries I AM INEFFICIENT:

    Never ever use pow() function while calculating value of a polynomial. Use Horner scheme:

    [tex]x^4+x^3-12x^2-2x+10 = x(x(x(x+1)-12)-2)+10[/tex]

    which means replacing

    Code (Text):
    series=(pow(x,4))+(pow(x,3))-(12*(pow(x,2))-(2*x)+10);
    with

    Code (Text):
    series=x*(x*(x*(x+1)-12)-2)+10;
    Also note you don't need parentheses around (12*(pow(x,2)).

    And moving calculation of polynomial to the function external to the main body will make it simpler to modify the program when you will be given another function (right now you have the same code in two different places, it can be in one place only).
     
    Last edited: Dec 13, 2011
  4. Dec 12, 2011 #3

    D H

    User Avatar
    Staff Emeritus
    Science Advisor

    You can't use bisection if the function has the same sign at the initial points x1 and x2. Your function, f(x)=x4+x3-12x2-2x+10 (see note), has a value of 10 at x=0 and a value of 4 at x=3. You should give some kind of error message if the user specifies 0 and 3 as the initial values of x1 and x2.


    Note: As Borek noted, this is better written as x*(x*(x*(x+1)-12)-2)+10 and should be a separate function.
     
  5. Dec 12, 2011 #4
    thank you very much for your help guys, my code is all sorted!
     
  6. Dec 13, 2011 #5
    beweare
    x*(x*(x*x+1)-12)-2)+10 = x^4+x^2-12 x+8

    ...x^4+x^3- 12x^2 -2x + 10 =
    (((1x +1)x - 12)x - 2)x + 10
     
  7. Dec 13, 2011 #6

    Borek

    User Avatar

    Staff: Mentor

    My mistake, DH posted correct formula. Correcting my post.

    For some reason I prefer the x*(x*(x*(x... version.
     
  8. Dec 13, 2011 #7

    D H

    User Avatar
    Staff Emeritus
    Science Advisor

    No, it doesn't. The left hand side isn't even well-formed.

    Looking back, Borek did make that mistake. He also pointed out the name of the representation scheme. It was stated correctly as x*(x*(x*(x+1)-12)-2)+10 in post #3.


    There's no reason for that 1*x. Just write x. (This happens a lot; a polynomial with a leading coefficient of one is a proper, or monic, polynomial.)
    So ((((x+1)x-12)x-2)x+10
    Or 10+(-2+(-12+(1+x)x)x)x
    Or x(x(x(x+1)-12)-2)+10
    They're all the same thing. I like the latter two better than the first, and the last one best. That first one looks a bit inside out to me. But that's just personal preference. All three have the same number of multiplications.
     
  9. Dec 13, 2011 #8
    i prefer
    Code (Text):
    double a[]={ 10, -2, -12, 1, 1};
    const int ord=sizeof(a)/sizeof(a[0]) - 1;
    then
    Code (Text):
    double series(double x){
        int i; double s=a[ord];
        for( i=ord-1; i>=0; i-- )
            s = s*x +a[i];
        return s; }
    we can calculate derivatives, zero of 3-rd is start of bisection
    SFME :-)
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook