I've been trying to perform a nonlinear regression using the fuctions nls
and nlr
from gnlm
package but my objective function has many adjustable parameters and is easier to define it by defining a bunch of different equations first. So, I've got the data in the link (https://github.com/Shend92/Nonlinear-regression) and the following equations:
#Import data to data.frame called 'DATA'
#Equations:
ws = function (ap,bp,cp,dp,vel) {
ap*vel+cp*vel^2+dp
}
Fins = function(bs) {
(X1+X5+bs)/(522.64+bs)
}
alp = function(ap,bp,cp,dp,vel,bs) {
Fins(bs)*(ws(ap,bp,cp,dp,vel)-Fins(bs))/ws(ap,bp,cp,dp,vel)^2
}
vel.max = function(ep,fp,bs) {
ep-fp*Fins(bs)
}
del = function(vel,ep,fp,gp,bs) {
vel*(1-(1-vel.max(ep,fp,bs))*exp(-gp*(vel.max(ep,fp,bs)-vel)))
}
Le = function(hp,L,Ld,bs) {
L*(1+hp*Fins(bs)*(1-Fins(bs))*Ld/L)
}
E.s = function(ae,be,ce) {
ae*X1*X2/(100*X1)+be*X1*X3/(100*X1)+ce*(X1*X4)/(100*X1)
}
dens.0 = function(ad,bd,cd){
ad*X1*X2/(100*X1)+bd*X1*X3/(100*X1)+cd*(X1*X4)/(100*X1)
}
Fb = function(lp,Dmill,L) {
lp/(pi*Dmill^2*L)
}
dens.b = 8.05
dens.c = function(bs,ad,bd,cd,ae,be,ce,lp,Dmill,L) {
(Fins(bs)*dens.0(ad,bd,cd)*(1-E.s(ae,be,ce))+Fb(lp,Dmill,L)*
(dens.b-dens.0(ad,bd,cd))*(1-E.s(ae,be,ce)))/Fins(bs)
}
Pmo.s = function(Dmill,vel,Ld,L,ip,jp,kp) {
Dmill^ip*(vel*(jp*Ld+L))^kp
}
##Objective function
Y.s = function(K,Dmill,vel,Ld,L,ip,jp,kp,bs,ad,bd,cd,ae,be,ce,lp,ap,bp,
cp,dp,ep,fp,gp,hp) {
Pmo.s(Dmill,vel,Ld,L,ip,jp,kp)+K*Dmill^2.5*Le(hp,L,Ld,bs)*
dens.c(bs,ad,bd,cd,ae,be,ce,lp,Dmill,L)*alp(ap,bp,cp,dp,vel,bs)*
del(vel,ep,fp,gp,bs)
}
Once all my equations are defined (Note that the objective function Y.s
has all the other functions included and I checked that this final equation ran correctly with some test parameters) I tried to run the following code to fit all the adjustable parameters (K,Dmill,vel,Ld,L,ip,jp,kp,bs,ad,bd,cd,ae,be,ce,lp,ap,bp,cp,dp,ep,fp,gp,hp)
nlr.test1 <- nls(Y ~ Y.s(K,Dmill,vel,Ld,L,ip,jp,kp,bs,ad,bd,cd,ae,be,ce,lp,
ap,bp,cp,dp,ep,fp,gp,hp),
start=list(Dmill = 3.526,ap = 2.000,bp = 2.900,cp = -2.200,
dp = -0.500,ep = 0.900,fp = -0.135,gp = -19.420,
hp = 12.280,ip = 2.500,jp = 0.600,kp = 0.8,K = 2.000,
vel = 0.700,bs = 0.187,L = 15.000,Ld = 3.000,ae = 0.307,
be = 0.174,ce = 0.279,ad = 3.200,bd = 2.700,
cd = 2.749,lp=430),
algorithm = "port", ,lower=list(ap = 0,bp = 0,cp = -5,dp = -2,ep = 0,
fp = -5,gp = -100,hp = 0,ip = 0,jp = 0,kp = 0,K = 0,
Dmill = 1,vel = 0,bs = 0,L = 8,Ld = 0,ae = 0,be = 0,
ce = 0,ad = 0,bd = 0,cd = 0,lp=0), upper=list(ap = 5,
bp = 5,cp = -1,dp = 0,ep = 2,fp = 0,gp = 0,hp = 20,ip = 5,
jp = 1,kp = 2,K = 5,Dmill = 5,vel = 2,bs = 5,L = 20,
Ld = 8,ae = 1,be = 1,ce = 1,ad = 5,bd = 4,cd = 4,lp=1000),
data=DATA)
Running this code gives the following error message
Error in nlsModel(formula, mf, start, wts, upper) : singular gradient matrix at initial parameter estimates
From what I understand, this error is saying that the initial values are not good, but I think is not true because the initial values seem to be giving Y.s values close to Y real values. So I tried a different function:
nlr(Y,mu=Y.s(K,Dmill,vel,Ld,L,ip,jp,kp,bs,ad,bd,cd,ae,be,ce,lp,
ap,bp,cp,dp,ep,fp,gp,hp),
pmu=list(Dmill = 3.526,ap = 2.000,bp = 2.900,cp = -2.200,
dp = -0.500,ep = 0.900,fp = -0.135,gp = -19.420,
hp = 12.280,ip = 2.500,jp = 0.600,kp = 0.8,K = 2.000,
vel = 0.700,bs = 0.187,L = 15.000,Ld = 3.000,ae = 0.307,
be = 0.174,ce = 0.279,ad = 3.200,bd = 2.700,
cd = 2.749,lp=430))
Running this code gives the following error message:
Error in Pmo.s(Dmill, vel, Ld, L, ip, jp, kp) : object 'Dmill' not found
Now here I'm not sure what is happening because as I said before, I checked that the function was defined correctly by giving test values for all the parameters.
I know the problem is a bit difficult to understand, as it has so many parameters and equations, but I would really appreciate it if someone could at least help me by explaining why is nlr
giving me the error of not finding the defined objects in the main function. Or, if there is a better function to solve nonlinear regression problems.
Thank you so much in advance!
Sofía