3
$\begingroup$

How would I find the definite integral (between any 2 limits, say a and b) of the absolute value of sin(x)?

I can calculate for the interval 0 to Pi, and from 0 to 2*Pi, but what if the user enters a value far outside 2*Pi? Could I create a while loop?

EDIT: Here is a look at my code and its purpose. I have left my analytical function blank for now because I am still working on it.

/*This program computes the area between the sine curve and the x-axis
It estimates the area using the Trapezoidal method and Simpson's 1/3 rule
and compares all three values */

#include <iostream> //preprocessor directive needed in order to use std::cout
                    //and std::cin
#include <iomanip> //preprocessor directive needed in order to use
                   //a manipulator which uses an argument
#include <cmath>   //preprocessor directive needed in order to use trig, exp and
                   //log functions

using namespace std; //avoids having to uses std:: with cout and cin

//declare the variables
double a, b;
int n;

//prototypes for f(), analytical(), and integrateTrap()
double f (double x);
double analytical (double a, double b);
double integrateTrap (double a, double b, int n);
double integrateSimpson (double a, double b, int n);

int main (int argc, char* argv[])
{  
    //tell the user what the program does
    cout << "The program estimates the integral of sin(x) between\n the limits"
    "[a,b] using both the Trapezoidal method and Simpson's 1/3 rule" << endl;

    cout << "\n\nEnter the lower limit a as a floating point number: ";
    cin >> a;
    cout << "\n\nEnter the upper limit b as a floating point number: ";
    cin >> b;
    cout << "\n\nEnter the number of intervals (an integer>0): ";
    cin >> n;

    //call integrateTrap()
    cout << "\n\nThe estimate of the interval between the limits [" << a << ", "
    << b << "] using \nthe Trapezoidal rule = " << integrateTrap(a,b,n) << endl;

    //call integrateSimpson()
    cout << "\n\nThe estimate of the interval between the limits [" << a << ", "
    <<b<< "] using\nSimpson's 1/3 rule = " << integrateSimpson (a,b,n) << endl;

    //call analytical()
    cout << "\n\nThe analytical answer = " << analytical(a,b) << endl;

    //allow the user to see the results before ending the program
    cout << "\nPress Enter to end the program";
    cin.get();
    cin.get();
}

///////////////////////////////////////////////////////////////////////////////

//define sin(x)
double f (double x)
{
       return abs(sin(x));
}

////////////////////////////////////////////////////////////////////////////////

//define analytical() to be the answer to the definite integral
double analytical(double a, double b)
{

}

////////////////////////////////////////////////////////////////////////////////

//define integrateTrap()
double integrateTrap (double a, double b, int n)
{
       //declare and initialise the variables
       double h = (b-a)/n;
       double x = a;
       double sum = 0.0; 

       //sum up the area of each interval
       for (int i = 1; i <= n; i++) 
       {
           x = a + i*h;
           sum += f(x);    
       }
       return (h/2)*(f(a)+ 2*sum + f(b));     
}

////////////////////////////////////////////////////////////////////////////////

//define integrateSimpson()
double integrateSimpson (double a, double b, int n)
{
       //declare and initialise the variables
       double h = (b-a)/n;
       double even = 0.0, odd=0, x;
       int i;

       //sum up the area of each interval
       for (i = 0, x=a+h; i<n; x=x+h, i++) 
       {
            if(i % 2 == 0)
            {
                 even += f(x);
            }
            else
            {
                 odd += f(x);
            }

       }  
       return (h/3)*(f(a)+ 2*even + 4*odd + f(b));
}
$\endgroup$
4
  • $\begingroup$ Is your question about the correct commands in C++ or about how to evaluate the integral at all? If the latter, you have a periodic function, so you just have to know how the interval $[a,b]$ corresponds to the reference $[0,\pi]$ (via modulo maybe) $\endgroup$
    – Anke
    Mar 20, 2013 at 16:28
  • $\begingroup$ to evaluate between 0 and pi, when the area would be positive anyway, I returned the function -cos(b)+cos(a). After this I started to struggle with modulo Pi, not sure what approach would be best here $\endgroup$ Mar 20, 2013 at 17:31
  • 1
    $\begingroup$ Well, you need to take a and b modulo pi and then make sure the length of the interval is correct. For example: Integrating over $[a,b]=[5\pi,8\pi]$ yields the same result as three times over $[0,\pi]$. The absolute value is never negative, by the way... $\endgroup$
    – Anke
    Mar 21, 2013 at 8:49
  • $\begingroup$ Thanks, this is what I was thinking too. I came up with a function (posted in Answers) but it doesn't return the correct value $\endgroup$ Mar 21, 2013 at 10:58

3 Answers 3

6
$\begingroup$

You could just go for the direct final answer of the integral: $$\int_{a}^{b}\vert {\sin(x)}\vert dx = 2\left(\left\lfloor\frac{b}{\pi}\right\rfloor - \left\lfloor\frac{a}{\pi}\right\rfloor\right) + \cos\left(\left\{\frac{a}{\pi}\right\}\pi\right) - \cos\left(\left\{\frac{b}{\pi}\right\}\pi\right)$$

where $\left\lfloor c\right\rfloor$ denotes the flooring operation and $\left\{c\right\}$ denotes the fractional part operation that extracts the decimal part of the number.

$\endgroup$
0
2
$\begingroup$

EDIT: Here is an updated version of my analytical function. Tested it for a few values and it seems to work. Thanks to Anke for your help

double analytical(double a, double b)
{
  const double PI = 2*acos(0);

  if ( b-a <=PI)
  {
       return abs(-cos(b) + cos(a));
  }
  else if ((b-a) > PI)
  {
       float area=0;
       double aReduced = fmod(a,PI);
       double bReduced = fmod(b,PI);

       while (b-PI > a)
       {
            b = b - PI;
            area += 2;
       }

       area += abs(-cos(PI)+cos(a)) + abs(-cos(b)+cos(PI));
       return area;
  }
}
$\endgroup$
3
  • $\begingroup$ Your variables aReduced and bReduced are the same... Also, you should take and b modulo $\pi$, because the absolute value of sine is only $\pi$-periodic. Then you have to pay attention to the area calculation: You have to split your interval according to where sine is positive or negative. I get the impression that you should clarify what exactly you want to compute... $\endgroup$
    – Anke
    Mar 21, 2013 at 11:22
  • $\begingroup$ Got it working! Thank you for all your help. I will update my answer with the new version. $\endgroup$ Mar 21, 2013 at 14:43
  • $\begingroup$ I still don't think it's correct. Even if $[a,b]$ is less than $\pi$ in length, you have to be careful there. Integrating an absolute value simply doesn't work that way. You cannot place the absolute value around the rest, you have to divide the integral into the parts where the absolute value leaves and where it changes the sign. Try $[a,b] = [\pi/2,3\pi/2]$. Your code will return zero because cosine is zero in both point, but obviously the integral is two. You have to split it into two integrals over $[\pi/2,\pi]$ and $[\pi,3\pi/2]$, so you have $\sin x$ and $-\sin x$ as integrands. $\endgroup$
    – Anke
    Mar 22, 2013 at 7:58
1
$\begingroup$

It looks like you are looking for the functions fmod and remainder, or perhaps remquo if you're willing to accept a non-portable maximum number of intervals.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.