help-gsl
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Help-gsl] setting function of gsl_odeiv_system structure to a C++


From: Luke
Subject: Re: [Help-gsl] setting function of gsl_odeiv_system structure to a C++ class member function
Date: Tue, 20 Apr 2010 12:01:43 -0700

Daniel,
  I got it to work doing this, which is sort of what you suggested:

torus.cpp
// Begin ugly hack
Torus * TorusPtr;

int TorusEomsWrapper(double t, const double x[8], double f[8], void *params)
{
  return TorusPtr->eoms(t, x, f, params);
}
// End ugly hack

Torus::Torus()
{
  ...
  // can't assign Torus::eoms to sys.function because of C++ calling
convention for class member functions
  sys.function = TorusEomsWrapper;
  ...
}

int Torus::eoms(double t, const double x[8], double f[8], void *params)
{
  ...
  return GSL_SUCCESS;
}

So this way the code for eoms is part of the class, but isn't used directly
by GSL, instead it uses the wrapper function...  It works, but isn't pretty.

Anybody else know of a cleaner way to do it?

~Luke

On Tue, Apr 20, 2010 at 11:54 AM, Daniel Neilson <address@hidden>wrote:

>
> Luke,
>  I actually don't use GSL enough to even know if there are developer
> preferred ways of doing things with it. But, one thing you could do is to
> make your eoms() function a static extern "C" function defined only in the
> source file for your Torus class; that is, don't make it a member function
> of Torus. Then, in the constructor for Torus you can set up the function
> pointer to point to that statically defined function.
>
>  It'd work, and would still be somewhat encapsulated.
>
> -Daniel
>
>
> On 10-04-20 11:25 AM, Luke wrote:
>
>> Daniel,
>>   Thanks for the link, at least now I understand why the error is
>> occurring.  I think I can figure out how to use the article's
>> suggestions to make things work, but do you (or anybody else) have a
>> preferred way of doing this sort of thing in GSL?
>> Thanks,
>> ~Luke
>>
>>
>> On Tue, Apr 20, 2010 at 10:16 AM, Daniel Neilson <address@hidden
>> <mailto:address@hidden>> wrote:
>>
>>
>>    Hi Luke,
>>      C++ class member functions have a hidden parameter -- the object
>>    that they're being called on.
>>
>>      So, your function:
>>
>>    int eoms(double t, const double x[8], double f[8], void *params);
>>
>>      is actually more like (if it were in C):
>>    int eoms(Torus *this, double t, const double x[8], double f[8], void
>>    *params);
>>
>>      This might help:
>>    http://www.parashift.com/c++-faq-lite/pointers-to-members.html
>>
>>    -Daniel
>>
>>
>>    On 10-04-20 11:09 AM, Luke wrote:
>>
>>        I am trying to create a C++ class to organize the various
>>        functions I have
>>        generated for my system.  Here is my class definition:
>>
>>        class
>>        Torus
>>
>>        {
>>
>>
>>        private:
>>
>>
>>             const gsl_odeiv_step_type *
>>        T;
>>
>>             gsl_odeiv_step *
>>        s;
>>
>>             gsl_odeiv_control *
>>        c;
>>
>>             gsl_odeiv_evolve *
>>        e;
>>
>>             gsl_odeiv_system sys;
>>           public:
>>
>>
>>
>>        Torus();
>>
>>
>>        ~Torus();
>>
>>             int eoms(double t, const double x[8], double f[8], void
>>        *params);
>>        };
>>
>>
>>        Then, in the constructor, I have:
>>
>>        Torus::Torus()
>>
>>        {
>>
>>           t =
>>        0.0;
>>
>>           T =
>>        gsl_odeiv_step_rk8pd;
>>
>>           s = gsl_odeiv_step_alloc(T,
>>        8);
>>
>>           c = gsl_odeiv_control_y_new(1e-6,
>>        0.0);
>>
>>           e = gsl_odeiv_evolve_alloc(8);
>>           // Can't get the following to work:
>>
>>
>>           //sys = {eoms, NULL, 8, NULL};  // doesn't work
>>           sys.function =&eoms; // doesn't work
>>           sys.function = eoms; // doesn't work
>>           sys.function = this.eoms; // doesn't work
>>           sys.function = Torus::eoms; // doesn't work
>>           sys.jacobian = NULL; // works
>>           sys.dimension = 8; // works
>>
>>
>>           sys.params= NULL;  // works
>>
>>
>>        }
>>
>>        right now, I just have a stub for my eoms function:
>>
>>        int Torus::eoms(double t, const double x[8], double f[8], void
>>        *params)
>>        {
>>           return GSL_SUCCESS;
>>        }
>>
>>        Here are the errors I have receive when I try to compile (g++
>>        -Wall -lgsl -c
>>        torus.cpp):
>>        With sys.function =&eoms;  :
>>        torus.cpp: In constructor ‘Torus::Torus()’:
>>        torus.cpp:12: error: ISO C++ forbids taking the address of an
>>        unqualified or
>>        parenthesized non-static member function to form a pointer to
>> member
>>        function.  Say ‘&Torus::eoms’
>>        torus.cpp:12: error: cannot convert ‘int (Torus::*)(double,
>>        const double*,
>>        double*, void*)’ to ‘int (*)(double, const double*, double*,
>>        void*)’ in
>>        assignment
>>
>>        With sys.function = eoms; :
>>        torus.cpp: In constructor ‘Torus::Torus()’:
>>        torus.cpp:12: error: argument of type ‘int (Torus::)(double,
>>        const double*,
>>        double*, void*)’ does not match ‘int (*)(double, const double*,
>>        double*,
>>        void*)’
>>
>>        With sys.function = this.eoms;
>>        torus.cpp: In constructor ‘Torus::Torus()’:
>>        torus.cpp:12: error: request for member ‘eoms’ in ‘this’, which
>>        is of
>>        non-class type ‘Torus* const’
>>
>>        With sys.function = this->eoms;
>>        torus.cpp: In constructor ‘Torus::Torus()’:
>>        torus.cpp:12: error: argument of type ‘int (Torus::)(double,
>>        const double*,
>>        double*, void*)’ does not match ‘int (*)(double, const double*,
>>        double*,
>>        void*)’
>>
>>        With sys.function =&Torus::eoms;
>>        torus.cpp: In constructor ‘Torus::Torus()’:
>>        torus.cpp:12: error: cannot convert ‘int (Torus::*)(double,
>>        const double*,
>>        double*, void*)’ to ‘int (*)(double, const double*, double*,
>>        void*)’ in
>>        assignment
>>
>>        Is there something simple that I haven't tried to get this
>>        assignment to
>>        work?  Or is there a different way I should be doing it?
>>
>>        Thanks,
>>        ~Luke Peterson
>>        _______________________________________________
>>        Help-gsl mailing list
>>        address@hidden <mailto:address@hidden>
>>
>>        http://lists.gnu.org/mailman/listinfo/help-gsl
>>
>>
>>
>>
>


reply via email to

[Prev in Thread] Current Thread [Next in Thread]