[R] Fwd: Using odesolve to produce non-negative solutions

Martin Henry H. Stevens HStevens at MUOhio.edu
Mon Jun 11 18:18:36 CEST 2007


Hi Jeremy,
First, setting hmax to a small number could prevent a large step, if  
you think that is a problem. Second, however, I don't see how you can  
get a negative population size when using the log trick. I would  
think that that would prevent completely any negative values of N  
(i.e. e^-100000 > 0). Can you explain? or do you want to a void that  
trick? The only other solver I know of is rk4 and it is not recommended.
Hank
On Jun 11, 2007, at 11:46 AM, Jeremy Goldhaber-Fiebert wrote:

> Hi Spencer,
>
> Thank you for your response. I also did not see anything on the  
> lsoda help page which is the reason that I wrote to the list.
>
>> From your response, I am not sure if I asked my question clearly.
>
> I am modeling a group of people (in a variety of health states)  
> moving through time (and getting infected with an infectious  
> disease). This means that the count of the number of people in each  
> state should be positive at all times.
>
> What appears to happen is that lsoda asks for a derivative at a  
> given point in time t and then adjusts the state of the population.  
> However, perhaps due to numerical instability, it occasionally  
> lower the population count below 0 for one of the health states  
> (perhaps because it's step size is too big or something).
>
> I have tried both the logarithm trick and also changing the  
> relative and absolute tolerance inputs but I still get the problem  
> for certain combinations of parameters and initial conditions.
>
> It occurs both under MS Windows XP Service Pack 2 and on a Linux  
> cluster so I am pretty sure it is not platform specific.
>
> My real question to the group is if there is not a work around in  
> lsoda are there other ode solvers in R that will allow the  
> constraint of solutions to the ODEs remain non-negative?
>
> Best regards,
> Jeremy
>
>
>>>> Spencer Graves <spencer.graves at pdf.com> 6/8/2007 9:51 AM >>>
> On the 'lsoda' help page, I did not see any option to force some
> or all parameters to be nonnegative.
>
>       Have you considered replacing the parameters that must be
> nonnegative with their logarithms?  This effective moves the 0 lower
> limit to (-Inf) and seems to have worked well for me in the past.
> Often, it can even make the log likelihood or sum of squares surface
> more elliptical, which means that the standard normal approximation  
> for
> the sampling distribution of parameter estimates will likely be more
> accurate.
>
>       Hope this helps.
>       Spencer Graves
> p.s.  Your example seems not to be self contained.  If I could have
> easily copied it from your email and run it myself, I might have been
> able to offer more useful suggestions.
>
> Jeremy Goldhaber-Fiebert wrote:
>> Hello,
>>
>> I am using odesolve to simulate a group of people moving through  
>> time and transmitting infections to one another.
>>
>> In Matlab, there is a NonNegative option which tells the Matlab  
>> solver to keep the vector elements of the ODE solution non- 
>> negative at all times. What is the right way to do this in R?
>>
>> Thanks,
>> Jeremy
>>
>> P.S., Below is a simplified version of the code I use to try to do  
>> this, but I am not sure that it is theoretically right
>>
>> dynmodel <- function(t,y,p)
>> {
>> ## Initialize parameter values
>>
>> 	birth <- p$mybirth(t)
>> 	death <- p$mydeath(t)
>> 	recover <- p$myrecover
>> 	beta <- p$mybeta
>> 	vaxeff <- p$myvaxeff
>> 	vaccinated <- p$myvax(t)
>>
>> 	vax <- vaxeff*vaccinated/100
>>
>> ## If the state currently has negative quantities (shouldn't  
>> have), then reset to reasonable values for computing meaningful  
>> derivatives
>>
>> 	for (i in 1:length(y)) {
>> 		if (y[i]<0) {
>> 			y[i] <- 0
>> 		}
>> 	}
>>
>> 	S <- y[1]
>> 	I <- y[2]
>> 	R <- y[3]
>> 	N <- y[4]
>>
>> 	shat <- (birth*(1-vax)) - (death*S) - (beta*S*I/N)
>> 	ihat <- (beta*S*I/N) - (death*I) - (recover*I)
>> 	rhat <- (birth*(vax)) + (recover*I) - (death*R)
>>
>> ## Do we overshoot into negative space, if so shrink derivative to  
>> bring state to 0
>> ## then rescale the components that take the derivative negative
>>
>> 	if (shat+S<0) {
>> 		shat_old <- shat
>> 		shat <- -1*S
>> 		scaled_transmission <- (shat/shat_old)*(beta*S*I/N)
>> 		ihat <- scaled_transmission - (death*I) - (recover*I)
>> 		
>> 	}	
>> 	if (ihat+I<0) {
>> 		ihat_old <- ihat
>> 		ihat <- -1*I
>> 		scaled_recovery <- (ihat/ihat_old)*(recover*I)
>> 		rhat <- scaled_recovery +(birth*(vax)) - (death*R)
>> 	
>> 	}	
>> 	if (rhat+R<0) {
>> 		rhat <- -1*R
>> 	}	
>>
>> 	nhat <- shat + ihat + rhat
>>
>> 	if (nhat+N<0) {
>> 		nhat <- -1*N	
>> 	}	
>>
>> ## return derivatives
>>
>> 	list(c(shat,ihat,rhat,nhat),c(0))
>>
>> }
>>
>> ______________________________________________
>> R-help at stat.math.ethz.ch 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.
>>
>
> ______________________________________________
> R-help at stat.math.ethz.ch 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.



Dr. Hank Stevens, Assistant Professor
338 Pearson Hall
Botany Department
Miami University
Oxford, OH 45056

Office: (513) 529-4206
Lab: (513) 529-4262
FAX: (513) 529-4243
http://www.cas.muohio.edu/~stevenmh/
http://www.muohio.edu/ecology/
http://www.muohio.edu/botany/

"E Pluribus Unum"



More information about the R-help mailing list