3
$\begingroup$

I have a data set in which $y$ is roughly related to $\log(x)$. Now I wish to fit the curve $$y=A(1-\exp(BX))$$

When I use R and the nls2 function, then I encounter the error SINGULAR MATRIX at initial parameters.

  • I have tried to use a model with the $a$ parameter fixed, in which case it works fine

    model2<-nls2(ynew~1000*(1-exp(bx)),data=sData,start = list(b=0.08),trace = TRUE,control = list(maxiter=1000)) 
    
  • But when I have both $a$ and $b$ as free parameters then I get the error

    model1<-nls2(ynew~A*(1-exp(bx)),data=sData,start = list(A=10,b=0.08),trace = TRUE,control = list(maxiter=1000))
    

Some similar issue is explained in this thread R nls singular gradient where they suggest to:

  • linearize to get better starting values
  • in addition use the plinear method

How can I linearize my function? I can not rewrite into a linear function by taking the logarithm.

Below is an image of my function/data. I will try to post the subset of the data

example

$\endgroup$
16
  • 4
    $\begingroup$ My guess is that the starting values are the problem. If possible, please post a graph as well as your R-code and the data. It will raise the chance of helpful answers greatly. $\endgroup$ Commented Jul 14, 2018 at 9:39
  • 1
    $\begingroup$ The basics are explained here stackoverflow.com/questions/18364402/r-nls-singular-gradient (1) use linearizion to estimate good initial starting conditions, and (2) use the plinear method (since you have this linear term a). For more help you should do like COOLSerdash suggests and post more information. For the linearization you might look into the Tittelbach Helmrich method ( iopscience.iop.org/article/10.1088/0957-0233/4/12/003 ) where you fit y with it's integrated values. $\endgroup$ Commented Jul 14, 2018 at 9:53
  • $\begingroup$ I need get model1(not working) model1<-nls2(ynew~A*(1-exp(bx)),data=sData,start = list(A=10,b=0.08),trace = TRUE,control = list(maxiter=1000)) This work fine model2<-nls2(ynew~1000*(1-exp(bx)),data=sData,start = list(b=0.08),trace = TRUE,control = list(maxiter=1000)) I will try to post the subset of the data $\endgroup$ Commented Jul 14, 2018 at 11:50
  • $\begingroup$ The $b$ parameter should be negative. But whether your initial guess about $a$ is correct is difficult to say based on your graph (although I imagine it leads to difficulties if just the sign of $b$ is wrong). Why did you not do model2 with the parameter at 10 instead of 1000, and what is the output? Is your data real data with noise or modeled data (in the second case, zero error, you may additionally get problems with the model not detecting convergence)? What is your graph representing exactly? $\endgroup$ Commented Jul 15, 2018 at 19:36
  • $\begingroup$ So your case seems to be similar to the earlier linked question about singular gradients. But your case can be considered a special case when you ask about the way to get the starting conditions. To get the initial starting conditions you can use (a variant of the Tittelbach Helmrich method) : $$ y(x) = a(1-e^{bx}) $$ and $$Y(x) = \int_{0}^x y(t) dt = a(x+\frac{1-e^{bx}}{b})$$ which you can fit (linear) like: $$y(x) = b Y(x) - ab x = b Y(x) - d x$$ and the coefficients of that fit give you good starting conditions. To calculate $Y(x)$ a numerical integration will do. $\endgroup$ Commented Jul 16, 2018 at 8:12

0