|
From: | Francesco Faccio |
Subject: | Re: Avoid global pointers in dae |
Date: | Mon, 15 Aug 2016 10:42:43 +0000 |
Carlo de Falco<address@hidden> wrote:
> On 15 Aug 2016, at 09:09, Francesco Faccio <address@hidden> wrote: > > > > > Carlo de Falco<address@hidden> wrote: > > >On 14 Aug 2016, at 02:11, Carlo de Falco <address@hidden> wrote: > > > > > >> > > >> On 14 Aug 2016, at 01:17, Carnë Draug <address@hidden> wrote: > > >> > > >>> On 13 August 2016 at 06:30, Francesco Faccio > > >>> <address@hidden> wrote: > > >>>> [...] > > >>>> Since I don't own copiright, I would like to know if it's ok to change the > > >>>> interface of that base class. > > >>>> > > >>> > > >>> The ability to change the code is one of the main points behind GPL. > > >>> So yes, you can change the source. > > >>> > > >>> Just beware that if the interface is public you should try to keep > > >>> backwards compatibility. I grepped all of the Octave Forge for DAEFunc > > >>> and all of its subclasses [1] but couldn't find it being used so you > > >>> should be fine. > > >>> > > >>> Carnë > > >>> > > >>> [1] http://octave.org/doxygen/4.1/d9/d83/classDAEFunc.html > > >> > > >> Francesco, > > >> > > >> As Carnë's answer shows, your question is ill posed and leads to misunderstandings: > > >> > > >> of course you can change the source, the GPL license grants you this right, > > >> the real question would be whether that change would be accepted by Octave > > >> developers in the main repository or not. > > > > > >To make this more clear, who holds copyright is pointless and referring to that > > >in your question is distracting. > > > > > >The question is a technical question about the class design and functionality, not > > >a legal question about licenses and copyright. > > > > > >> c. > > > > Carlo, Carnë, > > > > sorry, my question was not well posed and thank you for making this clear to me. > > I'm not still sure we can avoid global pointers wrt the design of Octave. Let me explain why: > > > > In my dld-function I have a pointer to the octave_function provided by the user and I use it inside a DAERHSFunc to compute > residual. I use a pointer to thisDAERHSFunc when I construct an object of my class. > > > > Inside my class I have methods which allows me to interface with Sundials' types and functions. In particular, I use a lambda to pass a > residual function (with fixed signature) to a function of Sundials (with fixed signature). > > > > The problem here is that I cannot use classes and methods of libinterp inside liboctave to compute residual, I can only put a forward declaration in my class. > > > > My first and actual solution is to call inside my lambda a pointer (stored in the base class) to the DAERHSFunc defined in my dld-fun, so I can call methods of class octave_function and I avoid code duplication, but I need to declare the poiner to octave_function global in my dld-function. > > > > What I was trying to do, was to store the octave_function pointer as member of my class and to pass it as a parameter when I dereference the pointer to the DAERHSFunc in my lambda. But since it has incomplete type I get segmentation fault. > > > > I think I could avoid global pointers changing completely the constructor of my class, but then inheriting from DAE would be meaningless. > > > > Do you have any suggestions or do you know some workaround to this? > > > > Thank you, > > > > Francesco > > > Hi Francesco, > > As a general > > Can you provide links to lines in your code on bitbucket so we can follow more clearly what you are talking about? Dear Carlo, here's the link to my dld-function [1], to the header of my class [2] and its implementation [3]. In [1] line 71 there is the definition of the DAERHSFunc I call in line 230 where I construct my object. >Are lambdas among the C++11 features that are acceptable to use in Octave 4.1? I can compile Octave using lambdas, but as you asket I suppose that's not enough. Where can I check this? Why is your class IDA inheriting from DAE? What methods from the base class are you actually using? Since a dae solved by ode15i "is a" DAE and the design is pretty similar to daspk.cc, I think that it's the right place to be inside Octave. In IDA I call the constructor of the base class DAEFunc passing as argument a pointer to the DAERHSFunc and the constructors of base class base_diff_alg_eqn and base_diff_eqn. I call methods base_diff_eqn::time(), base_diff_eqn::state(), base_diff_alg_eqn::state_derivative() inside another method to initialize Ida solver and I dereference the function of the base class DAEFunc in order to compute residual ([3] line 70). > 2 - use the void pointer user_data to pass the 'this' pointer of the current object > > static int > IDA::res_interface (realtype tt, N_Vector yy, N_Vector yp, N_Vector rr, void *user_data) > { > IDA *self = static_cast<IDA*>(user_data); > ... > } This is similar to what I do: my lambda can't capture any parameter because the signature would change. If the lambda doesn't capture anything, I still create a closure, but I can pass the lambda as a pointer to function to IDAInit ([3], line 79). I store in user_data the pointer to the DAERHSFunc I want to call: void IDA::set_userdata(void *& ida_mem)
{
void * userdata = &fun;
int flag = IDASetUserData(ida_mem, userdata);
}
and then, inside a method: auto resfun = [] (realtype t, N_Vector yy, N_Vector yp, N_Vector rr, void *user_data) {
...
DAEFunc::DAERHSFunc *data = "" *>(user_data);
DAEFunc::DAERHSFunc pointres = *data;
ColumnVector res = (*pointres) (y0, yp0, t, ires);
...};
int flag = IDAInit (ida_mem, resfun, t0, yy, yp); >3 - you can now access the non static class member methods via the pointer This is nice, but I can't write methods that compute residual inside my class. I need to call method do_multi_index_op or feval, which are defined in libinterp. That's why I dereference pointres to call function defined in [1] line 72. What I wanted to do to avoid global pointers was to overload the constructor of DAEFunc in order to call
ColumnVector res = (*pointres) (y0, yp0, t, ires, ida_fcn);
The same problem affects the Jacobian evaluation. We have 4 options I think: - find a brilliant way to evaluate residual in liboctave avoiding global pointers (passing ida_fcn in some way) -inherit from DAE and evaluate residual completely inside the dld-function (I can write resfun as a normal function and pass it to IDAInit) -don't inherit from DAE and evaluate residual completely inside the dld-function -use the global pointer as daspk, dassl, dasrt and other corefcn In these days I became quite familiar with std::function, std::function::target, std::bind, so if there is a nice way to use them we can try something magic. Thank you for the hints, Francesco [1] https://bitbucket.org/Francesco_Faccio/octave/src/6f04dbbe5fdf147fbd95fb3ea8901e5fd61081a7/libinterp/dldfcn/__ode15__.cc?at=default&fileviewer=file-view-default [2]https://bitbucket.org/Francesco_Faccio/octave/src/6f04dbbe5fdf147fbd95fb3ea8901e5fd61081a7/liboctave/numeric/IDA.h?at=default&fileviewer=file-view-default [3]https://bitbucket.org/Francesco_Faccio/octave/src/6f04dbbe5fdf147fbd95fb3ea8901e5fd61081a7/liboctave/numeric/IDA.cc?at=default&fileviewer=file-view-default |
[Prev in Thread] | Current Thread | [Next in Thread] |