[Rcpp-devel] Evaluating a call in a particular environment

Romain Francois romain.francois at dbmail.com
Fri May 21 09:21:16 CEST 2010


Le 21/05/10 08:18, Dirk Eddelbuettel a écrit :
>
>
> On 20 May 2010 at 16:54, Douglas Bates wrote:
> | A short version of this question is "can I evaluate an Rcpp::Language
> | instance in an Rcpp::Environment instance"?  Initially I thought this
> | was a given but on looking closer at the unit tests I don't see how
> | exactly it would be done.

Language has this:

        /**
	 * eval this call in the requested environment
	 */
	SEXP eval(SEXP env) ;

And Rcpp::Environment is convertible to SEXP

> | A second short version of this question is "could someone, probably
> | Romain, remind me what is done to activate the debugging code in Rcpp
> | or point me to the documentation for it?".
>
> Two simple macros are in RcppCommon.h:
>
> // simple logging help
> #define RCPP_DEBUG_LEVEL 0
>
> #ifndef logTxt
> 	#if RCPP_DEBUG_LEVEL>  0
> 		#define logTxt(x) ::logTxtFunction(__FILE__, __LINE__, x);
> 	#else
> 		#define logTxt(x)
> 	#endif
> #endif
>
> #if RCPP_DEBUG_LEVEL>  0
> 	#define RCPP_DEBUG( fmt , ... ) Rprintf( "%s:%d " fmt "\n" , __FILE__, __LINE__,##__VA_ARGS__ ) ;
> #else
> 	#define RCPP_DEBUG( fmt , ... )
> #endif
>
> So by flipping RCPP_DEBUG_LEVEL from 0 to 1 or greater you get
> these. logTxtFunction is in RcppCommon.cpp:
>
> void logTxtFunction(const char* file, const int line, const char* expression) {
>      Rprintf("%s:%d %s\n", file, line, expression);
> }
>
> That was the easy part. I think I pass on the long version... That looks a
> little hairy and I am only one coffee into the day...
>
> Dirk
>
>
> | The long version follows:
> |
> | In the lme4a package (only on R-forge and requiring the R-forge
> | version of the Matrix package) the nlmer function to fit nonlinear
> | mixed-effects models has a nonlinear model, expressed as a call, and
> | an environment in which to evaluate this call.  The operation of
> | evaluating the deviance of the model involves changing the contents of
> | some numeric vectors in this environment then evaluating the call.
> |
> | The nlmerResp class is declared (in lme4a/src/mer.h) as
> |     class nlmerResp : public rwResp {
> | 	Rcpp::Environment nlenv;
> | 	Rcpp::Language nlmod;
> | 	Rcpp::CharacterVector pnames;
> |     public:
> | 	nlmerResp(Rcpp::S4 xp);
> | 	void updateMu(Rcpp::NumericVector const&gamma);
> |     };
> |
> | and initialized from an Rcpp::S4 object.  I have some debugging code
> | in the current version of the updateMu method to check that the values
> | in the environment are what I expect them to be
> |>  nm1<- lme4a:::nlmer2(circumference ~ SSlogis(age, Asym, xmid, scal) ~ 0 + Asym + xmid + scal + (0 + Asym|Tree), Orange, start = c(Asym = 200, xmid = 725, scal = 350))
> |>  .Call("nlmerDeEval", nm1)
> | past initialization of nlmerDe object
> | gamma after offset: 0, 0, 0, 0, 0
> | u: 0, 0, 0, 0, 0
> | b: 0, 0, 0, 0, 0
> | gamma after reUpdate: 0, 0, 0, 0, 0
> | gamma after feUpdate: 200, 200, 200, 200, 200
> | gamma in resp::updateMu: 200, 200, 200, 200, 200
> | p = 0, parameter name = Asym
> | current: 200, 200, 200, 200, 200
> | updated: 200, 200, 200, 200, 200
> | p = 1, parameter name = xmid
> | current: 725, 725, 725, 725, 725
> | updated: 725, 725, 725, 725, 725
> | p = 2, parameter name = scal
> | current: 350, 350, 350, 350, 350
> | updated: 350, 350, 350, 350, 350
> |
> | Before evaluation
> | Error in cpp_exception(message = "object 'xmid' not found", class =
> | "Rcpp::eval_error") :
> |   object 'xmid' not found
> |
> | So I am a bit surprised at xmid not being found because I just
> | modified it.  The objects at the R level are
> |
> |>  nm1 at resp@nlmod
> | SSlogis(age, Asym, xmid, scal)
> |>  class(nm1 at resp@nlmod)
> | [1] "call"
> |>  ls.str(nm1 at resp@nlenv)
> | age :  num [1:35] 118 484 664 1004 1231 ...
> | Asym :  num [1:35] 200 200 200 200 200 200 200 200 200 200 ...
> | scal :  num [1:35] 350 350 350 350 350 350 350 350 350 350 ...
> | xmid :  num [1:35] 725 725 725 725 725 725 725 725 725 725 ...
> |
> | and I can evaluate the call in R
> |
> |>  head(eval(nm1 at resp@nlmod, nm1 at resp@nlenv))
> | [1]  30.00804  66.87019  91.30771 137.87260 161.86760 172.79186
> |
> | I am trying to evaluate the call in the C++ code as
> |
> |    NumericVector rr = nlmod.eval(nlenv);
> |
> | which, I assume, expands to
> |
> |   NumericVector rr = nlmod.eval(SEXP(nlenv));
> |
> | Is there some trick I am missing?

Ah. There might be a problem then:

require( Rcpp )

fx <- cppfunction( signature(x = "environment" ), '
	Environment env(x) ;
	Language call( "sum", Symbol("y") ) ;
	Rf_PrintValue( call ) ;
	return call.eval( env ) ;
' )

e <- new.env()
e[["y"]] <- 1:10
fx(e)

gives me :

 > fx(e)
sum(y)
Erreur dans fx(e) : objet 'y' introuvable

Not sure what the problem is.

-- 
Romain Francois
Professional R Enthusiast
+33(0) 6 28 91 30 30
http://romainfrancois.blog.free.fr
|- http://bit.ly/bklUXt : RcppArmadillo 0.2.1
|- http://bit.ly/936ck2 : Rcpp 0.8.0
`- http://bit.ly/9aKDM9 : embed images in Rd documents




More information about the Rcpp-devel mailing list