# computer math using C++



## HAJ (Mar 12, 2003)

how can i find the area bounded between two giving points of a graph and the x-axis using C++


----------



## AlbertB (Nov 24, 2002)

Hi HAJ,

I am not quite sure of the setup of your problem, but if you are simply taking points (X,Y), (I am using Capitals to denote the numeric values of a specific point under test, smallcase to denote the general term as in; y = f(x) the general statement of your function, Y = f(X) the value of y specifically at the point where x = X), to test for inclusion in the area under the curve, you could test for X and Y separately in nested if statements, X first as it is usually the simpler. The conditions are for the most part obvious.

as we have y = f(x), setting your test to
y < f(x) for +ve y, ie curve above the x-axis, or
y > f(x) for -ve y, ie curve below the x-axis,
will filter your y values.

For a point to be included it must fulfil all of the following, (see note at the end re possibility of = ) :

x > lower limit
x < upper limit
y > 0 if curve is above x-axis, in which case also y < f(x)
y < 0 if curve is below x-axis, in which case also y > f(x)

I would have imagined that you simply set up tests for the following conditions on the specific point (X,Y).

( ( X > lower limit ) and ( X < upper limit ) ) to test for x acceptability, then

if f(X) > 0
( ( Y > 0 ) and ( Y < f(X) ) )

if f(X) < 0

( ( Y < 0 ) and ( Y > f(X) ) )

This does not take into account the possibility that any of the inequalities could also include =, this will have to be decided by the wording of your question. I have assumed that your problem revolves around fairly simple curves which will require no complicated modelling, discontinuities etc, although you can normally get around that.

Post more details if this is too simple an approach or does not do what you want.


----------



## HAJ (Mar 12, 2003)

it did help 
thank you


----------



## AlbertB (Nov 24, 2002)

Ok Haj, so now let's get a bit deeper into the area side of it.

We are calculating the area under the curve, effectively integrating between two limits. Let's set the limits as "Xlower" and "Xupper". The function is y = f(x).

First set up a function in C++ to calculate the Y value of your maths function for a given X value.

What we are going to do is to imagine the curve to be made up of a series of side by side rectangles, each one with its top left corner on the curve and its bottom edge on the x-axis. For most of these rectangles the top edge will therefore not truly be in contact with the curve and this method of modelling the curve means that there will always be a slight inaccuracy. We will sum the area of the rectangles to obtain an approximation to the area under the curve.

Select a starting value of Xincrement, the width of each rectangle and therefore the amount each rectangle's right hand edge is increased in each step. A sensible way is to decide on a reasonable number of rectangles and then make Xincrement = (Xupper - Xlower)/number of rectangles. The higher the number of rectangles the closer we get to the rectangles following the curve and the greater the accuracy of our approximated area.

Start at Xlower and calculate the value of Y, ( = f(X) ). The first rectangle has dimensions width = Xincrement and height = Y, and its area is therefore Xincrement * Y. Calculate this and add it to a rolling total. (I will put a possible improvement for this stage at the end).

Increment X by Xincrement to move on to the next rectangle and do the same adding its area to the rolling total. Continue until you have completed all of the steps and have reached Xupper. You then have a total of the area of all of the rectangles under the curve.

At this stage you have no way of knowing what your accuracy is like. One way to approach this aspect is to repeat the process with an increased number of steps, ie narrower rectangles, to get a better approximation to the curve, while keeping a record of the previous total. Subtract the two area totals to see how significant the difference is. This can be made an iterative process until some preset value of difference is reached, implying a certain level of accuracy has been achieved.

All of the above can be performed with simple nested loops.

In fact mathematical integration is only this process but with "infinitely narrow rectangles"! ie decreasing width until we reach the limit of the width of the rectangles = 0.

The improvement I spoke of earlier is that when you calculate the height of each rectangle, do not do it for the left hand edge value of X. This allows the most significant error to creep in. Calculate it for the X value of the midpoint of the rectangle, = (X left edge of rectangle) + (Xincrement / 2). If you make a sketch of these two situations you will see that the second loses a little area on one side of the curve and gains a little area on the other giving it less error overall for each rectangle. It should therefore be possible to reach your preset accuracy in less steps.

Hope that gives you a few more ideas.


----------



## AlbertB (Nov 24, 2002)

Hi again Haj,

I am not sure if in your PM you are giving me all of the code or just the bits relevant to the calculation. The code as you sent it is missing many aspects essential to getting it to compile and run correctly. simple things like your variables not being declared for example.

