On 29/11/06, Ivan Liu <[EMAIL PROTECTED]> wrote:
The following test routine works. But I'd like to use the member functions
of class Testo in the integrand function:
static double f (double x, void * params)
without declaring another object of class Testo ( pT in the example).

How can I do that?
[original code snipped out]

The problem seems to arise that you're declaring Testo::f to be
static, which in turn is necessary in order to be able to take its
address.

I think it makes more sense to declare f to be a non-member function,
and put it in some enclosing namespace.

I also don't understand what the point of the GetX function is
supposed to be. I removed it.

I think it makes sense to have Testo contain as a private member a
pointer to the function you actually want to integrate, and to
manipulate this pointer via member functions (which includes
constructors).

By the way, some stylistic points about your C++ code: it's not
necessary to use the "struct" qualifier when you're declaring objects
of type f_params (I think that's necessary for C, but it's certainly
not necessary in C++). Also, putting a global using declaration is
generally bad form. Put your using declarations inside other
namespaces or scoped inside functions or classes, or avoid them
altogether if you're only using a few objects from a specific
namespace. I have also added a destructor to your Testo class,
necessary since you allocated memory on the heap with new and with
malloc indirectly through GSL.

I attach my opinions of what your code should look like. My
modifications avoid the declaration of a new object as you requested,
and your class's destructors and constructors automatically take care
of memory management, while providing, IMHO, a more comfortable
syntax. These are the advantages of wrapping C code in C++.

HTH,
- Jordi G. H.
#include <iostream>
#include <cmath>
#include <gsl/gsl_math.h>
#include <gsl/gsl_integration.h>


namespace Test{

  struct f_params{ double a; double b; }; //Struct definition,
					  //properly namespaced inside Test.

  class Testo
  {
  private:
    gsl_integration_workspace * w;
    gsl_function * pIntegrand;
    double (*pTheFunction)(double, void*);

  public:
    Testo():
      w( gsl_integration_workspace_alloc(1000)),
      pIntegrand( new gsl_function() )
    {}; //No need for extra semicolon in empty constructor body.

    Testo( double (*pNewFunction)(double, void*)) : //Construct a
						    //Testo object
						    //with a pointer
						    //to the function
						    //to be integrated.
      w( gsl_integration_workspace_alloc(1000)),
      pIntegrand( new gsl_function() ),
      pTheFunction(pNewFunction)
    {};

    ~Testo()
    {
      gsl_integration_workspace_free(w);
      delete pIntegrand;
    };

    double Integrate()
    {
      double resIntegral, abserr;
      f_params list= {0.0,1.0}; //C-style struct initialisation ok,
				//but I prefer:
                                //
				//  f_params list;
				//  list.a = 0.0;
                                //  list.b = 1.0;

      double x_start=0.0;
      double x_end=1.0;
      int limit=999;
      double epsabs= 0.0;
      double epsrel=1e-6;

      pIntegrand->function = pTheFunction;
      pIntegrand->params = &list;

      gsl_integration_qag (pIntegrand, x_start, x_end, epsabs, epsrel,
			   limit, 1,
			   w, &resIntegral, &abserr);

      return resIntegral;
    };

  };

  double f (double x, void * params) {
    f_params * pList = (f_params *) params;
    double a = (pList->a);
    double b = (pList->b);
    return a+b*x; 
  }

}//end namespace Test


int main(void)
{

  //If you prefer to avoid the scope resolution operators below,
  //(i.e. the :: operator)uncomment the following two using
  //declarations. Note that this opens up the std and Test namespaces
  //only inside the current function, main(), instead of dumping all
  //of std and Test into the global namespace, which would defeat the
  //purpose of namespaces to begin with.

  //using namespace Test
  //using namespace std;

  Test::Testo G(&Test::f); //Create object of type Testo and assign it
			   //Test::f as the function it will
			   //integrate.

  std::cout <<  G.Integrate() << std::endl;

  return 0;
}
_______________________________________________
Help-gsl mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/help-gsl

Reply via email to