求解一个简单的(?)非线性方程组
solving a simple (?) system of nonlinear equations
我正在尝试求解此 post 中描述的一个简单的非线性方程组。
系统是两个方程,有两个未知数 p 和 q 以及一个自由参数 lambda:
当 lambda = 1 时,系统如下所示:
存在唯一解,在p = 0.3, q = 0.1附近
我正在尝试用 nleqslv
解决它。我的 objective 函数是:
library(nleqslv)
fn = function(x, lambda = 1){
# p = x[1]
# q = x[2]
pstar = exp(lambda * (1*x[2])) / (exp(lambda * (1*x[2])) + exp(lambda * (1 - x[2])))
qstar = exp(lambda * (1 - x[1])) / (exp(lambda * ((1 - x[1]))) + exp(lambda * (9*x[1])))
return(c(pstar,qstar))
}
但结果与剧情不符:
> xstart = c(0.1, 0.3)
> nleqslv(xstart, fn)$x
[1] 1.994155 -8.921285
我的第一个问题是:我是否正确使用了 nleqslv
?在看了其他例子之后,我是这么认为的。但是现在我不确定。
我的第二个问题:nleqslv 是个好问题吗?还是我找错树了?
您的函数没有正确反映您的需求。
你可以通过如下评估fn(c(0.3,0.1))
看到这一点。
fn(c(0.3,0.1))
[1] 0.3100255 0.1192029
所以输出与输入非常接近。你想要(几乎)零作为输出。
所以你想解决p
和q
的系统。
您需要做的是使您的函数 return 输入 p
与 pstar
的表达式之间的差异以及输入 q
与 q
的表达式之间的差异=20=].
所以重写你的函数如下
fn <- function(x, lambda = 1){
p <- x[1]
q <- x[2]
pstar <- exp(lambda * (1*x[2])) / (exp(lambda * (1*x[2])) + exp(lambda * (1 - x[2])))
qstar <- exp(lambda * (1 - x[1])) / (exp(lambda * ((1 - x[1]))) + exp(lambda * (9*x[1])))
return(c(pstar-p,qstar-q))
}
然后调用 nleqslv
如下(请始终显示您正在使用的所有代码。您遗漏了 library(nleqslv)
)。
library(nleqslv)
xstart <- c(0.1, 0.3)
nleqslv(xstart, fn)
这将显示函数的完整输出。检查是否成功总是一个好主意。始终检查 $termcd
是否成功。
$x
[1] 0.3127804 0.1064237
$fvec
[1] 5.070055e-11 6.547240e-09
$termcd
[1] 1
$message
[1] "Function criterion near zero"
$scalex
[1] 1 1
$nfcnt
[1] 7
$njcnt
[1] 1
$iter
[1] 7
$x
的结果更符合您的预期。
最后请用<-
赋值。如果你不这样做,那一天你就会被 R
及其魔力所咬。
这个问题用nleqslv
没有错。你只是犯了一个小错误。
我正在尝试求解此 post 中描述的一个简单的非线性方程组。
系统是两个方程,有两个未知数 p 和 q 以及一个自由参数 lambda:
当 lambda = 1 时,系统如下所示:
存在唯一解,在p = 0.3, q = 0.1附近
我正在尝试用 nleqslv
解决它。我的 objective 函数是:
library(nleqslv)
fn = function(x, lambda = 1){
# p = x[1]
# q = x[2]
pstar = exp(lambda * (1*x[2])) / (exp(lambda * (1*x[2])) + exp(lambda * (1 - x[2])))
qstar = exp(lambda * (1 - x[1])) / (exp(lambda * ((1 - x[1]))) + exp(lambda * (9*x[1])))
return(c(pstar,qstar))
}
但结果与剧情不符:
> xstart = c(0.1, 0.3)
> nleqslv(xstart, fn)$x
[1] 1.994155 -8.921285
我的第一个问题是:我是否正确使用了 nleqslv
?在看了其他例子之后,我是这么认为的。但是现在我不确定。
我的第二个问题:nleqslv 是个好问题吗?还是我找错树了?
您的函数没有正确反映您的需求。
你可以通过如下评估fn(c(0.3,0.1))
看到这一点。
fn(c(0.3,0.1))
[1] 0.3100255 0.1192029
所以输出与输入非常接近。你想要(几乎)零作为输出。
所以你想解决p
和q
的系统。
您需要做的是使您的函数 return 输入 p
与 pstar
的表达式之间的差异以及输入 q
与 q
的表达式之间的差异=20=].
所以重写你的函数如下
fn <- function(x, lambda = 1){
p <- x[1]
q <- x[2]
pstar <- exp(lambda * (1*x[2])) / (exp(lambda * (1*x[2])) + exp(lambda * (1 - x[2])))
qstar <- exp(lambda * (1 - x[1])) / (exp(lambda * ((1 - x[1]))) + exp(lambda * (9*x[1])))
return(c(pstar-p,qstar-q))
}
然后调用 nleqslv
如下(请始终显示您正在使用的所有代码。您遗漏了 library(nleqslv)
)。
library(nleqslv)
xstart <- c(0.1, 0.3)
nleqslv(xstart, fn)
这将显示函数的完整输出。检查是否成功总是一个好主意。始终检查 $termcd
是否成功。
$x
[1] 0.3127804 0.1064237
$fvec
[1] 5.070055e-11 6.547240e-09
$termcd
[1] 1
$message
[1] "Function criterion near zero"
$scalex
[1] 1 1
$nfcnt
[1] 7
$njcnt
[1] 1
$iter
[1] 7
$x
的结果更符合您的预期。
最后请用<-
赋值。如果你不这样做,那一天你就会被 R
及其魔力所咬。
这个问题用nleqslv
没有错。你只是犯了一个小错误。