Reputation: 61
Working in R, I am trying to use nls()
to fit some data to the following model:
y ~ c - a * exp(-b * x)
My data:
x <- c(8, 8, 10, 10, 10, 10, 12, 12, 12, 12, 14, 14, 14, 16, 16, 16, 18, 18, 20, 20, 20, 22, 22, 22, 24, 24, 24, 26, 26, 26, 28, 28, 30, 30, 30, 32, 32, 34, 36, 36, 38, 38, 40, 42)
y <- c(0.49, 0.49, 0.48, 0.47, 0.48, 0.47, 0.46, 0.46, 0.45, 0.43, 0.45, 0.43, 0.43, 0.44, 0.43, 0.43, 0.46, 0.45, 0.42, 0.42, 0.43, 0.41, 0.41, 0.40, 0.42, 0.40, 0.40, 0.41, 0.40, 0.41, 0.41, 0.40, 0.40, 0.40, 0.38, 0.41, 0.40, 0.40, 0.41, 0.38, 0.40, 0.40, 0.39, 0.39)
data <- data.frame(x, y)
Check to see if data fits the form of the model:
The book I'm working with says the coefficient estimates should be: c=0.3896, a=-0.2194, b=0.992.
My attempt using the given values, based on this thread 2, returns a singular gradient error:
m <- nls(y ~ I(c-a*exp(-b*x)), data=data, start=list(a=-.2194, b=1, c=0.3), trace=T)
I get acceptable values when I try to fit y ~ a * exp(-b * x)
and y ~ exp(-b * x)
, but when I add the "c" term, I get the singular gradient error. I've also tried using nlsLM, which had the same issue, so I think it has to do with how I'm adding in that intercept term. Any advice is appreciated, thank you.
Upvotes: 3
Views: 99
Reputation: 269586
Use the plinear algorithm in which case starting values are not needed for the parameters that enter linearly. In that case the right hand side should be a matrix such that each column multiplies one of the parameters that enters linearly.
fm <- nls(y ~ cbind(c = 1, a = -exp(-b*x)), data,
start = list(b = 1), alg = "plinear")
fm
giving:
Nonlinear regression model
model: y ~ cbind(c = 1, a = -exp(-b * x))
data: data
b .lin.c .lin.a
0.09916 0.38963 -0.21940
residual sum-of-squares: 0.004997
Number of iterations to convergence: 6
Achieved convergence tolerance: 3.075e-07
We can examine the fit visually:
plot(y ~ x, data)
lines(fitted(fm) ~ x, data, col = "red")
Upvotes: 3