Re: [Rd] Interfacing a C++ class

2011-06-07 Thread soeren . vogel
On 06.06.2011, at 13:42, Romain Francois wrote:

> Le 04/06/11 16:31, soeren.vo...@uzh.ch a écrit :
> 
>> FOO is the C++ object, and Foo should be the S4 class. If the user creates 
>> an object, say bar, from class Foo, the creation process automatically makes 
>> a new FOO object relating to bar in that a unique name of the FOO instance 
>> is stored in a slot of bar. All the user then has to do is modify bar by 
>> simple assignments. The getters and setters ("$", "[") are set up and work. 
>> Each modification goes in hand with assigning new values to bar as well as 
>> updating the FOO object through available setters from FOO.
>> 
>> So far, this way has brought me to about 100 lines, but now I read about 
>> ReferenceClasses and was wondering, if there is a much easier way of 
>> achieving my goals. Moreover, I was not sure any longer if my goals make 
>> sense or if a more advanced programmer would do it totally different (and 
>> could share some structural thinking on their approach).
>> 
>> The idea behind my way of doing was based upon several considerations. 
>> First, a "classical" R object would not confuse users, as I assume users of 
>> my package to be rather non-skilled (and not willing to change that). 
>> Second, I want to create a properly programmed package for distribution on 
>> CRAN and publication, eventually. Third, I want to save objects across 
>> sessions. So if a user restores a session, a simple command, say, restore(), 
>> would do the trick to build all the related C++ objects again. However, I 
>> admit that I still have not figured out how to automatically clean up the 
>> workspace correctly before leaving a session, wanted or unwanted, that is, 
>> clean up memory before leaving home. Fourth, pure arithmetic check is done 
>> in C++, however, semantic check *should* be left to R, and the validity and 
>> class routines seem to be perfect for this. Fifth, some work should be done 
>> in R, such as the passing of data frames or samples from distributions.
> 
> Hello,
> 
> A C++ class that is exposed through an Rcpp module is already a reference 
> class, and so you can add methods, etc ...
> 
> Consider this example :
> 
> require(inline)
> require(Rcpp)
> 
> fx <- cxxfunction( , '', includes = '
> 
> class FOO{
> public:
>FOO( double x_, double y_): x(x_), y(y_){}
> 
>double x ;
>double y ;
> 
>void move( double dx, double dy){
>x += dx ;
>y += dy ;
>}
> } ;
> 
> RCPP_MODULE(mod){
> 
>class_("FOO" )
> 
>.constructor()
> 
>.field( "x", &FOO::x )
>.field( "y", &FOO::y )
> 
>.method( "move", &FOO::move )
>;
> }
> 
> 
> ', plugin = "Rcpp" )
> mod <- Module( "mod", getDynLib(fx),mustStart = TRUE )
> 
> # grab the exposed C++ class
> FOO <- mod$FOO
> 
> # add R methods
> FOO$methods(
>bla = function() x+y,
>reset = function() {
>x <<- 0.0
>y <<- 0.0
>}
> )
> # create an instance
> f <- new( FOO, 2.0, 3.0 )
> 
> # call an R method
> f$reset()
> 
> # call a C++ method
> f$move( 2.0, 2.0 )
> 
> # call an R method
> f$bla()

Thanks Simon and Romain for your great help! That C++ classes exposed via 
Rcpp-modules are already reference classes helps a lot and saves time for 
unnecessary mirroring. According to Romain saving class objects across sessions 
remains to be implemented in Rcpp. I have not browsed the rJava package 
extensively, but I found serialize() (base) and this function seems to provide 
a workaround. Yet, I do not know how to use it in practice with my package. 
Some thoughts: consider the small FOO example below. Then, on accidental crash 
or quit(save="yes"), or whatever users may do, R "should" know that it has to 
serialise all existing FOO objects. Note, that in my package these objects are 
"sort of lists" that can become quite large (say, a vector of 15,000 numeric 
values plus a character string). After restoring a previously saved image, R 
"should know" to load my package, and that in turn should deserialise every FOO 
object present in the image. Sounds like a not too complicated task, something 
like .dofirst()/.dolast() -- but that again exceeds my R and C++ programming 
skills, and I hope that you experts may share an idea. Thanks, Sören

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] Interfacing a C++ class

2011-06-06 Thread Romain Francois

Le 04/06/11 16:31, soeren.vo...@uzh.ch a écrit :


Hello

Apologies for cross-posting, the discussion should (if) go to R-devel, but I 
also want to reach the rcpp-devel people.

My C++ class FOO is a module available through Rcpp, and it works fine and is 
-- so far -- bug free. With trying to further develop my R package, I thought 
it was a good idea to interface my C++ workhorse FOO with an S4 class Foo. 
After some long and not always insightful trip through S4 classes and methods, 
I am not sure if I am on the right way of thinking and designing. Since there 
is no local assistance available, could you help to make things clearer?

