[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: |
Omar Andrés Zapata Mesa |
Subject: |
Re: [Help-gsl] setting function of gsl_odeiv_system structure to a C++ class member function |
Date: |
Tue, 20 Apr 2010 14:56:50 -0500 |
Hi all
you can solve this problem in this way
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();
static int eoms(double t, const double x[8], double f[8], void *params);
/*<-change*/
};
if you use some class atribute on static function eoms you need add
variable protopyte in Torus.cpp
ie.
int Torus::myvar;
it is if myvar is a variable of Torus and you use it in eoms
sorry my engilsh, I am learning now.
regards!
--
Omar Andres Zapata Mesa
Auxiliar programmer in Phenomenology of Fundamental Interactions Group (
Gfif <http://gfif.udea.edu.co/>)
Programmer Computational Physics and Astrophysics Group
Division of computer science (FACom <http://http//urania.udea.edu.co/sites>)
Ingeniería de Sistemas
Universidad de Antioquia
Usuario Linux #490962
2010/4/20 Luke <address@hidden>
> 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 mailing list
> 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, 2010/04/20
- Re: [Help-gsl] setting function of gsl_odeiv_system structure to a C++ class member function,
Omar Andrés Zapata Mesa <=
- 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