Trying to fit a three mechanism non-linear membrane fouling model which includes an integral expression. Tried to extend Example 1 from nls.lm {minpack.lm} help page. Question: How would I modify Example 1 to include an integral expression? Made various attempts after some searching and this seems the closest I could get but still gives me the following error ("Error in match.fun(f) : 'exp(1)^(xx * parS$b)' is not a function, character or symbol") and of course does not plot the curve fit. Any assistance is greatly appreciated!
require(minpack.lm)
###### example 1 + 'integrate() function
## values over which to simulate data
x <- seq(0,5,length=100)
xo <- x[1]
## two models based on a list of parameters
integrand <- function(parS=pp, xx=x) exp(1)^(xx * parS$b)
getPred <- function(parS, xx) parS$a * exp(xx * parS$b) + parS$c
getPred2 = function(parS, xx) parS$a * exp(xx * parS$b)+ integrate(integrand, lower=xo, upper=xx) + parS$c
## parameter values used to simulate data
pp <- list(a=9,b=-1, c=6)
## simulated data, with noise
simDNoisy <- getPred(pp,x) + rnorm(length(x),sd=.1); simDNoisy
simDNoisy2 <- getPred2(pp,x) + rnorm(length(x),sd=.1); simDNoisy2
## plot data
plot(x,simDNoisy, main="data")
## residual functions
residFun <- function(p, observed, xx) observed - getPred(p,xx)
residFun2 <- function(p, observed, xx) observed - getPred2(p,xx)
## starting values for parameters
parStart <- list(a=3,b=-.001, c=1)
## perform fit
nls.out <- nls.lm(par=parStart, fn = residFun, observed = simDNoisy, xx = x)
nls.out2 <- nls.lm(par=parStart, fn = residFun2, observed = simDNoisy, xx = x)
## plot model evaluated at final parameter estimates
lines(x, getPred(as.list(coef(nls.out)), x), col=2, lwd=2)
lines(x, getPred2(as.list(coef(nls.out2)), x), col=3, lty=2,lwd=2)
## summary information on parameter estimates
summary(nls.out)
summary(nls.out2
)
Modified code as suggested by NRussel and included an integrand but still getting error: "Error in parS$b : $ operator is invalid for atomic vectors" trying to figure out why. Thanks
How to pass vector to integrate function
The answer provided in link 1 by Roland helped to determine how to vectorize the integral part; but still trying to figure out how to pass the integral with parameters into a predictor function for nls.lm(). The revised piece of code is below:
# vectorize integrand and plot of results
integrand <- function(parS, xx) exp(1)^(xx * parS$b)
res = c()
for(ii in 1:100){
res[ii] = integrate(Vectorize(integrand, vectorize.args="xx"), lower=xo, upper=x[ii], parS=pp)
}
inres = unlist(res)
x
plot(x, inres)