0

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)
Community
  • 1
  • 1
VincePi
  • 45
  • 1
  • 8
  • The first argument to `integrate` needs to be a `function`, but you passing it `exp(1)^(xx * parS$b)`, which has already been evaluated to `exp(1)*(seq(0,5,length=100) * (-1))` by the interpreter. Since that isn't expressed in terms of any variable, you essentially are telling it to integrate over a vector of 100 constants. I don't know what function you are *trying* to integrate, but you should be doing something like `integrate(function(z) { ... }, lower=xo, upper=xx`. – nrussell Jul 07 '15 at 16:31
  • Thanks! looking into making suggested modifications. – VincePi Jul 07 '15 at 17:18
  • Added a short code snipped on how to vectorize the integrand based on Roland's reply. Still trying to figure out how to pass an integral function with parameters to a predictor function for nls.lm. Thanks! – VincePi Jul 07 '15 at 18:32

0 Answers0