Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Estimating non-monotonic bi-exponential curve fit

I am doing some pharmacokinetic analyses and am fine with non-compartmental methods. But I trying to also learn some non-linear curve-fitting techniques.

If we have the following data:

df <-  data.frame(x = c(0,2,4,8,12,24,48,72), y = c(0.000,0.05,0.0671,0.068,0.05,0.0250,0.0103,0.0043))
plot(df$x, df$y)

enter image description here

and I want to fit a non-monotonic bi-exponential curve to it as described on page 579 of this book, using the equation highlighted below:

enter image description here

I am fine with the standard bi-exponential form and finding starting values using Sbiexp, but do not know how to approach finding starting values for this equation. Would someone be able to give me some pointers?

> nls_mod_bi <-  nls(y ~ k * (exp(-b1*x) - exp(-b2*x)), start = c(k = 1, b1 = 1, b2 = 1), data = df)
Error in nlsModel(formula, mf, start, wts, scaleOffset = scOff, nDcentral = nDcntr) : 
  singular gradient matrix at initial parameter estimates
like image 584
LucaS Avatar asked Jan 26 '26 21:01

LucaS


1 Answers

Option 1: nls + SSbiexp

I think you can use SSbiexp in nls, and you don't need to manually setup the initial starting point

fit <- nls(y ~ SSbiexp(x, k1, b1, k2, b2), data = df)

f <- function(x, p = coef(fit)) {
  p["k1"] * exp(-exp(p["b1"]) * x) + p["k2"] * exp(-exp(p["b2"]) * x)
}

plot(y ~ x, df, type = "p", col = "blue")
curve(f, range(df$x), col = "red", add = TRUE)

enter image description here

Option 2: constrOptim

x <- df$x
y <- df$y
f <- function(p) {
  norm(p[1] * (exp(-p[2] * x) - exp(-p[3] * x)) - y, "2")
}
sol <- constrOptim(c(1, 0.1, 0.1), f, grad = NULL, ui = diag(3), ci = rep(0,3))
sol$par

which gives

> sol$par # (k, b1, b2)
[1] 0.10780726 0.05793686 0.43720768

which is really close to the nls approach outcome

> fit <- nls(y ~ SSbiexp(x, k1, b1, k2, b2), data = df)

> p <- coef(fit)

> c(p["k1"], exp(p["b1"]), p["k2"], exp(p["b2"]))
         k1          b1          k2          b2
-0.10802463  0.43855265  0.10774247  0.05791062
like image 70
ThomasIsCoding Avatar answered Jan 28 '26 14:01

ThomasIsCoding