如何使用 R 求解超定非线性方程组的最优解

How can I solve the optimal solution of a system of overdetermined nonlinear equations using R

library(BB)
library(nleqslv)
library(reprex)
library(ktsolve)

yfunc<-function(x){
   y<-vector()
   y[1]<-a+b*sin((238.61/365)+c)-(39393*0.00341802+149-273.15)
   y[2]<-a+b*sin((1821.2/365)+c)-(38795*0.00341802+149-273.15)
   y[3]<-a+b*sin((1946.8/365)+c)-(38875*0.00341802+149-273.15)
   y[4]<-a+b*sin((2072.4/365)+c)-(39231*0.00341802+149-273.15)
   y[5]<-a+b*sin((2111.36/365)+c)-(38505*0.00341802+149-273.15)
   y[6]<-a+b*sin((2223.12/3650)+c)-(37962*0.00341802+149-273.15)
   y
}
guess=list(a=8,b=15,c=30)
solv1<-ktsolve(yfunc,guess = guess)
#> Error in ktsolve(yfunc, guess = guess): Fewer guesses than equations.  System is underdefined.

我想用多个方程来求一个非线性方程的最优解。我应该如何配置该功能? reprex package (v2.0.1)

创建于 2021-09-01

您在 yfunc 中输入了六个方程式。 如果您想猜测 abc 并使用 ktsolve,请减少 yfunc.

中的方程数

AND 长度(猜) 必须与 yfunc 中 y[j] 方程的数量相同,以避免系统定义过度或欠定义。参见 https://cran.r-project.org/web/packages/ktsolve/ktsolve.pdf

例如,

yfunc<-function(x){
  y<-vector()
  y[1]<-a+b*sin((238.61/365)+c)-(39393*0.00341802+149-273.15)
  y[2]<-a+b*sin((1821.2/365)+c)-(38795*0.00341802+149-273.15)
  y[3]<-a+b*sin((1946.8/365)+c)-(38875*0.00341802+149-273.15)
  #y[4]<-a+b*sin((2072.4/365)+c)-(39231*0.00341802+149-273.15)
  #y[5]<-a+b*sin((2111.36/365)+c)-(38505*0.00341802+149-273.15)
  #y[6]<-a+b*sin((2223.12/3650)+c)-(37962*0.00341802+149-273.15)
  y
}

guess=list(a=8,b=15, c= 10)
solv1<-ktsolve(yfunc, guess = guess)

returns

  Successful convergence.
solution is:
        a         b         c 
 9.521837  1.238768 12.817678 

我们可以使用非线性最小二乘法找到使以下模型两侧差值的平方和最小的参数值。我们使用 plinear 算法,它只需要我们为非线性输入的参数提供起始值,在本例中只需要 c。由于有两个线性输入的参数,右侧应该是一个两列矩阵,它将矩阵乘以这些参数的向量: c(a, b) 。没有使用包。

x <- c(238.61, 1821.2, 1946.8, 2072.4, 2111.36, 2223.12) / 365
y <- c(39393, 38795, 38875, 39231, 38505, 37962) * 0.00341802 + 149 - 273.15

fm <- nls(y ~ cbind(a = 1, b = sin(x + c)), start = list(c = 30), alg = "plinear"); fm
## Nonlinear regression model
##   model: y ~ cbind(a = 1, b = sin(x + c))
##    data: parent.frame()
##      c .lin.a .lin.b 
## 30.255 12.226  4.598 
##  residual sum-of-squares: 10.72
##
## Number of iterations to convergence: 4 
## Achieved convergence tolerance: 1.47e-09