R中的Pi估计

a7qyws3x  于 2023-02-10  发布在  其他
关注(0)|答案(4)|浏览(236)

下面的代码估计R中的pi,现在我试图找到在估计pie时必须包含的最小项数N_Min,以使其精确到小数点后三位。

pi_Est<- function(NTerms){
  NTerms = 5 # start with an estimate of just five terms
  pi_Est = 0 # initialise the value of pi to zero
  Sum_i = NA # initialise the summation variable to null
  for(ii in 1:NTerms)
  {
    Sum_i[ii] = (-1)^(ii+1)/(2*ii - 1)  # this is the series equation for calculating pi
  }
  Sum_i = 4*Sum_i # multiply by four as required in the formula (see lecture notes)
  
  pi_Est = sum(Sum_i)
  cat('\nThe estimate of pi with terms = ', NTerms ,' is ',pi_Est)
  
}
oalqel3c

oalqel3c1#

首先,我会改变你的函数的一些东西,让它返回一个值,而不是打印出一条消息,否则它会变得很难对它的输出做任何事情,包括测试它是否收敛到pi。
此外,无论NTerms的值是多少,您都会立即覆盖函数内部的NTerms
您可以将函数重写为:

pi_Est <- function(NTerms) {
  
  pi_Est <- 0 
  Sum_i  <- numeric()
  
  for(ii in seq(NTerms))
  {
    Sum_i[ii] <- (-1)^(ii+1)/(2*ii - 1) 
  }
  
  return(sum(4 * Sum_i))
}

为了证明它收敛于π,让我们用5万项来测试它:

pi_Est(50000)
#> [1] 3.141573

现在,如果我们想找到NTerms的第一个值,它精确到小数点后3位,我们需要能够在NTerms的一个 vector 上调用这个函数--目前它只对一个数字起作用,所以让我们定义一个函数f,它将pi_Est向量化:

f <- Vectorize(pi_Est)

现在,让我们为NTerms在1到2,000之间的所有值创建估计值,并将它们存储在一个向量中:

estimates <- f(1:2000)

我们可以看到,estimates的值看起来在周围振荡,如果我们画出前100个值,就会收敛到pi

plot(estimates[1:100], type = 'l')
abline(h = pi)

我们的答案是第一个值,当四舍五入到小数点后三位时,它与四舍五入到小数点后三位的pi相同:

result <- which(round(estimates, 3) == round(pi, 3))[1]

result
#> [1] 1103

我们可以通过将1103输入到原始函数中来检查这是否正确:

pi_Est(result)
#> [1] 3.142499

你会看到,这会得到3.142,这与四舍五入到小数点后3位的pi相同。
reprex package(v2.0.1)于2022年1月31日创建

thigvfpy

thigvfpy2#

需要1000项以使估计精确到0.001内:

pi_Est1 <- function(n) {
  if (n == 0) return(0)
  neg <- 1/seq(3, 2*n + 1, 4)
  if (n%%2) neg[length(neg)] <- 0
  4*sum(1/seq(1, 2*n, 4) - neg)
}

pi_Est2 <- function(tol) {
  for (i in ceiling(1/tol + 0.5):0) {
    est <- pi_Est1(i)
    if (abs(est - pi) > tol) break
    est1 <- est
  }
  
  list(NTerms = i + 1, Estimate = est1)
}

tol <- 1e-3
pi_Est2(tol)
#> $NTerms
#> [1] 1000
#> 
#> $Estimate
#> [1] 3.140593
tol - abs(pi - pi_Est2(tol)$Estimate)
#> [1] 2.500001e-10
tol - abs(pi - pi_Est1(pi_Est2(tol)$NTerms - 1))
#> [1] -1.00075e-06

Created on 2022-01-31 by the reprex package (v2.0.1)
2ekbmq32

2ekbmq323#

也许我们可以试试下面的代码

pi_Est <- function(digits = 3) {
  s <- 0
  ii <- 1
  repeat  {
    s <- s + 4 * (-1)^(ii + 1) / (2 * ii - 1)
    if (round(s, digits) == round(pi, digits)) break
    ii <- ii + 1
  }
  list(est = s, iter = ii)
}

你会看到

> pi_Est()
$est
[1] 3.142499

$iter
[1] 1103

> pi_Est(5)
$est
[1] 3.141585

$iter
[1] 130658
irtuqstp

irtuqstp4#

为什么不使用单行代码进行计算呢?

Pi <- tail(cumsum(4*(1/seq(1,4*50000000,2))*rep(c(1,-1), 50000000)),1)

相关问题