Search code examples
c++std-pair

How to get a C++ pair to compile


I am trying to compile a very complicated code and I get the error

g++ -o MCBody MCBody.cpp
MCBody.cpp:36:34: error: expected initializer before ‘<’ token
 double numericalIntegration::pair<double,double> integrate(double (*pFun)(const double & x),const double & LBound, const double & UBound)

You can see that here is a problem with the recognition of the C++ pair object. I am too stupid to see what is wrong and cannot make the code very smaller. I want your help with respect.

Here is MCBody.cpp (the big one):

//---MCBody---//
// Function that performs a regular numeric integration by with random
// spacing between points and unit weighting. Tells the
// NumericalIntegration class what the functions are to do.
// INPUTS (for integrate):
// Fun = a function of x
// LBound = lower bound of integral
// UBound = upper bound of integral
// OUTPUT:
// IntDev = a pair with the first value being the integral and the second
// being the standard deviation.

#ifndef MCRULE_CPP                      // If Monte Carlo rule is not 
#define MCRULE_CPP                      // defined, define it.

#include "NumericalIntegrationClass.h"  // So it can see the class def.
#include <stdlib.h>                     // For rand and srand
#include <time.h>                       // Get random srand values.
#include <iostream>
#include <math.h>
#include <utility>
using namespace std;


// I: Tell the integration what the number of intervals/points taken are.
numericalIntegration::numericalIntegration(const int & numIntervals)
{
  // THIS is a pointer to the current object within a member function. It
  // is used when no other object name is specified.
  this->numIntervals = numIntervals;  // Stores the value of the
                                      // parameter numIntervals.
}


// II: Perform the integration approximation.
double numericalIntegration::pair<double,double> integrate(double (*pFun)(const double & x),const double & LBound, const double & UBound)
{
  // Return value is different to one stored in location pointed by time.
  srand(time(NULL)); 
  double XintSize = (UBound-LBound);
  double Total = 0;
  double SumOSquares = 0;

  for (int i =0; i<=numIntervals; i++)
    {
      // Creating 'random' points within the lower bound and upper bound.
      double x_i = LBound + (rand())/ (RAND_MAX/XintSize);

      // Evaluate the pointer at x_i and add to Total.
      double fx = (*pFun)(x_i);
      Total += fx;
      SumOSquares += pow(fx,2);
    }  
  double Deviation = SumOSquares - pow(Total,2);
  Deviation = (sqrt(Deviation))/((float)numIntervals+1);
  double Integral = (1/((float)numIntervals+1))*XintSize*Total;
  pair<double,double> IntDev;

  IntDev =  make_pair(Integral,Deviation);

  return IntDev;
}

#endif

Here is MCRule.cpp:

//---MCRule---//
// A function to calculate the integral of a function via the Monte Carlo
// method.
// INPUTS:
// n = number of points
// l = lower limit of the integration
// u = upper limit of the integration
// line 24: the function to be integrated

// I: Define a function that is supposed to be integrated.
#include "NumericalIntegrationClass.h" // Want to include a reference to
                                       // the header in the main file so 
                                       // it can see what's happening in
                                       // the class.
#include <math.h>                      // Cos.
#include "MCBody.cpp"
#include <iostream>
#include <utility>

double fun(const double & x)  // Passing a reference to some number x
{                             // (not going to change x within the loop).
                              // Passing by reference, therefore not
                              // allocating any new space.
  // Define the function to be integrated.
   return ((1 + 0.25*cos(x))/(1+x*x)); 
   //return (1+0.25*cos(tan(x)));

}

// II: Execute Monte Carlo integration function.
int main (int argc, char* argv[]) // First bit = counts the arguments.
                                  // Sec bit = the vector that stores the
                                  // arguments.
{
  // Retrieve inputs.
  int n = atoi(argv[1]);     // Extracts number of points.
  double l = atoi(argv[2]);  // Extracts lower bound for integration.
  double u = atoi(argv[3]);  // Extracts upper bound for integration.

  // Define number of intervals.
  numericalIntegration numInt(n);

  // Define lower and upper bounds for integral.
  pair<double,double> IntDev = numInt.integrate(fun,l,u);
  float abso = fabs(IntDev.first - 3.2294), rel = (abso/IntDev.first)*100;
  cout << "Integral is: " << IntDev.first << endl;
  cout << "Absolute Error: " << abso << endl;
  cout << "Relative Error: " << rel << "%" << endl;
  cout << "Standard Deviation: " << IntDev.second << endl;
  cout << "Monte Carlo Error: " << IntDev.second/(sqrt(n+1)) << endl;
  return 0;
}

Here is NumericalIntegrationClass.h:

//---NumericalIntegrationClass---//
// Creates a class of for functions which can be integrated using the
// Monte Carlo method.
// This class has 2 public functions; one which points the class to the 
// number of points/intervals used (numericalIntegration), and one used
// to perform the actual integration approximation.

// I: PRE-PROCESSORS
#pragma once   // Current source file to be included once in a single
               // compilation. Serves same purpose of #include guard but
               // avoids name clashes.
#include <utility>
using namespace std;


class numericalIntegration
{
  // II: DEFINE PUBLIC
  // Public area can be touched from outside of the function.
 public:   

  // NUMERICALINTEGRATION: Setting the number of intervals to be a 
  // constant integer.
  numericalIntegration(const int & numIntervals);

  // INTEGRATE: Call the method that calculates the value of the 
  // integral.
  pair<double,double> integrate(double (*pFun)(const double & x),const double & LBound, const double & UBound);


  // III: DEFINE PRIVATE
  // Private area can only be touched by internal methods.
 private:   
  int numIntervals;
};

Solution

  • numericalIntegration::pair<double,double> 
    

    This means:

    1. go to the numericalIntegration class
    2. find its pair member
    3. make sure it is a template that accepts two type arguments
    4. and instantiate it with <double, double> arguments

    This fails at #2 as there is no pair member in numericalIntegration. There is a member named integrate that returns std::pair<double, double>. To express that in C++, you say

    pair<double,double> numericalIntegration::integrate