使用 R 中的 nleqslv 包求解非线性方程

Solve non-linear equation using nleqslv package in R

我是 R 的新手,我正在尝试求解一个非线性方程。该等式是 4 个变量的函数:QDE2+zy1.new。我将 QDE2+z 的值存储在长度为 3364 的单个向量中。对于这些情况中的每一种,我想找到 y1.new 满足下面的等式

0 =  `y1.new` + (`Q`/((`D`^2)/8)*(2*acos(1-2*`y1.new`/`D`) - sin(2*acos(1-2*`y1.new`/`D`))))^2/(2*9.81) - `E2+z`.

我设置一个函数为

target.y1.new <- function(y1.new, Q=Q,D=D,`E2+z`=`E2+z`,g=9.81)
{
  y <- numeric(1)
  y[1] <- `y1.new` + (`Q`/((`D`^2)/8)*(2*acos(1-2*`y1.new`/`D`) - sin(2*acos(1-2*`y1.new`/`D`))))^2/(2*`g`) - `E2+z`
}

我的初始猜测存储在一个名为 y1 的向量中,也有 3364 个值

我尝试使用函数

nleqslv(`y1`,`target.y1.new`,control=list(btol=0.01),jacobian=TRUE)

但它会导致错误

Error in fn(par, ...) :
promise already under evaluation: recursive default argument reference or earlier problems?

谁能告诉我这里做错了什么?

提前致谢,
本尼

睿说的对。您在不需要的地方使用了反引号。

简化并更正您的函数 target.y1.new 结果

target.y1.new <- function(y1.new,g=9.81)
{
  y <- numeric(length(y1.new))
  y <- y1.new + (Q/((D^2)/8)*(2*acos(1-2*y1.new/D) - sin(2*acos(1-2*y1.new/D))))^2/(2*g) - E2pz
  y
}

你说你有长度为 3364 的向量。你的函数适用于向量。这意味着您的函数应该 return 一个长度为 3364 的向量,这就是 return 值 y 的定义应该与输入向量具有相同长度的原因。

有了一些试用值,我们可以试试这个

Q <- c(1,2)
D <- c(1,2)
E2pz <- c(1,2)
y1 <- rep(.1,2) 

您现在可以执行以下操作

nleqslv(y1,target.y1.new,control=list(btol=0.01),jacobian=TRUE)  

这会给你一个解决方案。 但它不是最有效的。你的方程组是对角线的,因为任何方程的输入 y 不会出现在任何其他方程中。

nleqslv 有一个指定带(包括对角线)jacobian 的选项(参见手册)。如下

nleqslv(y1,target.y1.new,control=list(btol=0.01,dsub=0,dsuper=0),
        jacobian=TRUE,method="Newton")

在这种情况下,最好使用 Newton 方法,因为默认的 Broyden 方法会做太多的工作。它不适用于对角雅可比矩阵。