[Top][All Lists]
[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:17:20 -0700 |
Aha. Thanks! I'm coming from the Python world where segfaults are few and
far between :)
So, doing it this way doesn't let me have access to class member it seems.
I have all the equations of motion (the odes) setup in such a way that the
parameters and states are class members (so passing their address wouldn't
actually be needed in the function signature if eoms could be a member
function).
Maybe I could make a friend function or something to handle this aspect of
things?
~Luke
On Tue, Apr 20, 2010 at 12:06 PM, Daniel Neilson <address@hidden>wrote:
>
> Luke,
> I'd recommend against doing it that way. At the least, the code as you've
> written it should segfault; you haven't assigned any value to TorusPtr, so
> the dereference "TorusPtr->" will do who knows what.
>
> Instead, it's cleaner (and, technically faster 'cause there's one less
> function call) to just do:
>
> extern "C" static int eoms(double t, const double x[8], double f[8], void
> *params)
> {
> ...
> return GSL_SUCCESS;
> }
>
> Torus::Torus()
> {
> sys.function = eoms;
> }
>
> -Daniel
>
>
> On 10-04-20 01:01 PM, Luke wrote:
>
>> 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
>> <mailto: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>
>> <mailto: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>
>> <mailto:address@hidden <mailto:address@hidden>>
>>
>>
>> http://lists.gnu.org/mailman/listinfo/help-gsl
>>
>>
>>
>>
>>
>>
>
- [Help-gsl] setting function of gsl_odeiv_system structure to a C++ class member function, Luke, 2010/04/20
- Message not available
- Message not available
- Message not available
- Re: [Help-gsl] setting function of gsl_odeiv_system structure to a C++ class member function, Luke, 2010/04/20
- Message not available
- Re: [Help-gsl] setting function of gsl_odeiv_system structure to a C++ class member function,
Luke <=
- Re: [Help-gsl] setting function of gsl_odeiv_system structure to a C++ class member function, Omar Andrés Zapata Mesa, 2010/04/20
- Message not available
- Re: [Help-gsl] setting function of gsl_odeiv_system structure to a C++ class member function, Luke, 2010/04/20
- Message not available
- Re: [Help-gsl] setting function of gsl_odeiv_system structure to a C++ class member function, Luke, 2010/04/20
- [Help-gsl] Re: setting function of gsl_odeiv_system structure to a C++ class member function, Rodney Sparapani, 2010/04/20
- Re: [Help-gsl] setting function of gsl_odeiv_system structure to a C++ class member function, Andrew W. Steiner, 2010/04/20