[R] Environmental problems.

Enrico Schumann es at enricoschumann.net
Tue Feb 25 12:56:10 CET 2014


On Tue, 25 Feb 2014, Rolf Turner <r.turner at auckland.ac.nz> writes:

> I have a function that makes use of the ode() function from the
> "deSolve" package.  I am trying to find a way of getting it to put out
> a "progress report" every "t.int" time units (by "progress report" I
> just mean reporting what time it's got up to).
>
> I thought to put code something like the following in my "func"
> function that gets called by (is an argument to) ode():
>
>> cat("Before: time =",tt,"tdone =",tdone,"diff =",tt-tdone,"\n")
>> if(tt - tdone >= 0.1-sqrt(.Machine$double.eps)) {
>>     cat("Prog. Rep.: time =",tt,"tdone =",tdone,"diff =",tt-tdone,"\n")
>>     assign("tdone",tt,envir=parent.env(environment()))
>> }
>> cat("After: time =",tt,"tdone =",tdone,"diff =",tt-tdone,"\n")
>
> The object "tdone" gets initialized (to 0) outside of func(), so there
> is not a problem with "tdone" not being found the first time that
> func() gets called by ode().  (I'm hardwiring "t.int=0.1" in the
> forgoing just for test/illustration purposes.)  The "Before" and
> "After" cat()-s are there to demonstrate what goes wrong.
>
> What goes wrong is that I get no progress report and tdone remains
> equal to 0 until tt reaches 0.1. As desired. I then get a progress
> report and tdone gets set equal to the first value of tt which is
> greater than 0.1. As desired.
>
> Then I get no further progress reports and tdone gets set equal to tt
> at every call to func() --- even though tt - tdone = 0 which is less
> than 0.1 so the assignment of tdone cannot occur.  And yet it does,
> keeping the difference equal to 0.  (*Not* as desired!)
>
> So the function is recognizing that the difference is less than 0.1 in
> that it does not execute the cat() statement.  Yet it executes the
> assign() statement.  This is clearly impossible! :-)  But it happens.
>
> The output from the cat()-ing, around time = 0.1, looks like:
>
>> Before: time = 0.09364548 tdone = 0 diff = 0.09364548
>> After: time = 0.09364548 tdone = 0 diff = 0.09364548
>> Before: time = 0.0975779 tdone = 0 diff = 0.0975779
>> After: time = 0.0975779 tdone = 0 diff = 0.0975779
>> Before: time = 0.0975779 tdone = 0 diff = 0.0975779
>> After: time = 0.0975779 tdone = 0 diff = 0.0975779
>> Before: time = 0.09698997 tdone = 0 diff = 0.09698997
>> After: time = 0.09698997 tdone = 0 diff = 0.09698997
>> Before: time = 0.1009224 tdone = 0 diff = 0.1009224
>> Prog. Rep.: time = 0.1009224 tdone = 0 diff = 0.1009224
>> After: time = 0.1009224 tdone = 0.1009224 diff = 0
>> Before: time = 0.1009224 tdone = 0.1009224 diff = 0
>> After: time = 0.1009224 tdone = 0.1009224 diff = 0
>> Before: time = 0.1003344 tdone = 0.1003344 diff = 0  <--------------|
>> After: time = 0.1003344 tdone = 0.1003344 diff = 0
>> Before: time = 0.1042669 tdone = 0.1042669 diff = 0
>> After: time = 0.1042669 tdone = 0.1042669 diff = 0
>
> It's at that line indicated by "<----|", 4 lines from the bottom of
> the forgoing display, where things go to hell in a handcart.  Why (how
> on earth can) tdone change from 0.1009224 to 0.1003344, given that the
> difference is 0 whence no assignment of tdone should take place?
>
> What am I not seeing?  Can anyone help me out?  I'm going mad!
> ***MAD*** I tell you! :-)
>
> Suggestions as to a better way of accomplishing my desired goal of
> producing progress reports would also be welcome.
>
> I am not at all sure that assigning "tdone" in
> parent.env(environment()) is the right thing to do.  I need to assign
> it in such a way and in such a location that its value will persist
> from call to call of "func".  Words of wisdom about this would be
> gratefully received.  (I don't really grok environments.  I just try
> things until *something* works!)
>
> cheers,
>
> Rolf Turner
>

I did not follow your example, neither do I use the deSolve package; but
why not pass an environment as an argument?

  ## some iterative function that takes another fun as argument
  outer <- function(fun, ...) {
      for (i in 1:20)
          fun(...)
  }
  
  ## create an environment ...
  info <- new.env()
  info$tt <- 0
    
  ## ... and pass it as an argument
  myfun <-function(e) {
      e$tt <- e$tt + 1
      cat("Iteration ", e$tt, "\n")
  }

  outer(myfun, info)
  info$tt


-- 
Enrico Schumann
Lucerne, Switzerland
http://enricoschumann.net




More information about the R-help mailing list