Area under curve recursive call crashing

I am trying to find a way to estimate the area under the curve of f(x) between 2 points a and b. I evaluate f at the endpoints of the interval, and use them to draw a trapezoid. The area of a trapezoid is the width multiplied by the average height of the legs: A = (b-a) (f(a) + f(b))/2

while this gives me an estimate of the area under the curve, nothing says it has to be a particularly good estimate. As a check, I divide the interval in half, at the midpoint between a and b, evaluate f at the midpoint, and sum the area of the two trapezoids that results. If the sum of the two smaller trapezoids is "close enough" to the area of the one larger trapezoid, we conclude our estimate is pretty good and return the area. Using the tolerance being asked for in the main part as the determining factor on the "Close Enough" part of the program.

It seems to work when you choose a small number such as 2 but when I use what is asked left bound of 0 and right bound of 4 it crashes. :-(

I am trying to use the input of 0 and 4 and tolerance of .1

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <iostream>
#include <cstdlib>

using namespace std;

double f(double x);
double CurveArea(double Tol, double a, double b, double A = 0);
double AbsVal(double Area1, double Area2, double A);

int main()
{
	double Tol, a, b;
	cout << "This is a demonstration of integrating X-cubed + 2" << endl;
	cout << "Enter the left and right limits of integration: ";
	cin >> a >> b;
	cout << "Enter desired error tolerance: ";
	cin >> Tol;
	cout << "The area is approximately " << CurveArea(Tol, a, b) << endl;

	return 0;
}

double f(double x)
{
	return (x * x * x) + 2;
}

double AbsVal(double Area1, double Area2, double A)
{
	if((Area1 + Area2) - A <= 0)
		return (((Area1 + Area2) - A) * -1);
	else 
		return ((Area1 + Area2) - A);
}

double CurveArea(double Tol, double a, double b, double A)
{
	double Area1, Area2;
	Area1 = (b-(a + b / 2)) * (f((a + b / 2)) +  f(b))/2;
	Area2 = ((a + b / 2)-a) * (f(a) +  f((a + b / 2)))/2;

	if(AbsVal(Area1, Area2, A) <= Tol)
	{
		return (Area1 + Area2);
	}
	else
	{
		return (CurveArea(Tol, a, (a + b / 2), Area1) + 
				CurveArea(Tol, (a + b / 2), b, Area2));
	}
}


Thank you all for your help :-)
Last edited on
When I was testing your program, I received an error for overflow on my stack. The function CurveArea executed infinitely, but I read your code and do not see anything really wrong. So, I decided to test those values you tried.... For some odd reason Tol != 0.1 it was instead == 0.10000000000000001 Maybe try just rounding the end off? I do not think anybody want an estimation beyond the fifth or sixth decimal place.
I can see where that might be causing some problems, I will try that out. Thank you for your input.

Tried that also. For some reason it is going in an infinite loop. There is somewhere in the program where the stopping case isnt being triggered. Still attempting to find the solution. >.<

I changed all the values to float but it didnt help
Last edited on
Omg I figured it out...FFS it just clicked....I looked at the value storage of area1 and area2 and noticed that area2 was 12 and area 1 was 76 through the first iteration...I was setting the coding up so that area1 was supposed to be the left side of the trapazoid...but I had mixed up which triangle was going where
1
2
Area1 = (b-(a + b / 2)) * (f((a + b / 2)) +  f(b))/2;
	Area2 = ((a + b / 2)-a) * (f(a) +  f((a + b / 2)))/2;


this is saying that area one should be on the right side of the division and area2 on the left side..I switched them around to

1
2
Area2 = (b-(a + b / 2)) * (f((a + b / 2)) +  f(b))/2;
	Area1 = ((a + b / 2)-a) * (f(a) +  f((a + b / 2)))/2;


I looked at the function on a graphic calculator and noticed area2 should be much larger than area1...now it runs PERFECTLY ^_^. Thank you for getting me thinking about looking at the numbers being stored Kevinkjt2000. It sparked the help


I broke it DANGIT
Last edited on
Actually I just threw that out and decided to go with my instincts on the area under the curve process...seems to be working much better...Remember always think about the problem in your own way rather than someone else telling you what should be there.

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <iostream>
#include <cstdlib>
#include <cmath>

using namespace std;

double f(double x);
double CurveArea(double Tol, double a, double b);
double AbsVal(double Area1, double Area2, double A);
double Trapezoid(double a, double b, int N);

int main()
{
	double a, b;
	double Tol;
	cout << "This is a demonstration of integrating X-cubed + 2" << endl;
	cout << "Enter the left and right limits of integration: ";
	cin >> a >> b;
	cout << "Enter desired error tolerance: ";
	cin >> Tol;
	cout << "The area is approximately " << CurveArea(Tol, a, b) << endl;

	return 0;
}

double f(double x)
{
	return (x * x * x) + 2;
}

double AbsVal(double Area, double PrevArea)
{
	if(Area - PrevArea <= 0)
		return ((Area - PrevArea) * -1);
	else 
		return (Area - PrevArea);
}

double Trapezoid(double a, double b, int N) 
{
	double h = (b - a) / N;
	double Sum = 0.5 * h * (f(a) + f(b));
	for (int k = 1; k < N; k++)
		Sum = Sum + h * f(a + h*k);
	return Sum;
}

double CurveArea(double Tol, double a, double b) 
{
	double Area = Trapezoid(a, b, 10);
	double PreviousArea = Trapezoid(a, b, 5);
	if (AbsVal(Area, PreviousArea) > Tol) 
	{
		double divided = (a + b) / 2;
		Area = CurveArea(Tol, a, divided) + CurveArea(Tol, divided, b);
	}
	return Area;
}
Topic archived. No new replies allowed.