Just a brief outline:

FOO is the C++ object, and Foo should be the S4 class. If the user creates an object, say bar, from 
class Foo, the creation process automatically makes a new FOO object relating to bar in that a 
unique name of the FOO instance is stored in a slot of bar. All the user then has to do is modify 
bar by simple assignments. The getters and setters ("$", "[") are set up and 
work. Each modification goes in hand with assigning new values to bar as well as updating the FOO 
object through available setters from FOO.

So far, this way has brought me to about 100 lines, but now I read about 
ReferenceClasses and was wondering, if there is a much easier way of achieving 
my goals. Moreover, I was not sure any longer if my goals make sense or if a 
more advanced programmer would do it totally different (and could share some 
structural thinking on their approach).

The idea behind my way of doing was based upon several considerations. First, a 
"classical" R object would not confuse users, as I assume users of my package 
to be rather non-skilled (and not willing to change that). Second, I want to create a 
properly programmed package for distribution on CRAN and publication, eventually. Third, 
I want to save objects across sessions. So if a user restores a session, a simple 
command, say, restore(), would do the trick to build all the related C++ objects again. 
However, I admit that I still have not figured out how to automatically clean up the 
workspace correctly before leaving a session, wanted or unwanted, that is, clean up 
memory before leaving home. Fourth, pure arithmetic check is done in C++, however, 
semantic check *should* be left to R, and the validity and class routines seem to be 
perfect for this. Fifth, some work should be done in R, such as the passing of data 
frames or samples from distributions.

I hope to get some structured ideas and hints how to start and/or proceed.

Thank you in advance,
Sören


Hello,

A C++ class that is exposed through an Rcpp module is already a 
reference class, and so you can add methods, etc ...


Consider this example :

require(inline)
require(Rcpp)