I sat down and tried to knock out a quick version of what you want. Not knowing what function you wanted it to model I assumed any quadratic. The accuracy required is prompted for, 0.1 - 0.001 seem to give sensible results for such a simple program. The upper and lower x-bounds of your problem are then prompted for. The next prompt is for the starting number of increments in one pass. 100 gives sensible results as it is doubled for each pass until the difference between two consecutive passes becomes less than the accuracy. Finally coefficients of X^2, X, and numeric are input. You can enter +ve, -ve or 0 for any of these to get the function you want. It then calculates the area under the curve between the two bounds, doubles the number of increments and repeats, calculates the error between the two and checks if the accuracy has been met. If not it doubles the increments and repeats again until the accuracy is met.

It needs a bit of improvement but runs as it is for simple functions. See what you think. Beware, although I have not seen a problem it may have been messed around a bit when posted on the page as html does not like things like angled brackets. It also takes out the leading spaces and makes the programme more difficult to read. No way around that I fear. You can see that C++ is not the most concise language around.

I am intrigued to know if your task is to perform the integration, which is effectively what we are doing, or to produce a programme. 

One interesting thing to do is to go to the function func_val and add in the line: x_val = x_val + x_increm/2 ; as the first line in the {}. This changes the point of reference of the rectangle from the top left corner to the centre of the top, and creates much smaller errors. You can see this in action by the smaller number of steps to accuracy.

//
// I have assumed a quadratic function:
// y = sqr_coeff*x^2 + x_coeff*x + num_coeff
// as a simple example
//

#include [stdafx.h] // These four lines need angled 
#include [iostream] // brackets in place of the square ones
#include [stdio.h] // Other lines with message[] and char[]
#include [math.h] // are correct.

using namespace std ;

float accuracy = 1.0 ;
float x_lower = 0 ;
float x_upper = 0 ;
double x_increm = 0 ;

int sqr_coeff = 0 ;
int x_coeff = 0 ;
int num_coeff = 0 ;
int increments = 100 ;

char message[41] ;
int num_elem = 1 ;

// function declarations
//
float get_float ( char[] ) ;
int get_int ( char[] ) ;
int initialise ( void ) ;
double width ( float, float, int ) ;
double func_val ( double ) ;
double rect_area ( double, double ) ;

//--------------
// MAIN function
//
int main( void )
{
double x_val = x_lower ;
double y_val = 0 ;
double curr_tot_area = 0 ;
double prev_tot_area = 0 ;
double error =0 ;

initialise () ;

do
{
x_val = x_lower ;
x_increm = width ( x_lower, x_upper, increments ) ;
curr_tot_area = 0 ;
do
{
y_val = func_val ( x_val ) ;
curr_tot_area += rect_area ( x_increm, y_val ) ;
x_val += x_increm ;
} while ( x_val ? x_upper ) ; // Replace ? with left angled bracket - less than
error = fabs( prev_tot_area - curr_tot_area ) ;
cout << "current increments: " << increments ;
cout << " current area: " << curr_tot_area ;
cout << " error: " << error << endl ;
prev_tot_area = curr_tot_area ;
increments = increments*2 ;
} while ( error > accuracy );

cout << "Final number of increments was: " << increments << endl ;
cout << "Total area under curve is: " << curr_tot_area << endl ;
cout << "Error is: " << error << endl << endl ;

return 0 ;
} ;

//-------------------------------------------------
// Input the values of x_lower, x_upper, no_increms
//
int initialise ( void )
{
strcpy(	message, "Input ACCURACY required, decimal: ") ;
accuracy = get_float ( message ) ;

strcpy(	message, "Input LOWER x bound, decimal: ") ;
x_lower = get_float ( message ) ;

strcpy(	message, "Input UPPER x bound, decimal: ") ;
x_upper = get_float ( message ) ;

strcpy(	message, "Input starting number of increments: ") ;
increments = get_float ( message ) ;

strcpy(	message, "Input coefficient of x^2, integer: ") ;
sqr_coeff = get_int ( message ) ;

strcpy(	message, "Input coefficient of x, integer: ") ;
x_coeff = get_int ( message ) ;

strcpy(	message, "Input numeric coefficient, integer: ") ;
num_coeff = get_int ( message ) ;

return 0 ;
} ;

//-----------------------------------------
// Print message prompt and input one float
//
float get_float ( char message[] )
{
float in_num ;
cout << message ;
cin >> in_num ;
cout << endl ;
return in_num ;
} ;

//-------------------------------------------
// Print message prompt and input one integer
//
int get_int ( char message[] )
{
int in_num ;
cout << message ;
cin >> in_num ;
cout << endl ;
return in_num ;
} ;

//----------------------------------
// Calculate width of each rectangle
//
double width (float min, float max, int steps )
{
return ((max - min)/steps) ;
} ;

//----------------------------------------------
// Calculate value of function for given X value
//
double func_val ( double x_val )
{
return (sqr_coeff*powf(x_val, 2) + x_coeff*x_val + num_coeff) ;
} ;

//------------------------------------
// Calculate area of current rectangle
//
double rect_area ( double x_width, double y_height )
{
return x_width*y_height ;
} ;


----------

