Daaviid
Daaviid

Reputation: 97

R - Singular gradient matrix at initial parameter estimates

I'm trying to fit a harmonic equation to my data, but when I'm applying the nls function, R gives me the following error:

Error in nlsModel(formula, mf, start, wts) : singular gradient matrix at initial parameter estimates.

All posts I've seen, related to this error, are of exponential functions, where a linearization is used to fix this error, but in this case, I'm not able to solve it in this way. I tried to use other starting points but it still not working.

CODE:

y <- c(20.91676, 20.65219, 20.39272, 20.58692, 21.64712, 23.30965, 23.35657, 24.22724, 24.83439, 24.34865, 23.13173, 21.96117)
t <- c(1, 2, 3, 4 , 5 , 6, 7, 8, 9, 10, 11, 12)


# Fitting function

fit <- function(x, a, b, c) {a+b*sin(2*pi*x)+c*cos(2*pi*x)}

res <- nls(y ~ fit(t, a, b, c), data=data.frame(t,y), start = list(a=1,b=0, c=1))

Can you help me? Thanks!

Upvotes: 1

Views: 4909

Answers (1)

G. Grothendieck
G. Grothendieck

Reputation: 269441

There are several problems:

  1. cos(2*pi*t) is a vector of all ones for the t given in the question so the model is not identifiable given that there is already an intercept

  2. the model is linear in the parameters so one can use lm rather than nls and no starting values are needed

  3. the model does not work well even if we address those points as seen by the large second coefficient. Improve the model.

lm(y ~ sin(2*pi*t))

giving:

Call:
lm(formula = y ~ sin(2 * pi * t))

Coefficients:
    (Intercept)  sin(2 * pi * t)  
      2.195e+01       -2.262e+14  

Instead try this model using the plinear algorithm which does not require starting values for the parameters that enter linearly. This implements the model .lin1 + .lin2 * cos(a * t + b) where the .lin1 and .lin2 parameters are implicit parameters that enter linearly and don't need starting values.

fm <- nls(y ~ cbind(1, cos(a * t + b)), start = list(a = 1, b = 1), alg = "plinear")

plot(y ~ t)
lines(fitted(fm) ~ t, col = "red")

fm

giving:

Nonlinear regression model
  model: y ~ cbind(1, cos(a * t + b))
   data: parent.frame()
      a       b   .lin1   .lin2 
 0.5226  4.8814 22.4454 -2.1530 
 residual sum-of-squares: 0.7947

Number of iterations to convergence: 9 
Achieved convergence tolerance: 8.865e-06

screenshot

Upvotes: 1

Related Questions