使用约束来使用nlsLM()

MaM*_*aMu 3 r constraints nls

nlsLM {minpack.lm}用来找到最适合数据集的参数ab函数的值myfun,mydata.

mydata=data.frame(x=c(0,5,9,13,17,20),y = c(0,11,20,29,38,45))

myfun=function(a,b,r,t){
  prd=a*b*(1-exp(-b*r*t))
  return(prd)
}
Run Code Online (Sandbox Code Playgroud)

和使用 nlsLM

myfit=nlsLM(y~myfun(a,b,r=2,t=x),data=mydata,start=list(a=2000,b=0.05),
                  lower = c(1000,0), upper = c(3000,1))
Run Code Online (Sandbox Code Playgroud)

有用.但是现在我想引入一个约束条件a*b<1000.我查看了可nlsLM用于设置约束的选项nls.lm.control.但它没有多大帮助.有人可以帮助我或建议一个不同的方法吗?

Mar*_*dri 6

据我所知,在minpack.lm包的nlsLM中,下限和上限参数是唯一可用的约束.
一个可能的问题解决方案是基于包的使用nloptr,一个R接口到免费的开源库NLopt进行非线性优化.
在我使用的代码中,使用cobyla非线性不等式和等式约束的无导数优化算法:

mydata <- data.frame(x=c(0,5,9,13,17,20), y=c(0,11,20,29,38,45))

myfun=function(a,b,r,t){
  prd=a*b*(1-exp(-b*r*t))
  return(prd)
}

library(nloptr)

sse <- function(ab,r,x,y){
   sum((y - myfun(ab[1],ab[2],r,x))^2)
}

nonlincons <- function(ab,r,x,y) {
   h <- numeric(1)
   h[1] <-  1000 - ab[1]*ab[2]
   return(h)
}

x0 <- c(2000,0.05)
optpar <- cobyla(x0=x0, fn=sse, lower = c(1000,0), upper = c(3000,1), 
                 hin=nonlincons, r=2, x=mydata$x, y=mydata$y, 
                 control = list(xtol_rel = 1e-12, maxeval = 20000))
(optpar <- optpar$par)

sum((mydata$y-myfun(optpar[1],optpar[2],r=2,mydata$x))^2)
Run Code Online (Sandbox Code Playgroud)

最佳参数的值为:

[1] 3.000000e+03 2.288303e-02
Run Code Online (Sandbox Code Playgroud)

并且误差平方和是:

[1] 38.02078
Run Code Online (Sandbox Code Playgroud)

希望它可以帮到你.