fx <- cxxfunction( , '', includes = '

class FOO{
public:
FOO( double x_, double y_): x(x_), y(y_){}

double x ;
double y ;

void move( double dx, double dy){
x += dx ;
y += dy ;
}
} ;

RCPP_MODULE(mod){

class_("FOO" )

.constructor()

.field( "x", &FOO::x )
.field( "y", &FOO::y )

.method( "move", &FOO::move )
;
}


', plugin = "Rcpp" )
mod <- Module( "mod", getDynLib(fx),mustStart = TRUE )

# grab the exposed C++ class
FOO <- mod$FOO

# add R methods
FOO$methods(
bla = function() x+y,
reset = function() {
x <<- 0.0
y <<- 0.0
}
)
# create an instance
f <- new( FOO, 2.0, 3.0 )

# call an R method
f$reset()

# call a C++ method
f$move( 2.0, 2.0 )

# call an R method
f$bla()


Hope this helps.

Romain

--
Romain Francois
Professional R Enthusiast
+33(0) 6 28 91 30 30
http://romainfrancois.blog.free.fr
http://romain-francois.com
|- http://bit.ly/hdKhCy : Rcpp article in JSS
|- http://bit.ly/elZJRJ : Montpellier Comedie Club - Avril 2011
`- http://bit.ly/fhqbRC : Rcpp workshop in Chicago on April 28th

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] Interfacing a C++ class

2011-06-04 Thread Simon Urbanek

On Jun 4, 2011, at 10:31 AM, soeren.vo...@uzh.ch wrote:

> Hello
> 
> Apologies for cross-posting, the discussion should (if) go to R-devel, but I 
> also want to reach the rcpp-devel people.
> 
> My C++ class FOO is a module available through Rcpp, and it works fine and is 
> -- so far -- bug free. With trying to further develop my R package, I thought 
> it was a good idea to interface my C++ workhorse FOO with an S4 class Foo. 
> After some long and not always insightful trip through S4 classes and 
> methods, I am not sure if I am on the right way of thinking and designing. 
> Since there is no local assistance available, could you help to make things 
> clearer?
> 
> Just a brief outline:
> 
> FOO is the C++ object, and Foo should be the S4 class. If the user creates an 
> object, say bar, from class Foo, the creation process automatically makes a 
> new FOO object relating to bar in that a unique name of the FOO instance is 
> stored in a slot of bar. All the user then has to do is modify bar by simple 
> assignments. The getters and setters ("$", "[") are set up and work. Each 
> modification goes in hand with assigning new values to bar as well as 
> updating the FOO object through available setters from FOO.
> 

It's fairly simple, you just create an external pointer for your object, 
register "delete obj;" as its finalizer and put it in a slot of your S4 object 
. Have a look, for example, at rJava. It uses S4 objects with one slot being an 
external pointer to the object in Java (in your case C++). For a C++ package 
with external pointers see Acinonyx (aka iPlots eXtreme) - from RCalls.cpp:

static void AObjFinalizer(SEXP ref) {
if (TYPEOF(ref) == EXTPTRSXP) {
AObject *o = static_cast (R_ExternalPtrAddr(ref));
if (o) o->release(); // NOTE: you would probably use delete o; 
instead
}
}

SEXP A2SEXP(AObject *o) {
SEXP xp = R_MakeExternalPtr(o, R_NilValue, R_NilValue);
R_RegisterCFinalizerEx(xp, AObjFinalizer, TRUE);
return xp;
}

AObject *SEXP2A(SEXP o) {
if (TYPEOF(o) != EXTPTRSXP)
Rf_error("invalid object");
return (AObject*) R_ExternalPtrAddr(o);
}



> So far, this way has brought me to about 100 lines, but now I read about 
> ReferenceClasses and was wondering, if there is a much easier way of 
> achieving my goals. Moreover, I was not sure any longer if my goals make 
> sense or if a more advanced programmer would do it totally different (and 
> could share some structural thinking on their approach).
> 

ReferenceClasses are very similar - they differ from the approach I described 
only in that they use an environment for the reference semantics where your 
would use external pointer to your object. Technically, you could put your 
external pointer in a reference class object - what you would gain is the 
ability to store other R objects alongside if you need them.


> The idea behind my way of doing was based upon several considerations. First, 
> a "classical" R object would not confuse users, as I assume users of my 
> package to be rather non-skilled (and not willing to change that). Second, I 
> want to create a properly programmed package for distribution on CRAN and 
> publication, eventually. Third, I want to save objects across sessions. So if 
> a user restores a session, a simple command, say, restore(), would do the 
> trick to build all the related C++ objects again. However, I admit that I 
> still have not figured out how to automatically clean up the workspace 
> correctly before leaving a session, wanted or unwanted, that is, clean up 
> memory before leaving home.

Again, have a look at rJava (see ?.jcache) - it uses Java object serialization 
to cache serialized versions of objects (as raw vectors) in the protection part 
of the pointer which gets serialized by R on save(). Then restoration is 
automatic: when rJava sees a NULL pointer (that's what the are deserialized 
too) in the S4 object, it checks whether there is a serialized cache and 
restores the Java object.

Cheers,
Simon



> Fourth, pure arithmetic check is done in C++, however, semantic check 
> *should* be left to R, and the validity and class routines seem to be perfect 
> for this. Fifth, some work should be done in R, such as the passing of data 
> frames or samples from distributions.
> 
> I hope to get some structured ideas and hints how to start and/or proceed.
> 
> Thank you in advance,
> Sören
> 
> __
> R-devel@r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
> 
> 


[[alternative HTML version deleted]]

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


[Rd] Interfacing a C++ class

2011-06-04 Thread soeren . vogel
Hello

Apologies for cross-posting, the discussion should (if) go to R-devel, but I 
also want to reach the rcpp-devel people.

My C++ class FOO is a module available through Rcpp, and it works fine and is 
-- so far -- bug free. With trying to further develop my R package, I thought 
it was a good idea to interface my C++ workhorse FOO with an S4 class Foo. 
After some long and not always insightful trip through S4 classes and methods, 
I am not sure if I am on the right way of thinking and designing. Since there 
is no local assistance available, could you help to make things clearer?

Just a brief outline:

FOO is the C++ object, and Foo should be the S4 class. If the user creates an 
object, say bar, from class Foo, the creation process automatically makes a new 
FOO object relating to bar in that a unique name of the FOO instance is stored 
in a slot of bar. All the user then has to do is modify bar by simple 
assignments. The getters and setters ("$", "[") are set up and work. Each 
modification goes in hand with assigning new values to bar as well as updating 
the FOO object through available setters from FOO.

So far, this way has brought me to about 100 lines, but now I read about 
ReferenceClasses and was wondering, if there is a much easier way of achieving 
my goals. Moreover, I was not sure any longer if my goals make sense or if a 
more advanced programmer would do it totally different (and could share some 
structural thinking on their approach).

The idea behind my way of doing was based upon several considerations. First, a 
"classical" R object would not confuse users, as I assume users of my package 
to be rather non-skilled (and not willing to change that). Second, I want to 
create a properly programmed package for distribution on CRAN and publication, 
eventually. Third, I want to save objects across sessions. So if a user 
restores a session, a simple command, say, restore(), would do the trick to 
build all the related C++ objects again. However, I admit that I still have not 
figured out how to automatically clean up the workspace correctly before 
leaving a session, wanted or unwanted, that is, clean up memory before leaving 
home. Fourth, pure arithmetic check is done in C++, however, semantic check 
*should* be left to R, and the validity and class routines seem to be perfect 
for this. Fifth, some work should be done in R, such as the passing of data 
frames or samples from distributions.

I hope to get some structured ideas and hints how to start and/or proceed.

Thank you in advance,
Sören

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel