Help with Integration function

Pages: 123
If you look at the code that I posted in response to this original question, you should find all of the information you need (from a working, validated program). Granted, what I supplied uses the trapezoidal method for one particular f(x), but you can see in the code (as well as the comments) how you can make it work to include the rest of your criteria.
Yes that is true but the fact is I don't understand what I have already. I just need to know what I need to put into my

double trap_integral
and
double rect_integral

and what I mean by that is the calculation. I don't see them in the assignment you posted because my code is different. I am sorry I just cant tell.
It looks as though aperio has provided example code which can be used as a guide.
What I would advise at this stage is to get the program working for a simplified version. Concentrate on getting the program to work for
• just one of the functions
• just for the trapezoid method.

The example code uses the same starting point, that is, the values a, b and n.
There is this line:
 
    delta = (b - a)/n; //takes the inputs and determines the width of each 'slice' 

which is done before calling the function check_f1()

You can either follow the same idea, and modify function trap_integral() to use the parameter delta, or alternatively, carry out that step inside the function instead.

One difference is that example function check_f1() uses a cout statement to display the result, and doesn't return any value. It could be modified to instead return the result.
If I were to modify function trap_integral() what would it look like? The information provided by aperio makes sense in that code but I am not sure how to make it work with my code. It is hard to compare both for me and see what I have and don't have. I think I just need to put the calculation for both integrals at the end of my code but the problem is I have no idea what those calculations of code are. If I know what they are I can put them in.
I'm not sure I understand what it is that's holding you back. The only guidance you are giving is of the form "I have no idea" or similar. While I sympathise with your situation, it's very difficult to provide assistance unless your questions are more specific.

The only thing I can really suggest is that you have a go, put some sort of code together and then we'll see what remains to be done.
I am sorry my questions have not been very specific. Let me try again.

I have put in a random equation into:
1
2
3
4
double rect_integral(double a, double b, int n, int choice)
{
    // here insert the code to calculate the integral
    return 1.0; // dummy value 


The program ran and returned a number that was correct for that calculation. Now I need to find the right equation to calculate the integral of a rectangle. But the problem is I do not know what that equation is. I do not have a problem with the code, it is the equations for:

double rect_integral(double a, double b, int n, int choice)

double trap_integral(double a, double b, int n, int choice)

I am having trouble with.
Well, it's not a single equation. If it was, the result could be calculated in just one line of code.

We know the area of a rectangle is base * height

The area of a trapezoid is similar, but there are two heights (left and right edges), so we take the average. Thus area = (height1 + height2)/2 * base

Those are the basic building blocks. What we need to do is to add up the total area of several rectangles (or several trapezoids).

Let's take an example.
Assume the function is the first one, 5x^4 + 3x^3 - 10x + 2
Lets say the user has input
a = 1
b = 2
n = 3
(Ignore choice for now, we can come back to that later)

So we split the region between a and b into three (that is n) slices.
first trapezoid
The first one has
x_left = 1
x_right = 1.33333

The two heights are calculated by calling the function fx with these values of x.
height_left = 0
height_right = 11.58
base = 0.33333
area = (height_left + height_right) / 2 * base
=1.93
Now we add that value to the total area

second trapezoid
Now we repeat the process
x_left = 1.33333
x_right = 1.66667

height_left = 11.58
height_right = 37.80
base = 0.33333
area = (height_left + height_right) / 2 * base
=8.23
add that to the total area

third trapezoid
x_left = 1.66667
x_right = 2

height_left = 37.80
height_right = 86
base = 0.33333
area = (height_left + height_right) / 2 * base
=20.63

again, add that to the total area.

Result
The result in this case is 1.93 + 8.23 + 20.63 which is 30.79
The proper answer is 29.25, but remember this is just an approximation. Using a bigger value of n will give a better answer.

So, that's a description (probably a confusing one) of how to get the area using trapezoids.

How to turn it into code?

Well, start with a variable which will contain the total, set it to zero.
Calculate the width of each slice ("base" in my example above) as (b-a)/n

Then we need a loop. Usually a for loop.
Something like
1
2
3
4
for (int i=0; i<n; i++)
{

}

Inside the loop we calculate the area of a single trapezoid and add it to the total.

When the loop finishes, the total area is the value to be returned from the function.

No this does help a lot! It got me to start something.

I have this so far:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
double rect_integral(double a, double b, int n, int choice)
{
     double area;
     int i;

     area+(b-a)/n;
      n=0;

          for(i=1; i<=n; i++) {
          area += (a + b*(i-0.5));
          }
return area;

}


What do I need to add to this for it to work right?
Well, it needs to call the function, let's say func_1 () for now.
Once it works for one function, it can be modified fairly easily to deal with the others.

Line 6, area+(b-a)/n; is just a passive expression, it doesn't do anything.

Setting n equal to zero on line 7 seems like it's done for no good reason. It will prevent the loop at line 9 from working.
Last edited on
sorry I meant area=(b-a)/n;

where should I call the function at?
The function is called inside the loop.

The function is called to get the height of each rectangle, so you call it with a different value of x each time.

x starts at 'a'
Each time around the loop, x increases by an amount equal to the width of each "slice". The width is a fixed amount equal to (b-a)/n
okay so I see that it needs to be in the loop. So it needs to be called two times? for a and b?
In the rectangle version, it needs to be called once.
I have

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
double rect_integral(double a, double b, int n, int choice)
{
     double area;
     int i;

     area+(b-a)/n;
      n=0;

          for(i=1; i<=n; i++) {
          area += (a + b*(i-0.5));
          choice;
          }
return area;

}


and it doesnt work.
Choice; is the function I choose.
Well, there are several things to consider here.

Let's describe what needs to be done in function rect_integral()

1. define a variable to store the total area
2. set the total area to zero.
3. calculate the width of each rectangle = (b-a)/n
4. set the initial value of x equal to a
5. repeat n times
    5.1 calculate the height by calling the function func_1() using the current x value
    5.2 calculate the area as height * width
    5.3 add the area to the total area
    5.4 calculate the next value of x by adding width to the current x value
6. return total area as the result


Items in bold are suggested variables.

Note, mathematically the area of the rectangle may be calculated using the value of the function at its left or right edge. One will give an over-estimate, the other an under-estimate. You may get a more accurate result by using the mid-point. Do that by setting the initial value of x to be a + width/2. However, consider that as a refinement for later consideration.
Last edited on
Possible ways to call the chosen function.

One, using switch-case.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    double height;

    switch (choice)
    {
        case 1:
            height = func_1(x);
            break;
           
        case 2:
            height = func_2(x);
            break;
           
        case 3:
            height = func_3(x);
            break;
           
        case 4:
            height = func_4(x);
            break;
           
        case 5:
            height = func_5(x);
            break;
        }



Two, using a function pointer.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    double (* fx) (double);
    
    switch (choice)
    {
        case 1: fx = func_1; break;
        case 2: fx = func_2; break;
        case 3: fx = func_3; break;
        case 4: fx = func_4; break;
        case 5: fx = func_5; break;
    }
    
    double height;

    height = fx(x);


The second one is probably more efficient, and tidier, as the switch-case needs to be executed just once. The first requires switch-case to be used inside the loop.


There may be other and better ways, these are just the ones which come to mind at the moment.
Do I put the second one in the function rect_integral?
That would work. Put lines 1-10 at the beginning.
Lines 12 and 14 go inside the loop.

okay makes sense. First of all thank you for all of you help, I know this is probably tedious.

Okay so now I have this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
double rect_integral(double a, double b, int n, int choice)
{

double (* fx) (double);

switch (choice)
{
 case 1: fx = func_1; break;
        case 2: fx = func_2; break;
        case 3: fx = func_3; break;
        case 4: fx = func_4; break;
        case 5: fx = func_5; break;
}

double height;
double x;
double total_area;
double width;
double area;

area = height * width;
width = (b-a)/n;
total_area = 0;
height = fx(x);

return total_area;

}


Now this code compiles but I am having trouble with #5 of the options you gave me so I think that is the step I need to do now. How exactly should I do step 5?
What you have so far looks to be heading in the right direction.
However, lines 21 and 24 don't quite belong there.

Also, going back to my earlier post, step 4 is missing:

4. set the initial value of x equal to a


Step 5 means, write a for-loop (which you already know how to do).
Steps 5.1 to 5.4 fit inside the loop.

I'm trying to describe this in terms of what the program is trying to achieve, rather than in terms of C++, because it's important to understand what the code is actually doing. Each step I've listed should probably translate into one line of code.
Last edited on
Pages: 123