Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Bisection c++ problem

  1. Sep 24, 2012 #1
    Code (Text):
    #include <iostream>
    #include <cstdlib>
    #include <cmath>
    using std::cout;
    using std::endl;
    using std::cin;

    int main()
     {
        double h,v,w,z,y;
       
        cout << "Enter the width, W: ";
        cin >> w;
       
            if (w<0)
            {
                cout << "Error: The Width must be strictly positive." << endl;
                return EXIT_FAILURE;
            }
       
        cout << "Enter the height, H: ";
        cin >> h;
       
            if (h<0)
            {
                cout << "Error: The Height must be strictly positive." << endl;
                return EXIT_FAILURE;
            }
       
       
        x=(6*x*x)+(x(-2h-2w))+((h*w)/2); // is this my x?
       
        y=((w/2)-x);
        z=(h-2x);
        v=(2*x*x*x)-(h*x*x)-(w*x*x)+((h*w)/2)
       
       
        return EXIT_SUCCESS;
     }
     
    That's all I got so far we have to do this:
    Suppose you want to build a covered box by cutting sections out of a W by H sheet of
    cardboard (in meters) and folding as shown in the figure below (cutout the shaded regions
    and fold on the dotted lines).

    https://dl.dropbox.com/u/28097097/image.jpg [Broken]


    Derive an expression for the volume, V , of the box and analytically compute its derivative
    as a function of x.

    Write a program to find the roots of your derivative and so find the dimension for x (and
    by extension y, and z) that maximizes the volume. Your program should read the values
    of W and H from standard input after providing an appropriate prompt, find the maximal
    volume, then print the maximal volume and the maximizing dimensions x, y, and z. Your
    program should automatically determine the allowed range of values for the dimensions given
    W and H (note some care is needed when they are equal). Use a constant tolerance of 0:01
    meters for the convergence criteria in the bisection.
    I've already found the derivative, which is in my code, but I really don't understand bisection that much and how I get the ranges using bisection . I can do the rest after that point, but the bisection just has me stuck.

    Basically I'm lost in what am I suppose to set equal to x, so I could get the rest of the equations to work.
     
    Last edited by a moderator: May 6, 2017
  2. jcsd
  3. Sep 24, 2012 #2
    Hints:

    Bisection almost always looks for x such that f(x)=0 where you know xlow and xhigh such that the sign of f(xlow) is the opposite of the sign of f(xhigh) and you know the function is continuous between xlow and xhigh. Often you can pick values for xlow and xhigh to make all this work.

    Or said another way, if you know your function has no "jumps" and it is positive when x=5 and negative when x=2 then there must be some place where it crosses the x axis and equals zero. Bisection will repeatedly divide the interval in half, look at the sign of f at that point and decide which half to work on next, the half where the sign still changes between the end and the middle.

    Now your diagram has x,y,z,h,w and that is too many variables. But you are probably given constants for some of those. The rest cannot all be anything you want, if you pick a value for some of them then the rest are forced to be some value. So try to decide which variable you want to use and see if you can express the whole problem in terms of that variable alone.

    Is that enough to get you started?
     
  4. Sep 24, 2012 #3
    I think I got it, but I'm not sure... The only problems I can see is if the compiler get's confused with what is what for my while and if statements.
    I also set the functions bounds to be constant.
    Code (Text):
    #include <iostream>
    #include <cstdlib>
    #include <cmath>
    using std::cout;
    using std::endl;
    using std::cin;

    int main()
     {
        double a,b,c,h,v,w,x,y,z, tolerance;
        tolerance=0.01;
       
        cout << "Enter the width, W: ";
        cin >> w;
       
            if (w<0)
            {
                cout << "Error: The Width must be strictly positive." << endl;
                return EXIT_FAILURE;
            }
       
        cout << "Enter the height, H: ";
        cin >> h;
       
            if (h<0)
            {
                cout << "Error: The Height must be strictly positive." << endl;
                return EXIT_FAILURE;
            }
       
        a=0;
        b=(w/2);
        c=((a+b)/2);
       
            while (abs(a-b)>=tolerance)
            {
                if ((w>=0) && (h>=0) && (a>=0))
                {
                    if ((w<=0) && (h<=0) && (c<=0))
                    {
                    b=c;
                    }
                else
                 {
                    if ((w>=0) && (h>=0) && (c>=0))
                    if ((w<=0) && (h<=0) && (b<=0))
                    a=c;
                    c=((a+b)/2);
                 }
                }
            break;
            }
        x=c;
       
        // x=(6*x*x)+(x(-2h-2w))+((h*w)/2); // did I need this derivative of the function?
        y=((w/2)-x);
        z=(h-(2*x));
        v=(2*x*x*x)-(h*x*x)-(w*x*x)+((h*w)/2)
       
        cout << "x= " << x << endl;
        cout << "y= " << y << endl;
        cout << "z= " << z << endl;
        cout << "v= " << v << endl;

        return EXIT_SUCCESS;
     }
     
    I can't test it because when I try to compile I get this error
    "line(59) : error C2146: syntax error : missing ';' before identifier 'cout'


    Also what would I need to make it look "cleaner"?
     
    Last edited: Sep 24, 2012
  5. Sep 24, 2012 #4
    "error on nn" often means look at line n-1 for the real error.

    I think if you count the lines you will see exactly where the error is.

    In fifty years error messages from compilers still don't seem to be
    "<---are you sure you didn't mean to put a semicolon right there?!?"

    Next, you demand w and h be positive or you bail out. And you never again change w or h.
    But you then test w and h for being positive every time inside your while loop. Why?
    And then you test w and h for being negative every time inside your while loop. Why?

    In general, look at each statement and think "why am I doing this, why is this essential, and is this correct?"

    Check each of those if's and see if they "make sense."
     
    Last edited: Sep 24, 2012
  6. Sep 24, 2012 #5
    could you please clarify a bit more I'm still kinda lost.

    Also I feel as if the program is working, but it isn't checking my tolerance value of 0.01/ making sure that the difference of a and be is not more then 0.01 of each other. Because when I run the program I get values, but they're off by a bit.
     
    Last edited: Sep 24, 2012
  7. Sep 25, 2012 #6
    Three lines from the second version of your program

    if ((w>=0) && (h>=0) && (a>=0))

    can that if() ever ever be false?

    and

    if ((w<=0) && (h<=0) && (c<=0))

    can that if() ever ever be true?

    and

    if ((w<=0) && (h<=0) && (b<=0))

    can that if() ever ever be true?

    I suppose it is possible that you are trying to be extremely careful and after you have already determined that a variable is positive you are again checking to see if it might have somehow become negative. If you are doing that on purpose maybe that is ok. But if you are not doing that on purpose then those three lines make me worry.

    Even more, the second if() really worries me because usually bisection has something like

    if this case
    then b=c
    else a=c

    and if your if() can never be true then it seems like one of your two endpoints is going to get stuck.

    Next, I'm really worried that you don't seem to be using your derivative anywhere. c just keeps getting set to the middle of a and b, but there isn't any f(c) which tells me whether your value in the middle is positive or negative.

    Perhaps you can try working on a simpler function to begin with.

    Use the same code with just a few modifications and find where y=3x-1 crosses the x axis when you start with a=0 (and 3*0-1 is definitely negative) and b=1 (and 3*1-1 is definitely positive). See if you can find exactly where 3x-1=0 using your bisection code.
     
  8. Sep 25, 2012 #7
    I think I got what you meant. The program works, but the precision and accuracy is still off and I don't know why. Can anyone see where I go wrong?

    Code (Text):
    #include <iostream>
    #include <cstdlib>
    #include <cmath>
    using std::cout;
    using std::endl;
    using std::cin;

    int main()
     {
        double a,b,c,h,v,w,x,y,z,tolerance,series,series1;
        tolerance=0.01;
       
        cout << "Enter the width, W: ";
        cin >> w;
       
            if (w<0)
            {
                cout << "Error: The Width must be strictly positive." << endl;
                return EXIT_FAILURE;
            }
       
        cout << "Enter the height, H: ";
        cin >> h;
       
            if (h<0)
            {
                cout << "Error: The Height must be strictly positive." << endl;
                return EXIT_FAILURE;
            }
       
        a=0;
        b=(w/2);

            while ((fabs(a-b))>=tolerance)
            {
                c=((a+b)/2);
                x=c;
               
                series=(6*x*x)+(x*((-2*h)-(2*w)))+((h*w)/2);
                series1=(6*x*x)+(x*((-2*h)-(2*w)))+((h*w)/2);
               
                if((series*series1)<0.0)
                {
                    b=c;
                }
                else
                {
                    a=c;
                }
            }
        x=c;
        // x=(6*x*x)+(x((-2*h)-(2*w)))+((h*w)/2);
        y=((w/2)-x);
        z=(h-(2*x));
        v=((2*x*x*x)-(h*x*x)-(w*x*x)+((h*w)/2));
       
        cout << "x= " << x << endl;
        cout << "y= " << y << endl;
        cout << "z= " << z << endl;
        cout << "v= " << v << endl;

        return EXIT_SUCCESS;
     }
     
     
  9. Sep 25, 2012 #8
    I do not see that you are keeping track of whether each endpoint is positive or negative and whether the centerpoint is positive or negative and then using that information to decide which endpoint to move.

    Your series1*series seems like that will be series squared and is anything squared always positive or negative, well except for the special case where it is zero?

    But you are listening to feedback and making progress, which is a very good sign.
    And your program is getting simpler, which is usually a good sign.

    Think about this simple example.
    My function is y=3*x-1.
    My leftend is x=0.
    My rightend is x=1.
    3*leftend-1=-1 and negative.
    3*rightend-1=2 and positive.
    center is 3*1/2-1=1/2 and positive.

    So I either want to move the leftend or the rightend to keep a positive and a negative value at the ends. Which end do I move?

    Then I start this process all over again.

    Try doing this manually a few times and see how the leftend and rightend get closer and closer to each other, but always have a positive and negative value for my function at those ends.

    Then see if your code also does this. Perhaps adding some print statements so you can watch to see if it is doing this same thing might help you
     
  10. Sep 25, 2012 #9

    Mark44

    Staff: Mentor

    I redid the indentation of your if statements and while loop. The usual practice is to indent the body of a loop or if statement, not the entire loop or if statement.

    Indentation is generally a good thing, as it enables a reader to see at a glance the structure of your program, but misleading indentation conveys the wrong idea. Besides, if there is too much indentation, a reader has to scroll over to see a line that extends too far to the right.

    The basic idea of indentation is to show visually which statements execute in sequence. The top lines of loops and if statements operate in sequence with whatever line of code precedes them. The bodies of loops and if statements, etc. break this sequential flow.
     
  11. Sep 25, 2012 #10
    Code (Text):
    #include <iostream>
    #include <cstdlib>
    #include <cmath>
    using std::cout;
    using std::endl;
    using std::cin;

    int main()
     {
        double a,b,c,h,v,w,x,y,z,tolerance,series,series1;
        tolerance=0.01;
       
        cout << "Enter the width, W: ";
        cin >> w;
       
        if (w<0)
        {
           cout << "Error: The Width must be strictly positive." << endl;
           return EXIT_FAILURE;
        }
       
        cout << "Enter the height, H: ";
        cin >> h;
       
        if (h<0)
        {
           cout << "Error: The Height must be strictly positive." << endl;
           return EXIT_FAILURE;
        }
       
        a=0;
        b=(w/2);

        while ((fabs(a-b))>=tolerance)
        {
           c=((a+b)/2);
           x=c;
               
           series=(6*x*x)+(x*((-2*h)-(2*w)))+((h*w)/2);
           // series1=(6*x*x)+(x*((-2*h)-(2*w)))+((h*w)/2);
               
           if((series)<0.0)
           {
            b=c;
           }
           else
           {
            a=c;
           }
        }
        x=c;
        // x=(6*x*x)+(x((-2*h)-(2*w)))+((h*w)/2);
        y=((w/2)-x);
        z=(h-(2*x));
        v=((2*x*x*x)-(h*x*x)-(w*x*x)+((h*w)/2));
       
        cout << "x= " << x << endl;
        cout << "y= " << y << endl;
        cout << "z= " << z << endl;
        cout << "v= " << v << endl;

        return EXIT_SUCCESS;
     }
     
    I took out the part you were talking about and this is what I got for my values:
    Code (Text):

    Enter the width, W: 2
    Enter the height, H: 2
    x= 0.335938
    y= 0.664063
    z= 1.32813
    v= 1.62441
     
    but these are the actual values I should get:
    Code (Text):

    Enter the width, W: 2
    Enter the height, H: 2
    x = 0.331998
    y = 0.668002
    z = 1.336
    V = 0.296293
     
    My x value is still off, which throws off the rest of my values, but I don't know why.
     
  12. Sep 25, 2012 #11
    Code (Text):
    #include <iostream>
    #include <cstdlib>
    #include <cmath>
    using std::cout;
    using std::endl;
    using std::cin;

    int main()
     {
        double a,b,c,h,v,w,x,y,z,tolerance,series,series1;
        tolerance=0.01;
       
        cout << "Enter the width, W: ";
        cin >> w;
       
        if (w<0)
        {
           cout << "Error: The Width must be strictly positive." << endl;
           return EXIT_FAILURE;
        }
       
        cout << "Enter the height, H: ";
        cin >> h;
       
        if (h<0)
        {
           cout << "Error: The Height must be strictly positive." << endl;
           return EXIT_FAILURE;
        }
       
        a=0;
        b=(w/2);

        while ((fabs(a-b))>=tolerance)
        {
           c=((a+b)/2);
           x=c;
               
           series=(6*x*x)+(x*((-2*h)-(2*w)))+((h*w)/2);
               
           if((series)<0.0)
           {
            b=c;
           }
           else
           {
            a=c;
           }
        }
        x=c;
        y=((w/2)-x);
        z=(h-(2*x));
        v=(x*y*z);
       
        cout << "x= " << x << endl;
        cout << "y= " << y << endl;
        cout << "z= " << z << endl;
        cout << "v= " << v << endl;

        return EXIT_SUCCESS;
     }
     
    The code works... Finally! thanks for all the help. I was told my values would come out a bit different due to how each computer processes the information.
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook




Similar Discussions: Bisection c++ problem
  1. A C problem (Replies: 3)

  2. C++ problem (Replies: 11)

  3. Problems in C++ (Replies: 5)

  4. A problem with C (Replies: 4)

  5. Bisection problem c++ (Replies: 23)

Loading...