简体   繁体   English

解决R中的非线性方程组

[英]Solving a system of nonlinear equations in R

Suppose I have the following system of equations: 假设我有以下方程组:

a * b = 5
sqrt(a * b^2) = 10

How can I solve these equations for a and b in R ? 如何解决R中a和b的这些方程式?

I guess this problem can be stated as an optimisation problem, with the following function... ? 我猜这个问题可以说是一个优化问题,具有以下功能...?

fn <- function(a, b) {

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

    return(c(rate, shape) )

}

Use this library. 使用此库。

library("nleqslv")

You need to define the multivariate function you want to solve for. 您需要定义要求解的多元函数。

fn <- function(x) {

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

  return(c(rate, shape))

}

Then you're good to go. 那你很好。

nleqslv(c(1,5), fn)

Always look at the detailed results. 始终查看详细结果。 Numerical calculations can be tricky. 数值计算可能很棘手。 In this case I got this: 在这种情况下,我得到了:

Warning message:
In sqrt(x[1] * x[2]^2) : NaNs produced

That just means the procedure searched a region that included x[1] < 0 and then presumably noped the heck back to the right hand side of the plane. 这仅意味着该程序搜索了一个包含x[1] < 0的区域,然后大概将点头点回到了平面的右侧。

In a comment the poster specifically asks about using solve and optim so we show how to solve this (1) by hand, (2) using solve , (3) using optim and (4) a fixed point iteration. 在评论中,发帖人特别询问如何使用solveoptim因此我们展示了如何手动解决(1),(2)使用solve ,(3)使用optim和(4)定点迭代。

1) by hand First note that if we write a = 5/b based on the first equation and substitute that into the second equation we get sqrt(5/b * b^2) = sqrt(5 * b) = 10 so b = 20 and a = 0.25. 1)手工首先要注意的是,如果我们根据第一个方程式写a = 5/b并将其代入第二个方程式,则得到sqrt(5/b * b^2) = sqrt(5 * b) = 10因此b = 20和a = 0.25。

2) solve Regarding the use of solve these equations can be transformed into linear form by taking the log of both sides giving: 2)解决关于使用solve这些方程可以通过取两侧给人日志转化成线性形式:

log(a) + log(b) = log(5)
0.5 * (loga + 2 * log(b)) = log(10)

which can be expressed as: 可以表示为:

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

3) optim Using optim we can write this where fn is from the question. 3)优化使用optim我们可以将fn写入问题中。 fn2 is formed by subtracting off the RHS of the equations and using crossprod to form the sum of squares. 通过减去方程式的RHS并使用crossprod来形成平方和,从而形成fn2

fn2 <- function(x) crossprod( fn(x[1], x[2]) - c(5, 10))
optim(c(1, 1), fn2)

giving: 给予:

$par
[1]  0.2500805 19.9958117

$value
[1] 5.51508e-07

$counts
function gradient 
      97       NA 

$convergence
[1] 0

$message
NULL

4) fixed point For this one rewrite the equations in a fixed point form, ie in the form c(a, b) = f(c(a, b)) and then iterate. 4)定点为此,我们以定点形式(即c(a,b)= f(c(a,b))形式)重写方程,然后进行迭代。 In general, there will be several ways to do this and not all of them will converge but in this case this seems to work. 通常,有几种方法可以做到这一点,但并非所有方法都可以收敛,但是在这种情况下,这似乎可行。 We use starting values of 1 for both a and b and divide both side of the first equation by b to get the first equation in fixed point form and we divide both sides of the second equation by sqrt(a) to get the second equation in fixed point form: 我们对ab都使用1的起始值,并将第一个方程的两边除以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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM