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