R中的迭代计算

时间:2019-09-20 20:44:03

标签: r

假设我们有一些变量:

s = 95
k = 100
r = .05
g = sx * .1
sx = s - px
px = need to solve for this

您将如何设置r来解决此问题?在Excel中,您可以创建目标单元格,通过“目标搜索”或“求解器”将其称为y为零。这涉及到迭代计算。

y = px - s/k-1 * r - g

Excel会通过将y减小为零来计算px。

这里px = 9.45945

该如何处理?

3 个答案:

答案 0 :(得分:3)

首先让我们澄清一下,问题是要解决三个未知数中的三个变量的系统。那就是:

Solve this system of 3 equations in the 3 unknowns px, sx and g:

       0.1 * sx      - g  = 0 
 px +        sx           = s 
 px                  - g  = s/k-1 * r

where s, k and r are known constants given in the question and we have 
rearranged the equations to put the constant terms on the right hand
side and have vertically aligned the variables on the left hand side.

这个方程组实际上很容易手动求解(通过用s-px替换第一个方程中的sx来消除sx,然后减去剩余的两个方程以消除g。最后,在一个未知数中剩下一个方程很容易解决)。由于这里的目的是使用R,因此我们展示了几种使用R的不同方法。

1)线性代数由于这些是线性方程式,我们可以将其公式化为矩阵问题并求解。矩阵m由上述等式的系数组成。 m的第一列是px的系数,下一列是sx的系数,最后一列是g的系数。例如,在三个等式中,px的系数分别为0、1和1。右侧向量为rhssolve可用于概念上反转m并将其乘以rhs

不使用任何程序包,不涉及任何显式的迭代计算,并且不需要将一个公式手动替换为另一个公式。我们按原样处理这三个方程,然后让计算机求解它们。

s <- 95; k <- 100; r <- .05
m <- matrix(c(0, 1, 1,   0.1, 1, 0,   -1, 0, -1), 3)
rhs <- c(0, s, s/k-1 * r)

solve(m, rhs)
## [1]  9.454545 85.545455  8.554545

以上输出向量中的值为pxsxg的值。

2)定点迭代,如果我们估计为px,则从 第二个方程式我们可以得到sx的估计值,并使用 第一个方程我们可以得到g的估计,从中我们可以 使用第三个方程获得px的新估计。将其写为函数f时,我们从初始估计1开始,然后对其进行迭代直到值收敛。不使用任何软件包。

f <- function(px) {
  sx <- s - px
  g <- .1 * sx
  s/k-1 * r + g 
}

px <- 1
for(i in 1:50) {
  prev <- px
  px <- f(px)
  cat(i, px, "\n")
  if (abs(px - prev) < 1e-5) break
}

## 1 10.3 
## 2 9.37 
## 3 9.463 
## 4 9.4537 
## 5 9.45463 
## 6 9.454537 
## 7 9.454546 

2a)优化我们可以交替使用optimize(在R的底部)以最小化f(x)x之间{{ 1}}:

px

2b)uniroot 或使用optimize(function(px) (f(px) - px)^2, c(0, 100)) ## $minimum ## [1] 9.454545 ## ## $objective ## [1] 3.155444e-30 (也以R为底)来找到f(px)-px的根:

uniroot

3)Ryacas 下面,我们使用Ryacas软件包进行设置,该软件包允许直接对三个方程式进行符号说明。

uniroot(function(px) f(px) - px, c(0, 100))
## $root
## [1] 9.454545
## 
## $f.root
## [1] 0
##
## $iter
## [1] 1
##
## $init.it
## [1] NA
##
## $estim.prec
## [1] 90.54545

给予:

# devtools::install_github("mikldk/ryacas0")

library(Ryacas0)

s <- 95
k <- 100
r <- .05

sx <- Sym("sx")
px <- Sym("px")
g <- Sym("g")

res <- Solve(List(g == sx * 0.1, sx == s - px, px - s/k-1 * r - g == 0), 
   List(px, sx, g))

上面的值是作为符号表达式的精确值,但我们可以对它们进行求值,以获得类似于以下的浮点近似值:

res
## Yacas matrix:
##      [,1]            [,2]           [,3]        
## [1,] px == 1.05/0.11 sx == 9.4/0.11 g == 9.4/1.1

答案 1 :(得分:3)

经过一些代数运算后,px - s/k-1 * r - g == 0的闭合形式的解为

px <- (10*k*r + 10*s + k*s)/(11*k)
# [1] 9.545455

使用nleqslv软件包的解决方案:

library(nleqslv)

fn <- function(px) {
  s <- 95
  k <- 100
  r <- .05
  sx <- s - px
  g <- sx * .1
  y <- px - s/k-1 * r - g
  return(y)
}

nleqslv(1, fn)

# $x
# [1] 9.545455
# ...

答案 2 :(得分:1)

这是一个基本的R解决方案,只要它可以解决线性方程式,就可以使用。

s = 95
k = 100
r = .05

g = function(sx) {
    sx * 0.1
}

sx = function(px) {
    s - px
}

fn = function(px) {
    px - s/k - 1 * r - g(sx(px))
}

foo = function(fn) {
    x1 = 1
    x2 = 2
    y1 = fn(x1)
    y2 = fn(x2)
    m = (y2 - y1)/(x2 - x1)  # Line slope
    solve(-m, -m * x1 + y1)
}

foo(fn)
#> [1] 9.545455