On Tue, 25 Feb 2014, Rolf Turner <r.tur...@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 ______________________________________________ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.