求解R中的非线性方程组

Lad*_*zyk 1 r equation-solving

假设我有以下方程组:

a * b = 5
sqrt(a * b^2) = 10
Run Code Online (Sandbox Code Playgroud)

如何在R中解决a和b的这些方程?

我想这个问题可以说是一个优化问题,具有以下功能......?

fn <- function(a, b) {

    rate <- a * b
    shape <- sqrt(a * b^2)

    return(c(rate, shape) )

}
Run Code Online (Sandbox Code Playgroud)

ngm*_*ngm 6

使用此库.

library("nleqslv")
Run Code Online (Sandbox Code Playgroud)

您需要定义要求解的多变量函数.

fn <- function(x) {

  rate <- x[1] * x[2] - 5
  shape <- sqrt(x[1] * x[2]^2) - 10

  return(c(rate, shape))

}
Run Code Online (Sandbox Code Playgroud)

然后你很高兴去.

nleqslv(c(1,5), fn)
Run Code Online (Sandbox Code Playgroud)

总是看详细的结果.数值计算可能很棘手.在这种情况下,我得到了这个:

Warning message:
In sqrt(x[1] * x[2]^2) : NaNs produced
Run Code Online (Sandbox Code Playgroud)

这只是意味着程序搜索了一个包含的区域,x[1] < 0然后可能会将这个区域反射到飞机的右侧.


G. *_*eck 5

在评论中,发帖人特别询问了使用solveoptim因此我们展示了如何手动解决此问题(1),(2)使用solve,(3)使用optim和(4)定点迭代。

1)手工首先要注意的是,如果我们a = 5/b根据第一个方程式进行书写并将其代入第二个方程式sqrt(5/b * b^2) = sqrt(5 * b) = 10,则b = 20,a = 0.25。

2)求解关于solve这些方程的使用,可以通过取双方的对数给出,将其转换为线性形式:

log(a) + log(b) = log(5)
0.5 * (loga + 2 * log(b)) = log(10)
Run Code Online (Sandbox Code Playgroud)

可以表示为:

m <- matrix(c(1, .5, 1, 1), 2)
exp(solve(m, log(c(5, 10))))
## [1]  0.25 20.00
Run Code Online (Sandbox Code Playgroud)

3)优化使用optim我们可以将其写fn在问题所在。fn2通过减去等式的RHS并使用crossprod来形成平方和,从而形成。

fn2 <- function(x) crossprod( fn(x[1], x[2]) - c(5, 10))
optim(c(1, 1), fn2)
Run Code Online (Sandbox Code Playgroud)

给予:

$par
[1]  0.2500805 19.9958117

$value
[1] 5.51508e-07

$counts
function gradient 
      97       NA 

$convergence
[1] 0

$message
NULL
Run Code Online (Sandbox Code Playgroud)

4)定点为此,我们以定点形式重写方程,即以c(a,b)= f(c(a,b))的形式进行迭代。通常,有几种方法可以做到这一点,但并非所有方法都可以收敛,但是在这种情况下,这似乎可行。我们将两者的起始值均设为1 ab然后将第一个方程的b两边除以得到定点形式的第一个方程,然后将第二个方程的两边除以sqrt(a)得到定点形式的第二个方程:

a <- b <- 1  # starting values
for(i in 1:100) {
  a = 5 / b
  b = 10 / sqrt(a)
}

data.frame(a, b)
##      a  b
## 1 0.25 20
Run Code Online (Sandbox Code Playgroud)