由Python运算π的值深入Python中科学计算的实现


Posted in Python onApril 17, 2015

π是一个无数人追随的真正的神奇数字。我不是很清楚一个永远重复的无理数的迷人之处。在我看来,我乐于计算π,也就是计算π的值。因为π是一个无理数,它是无限的。这就意味着任何对π的计算都仅仅是个近似值。如果你计算100位,我可以计算101位并且更精确。迄今为止,有些人已经选拔出超级计算机来试图计算最精确的π。一些极值包括 计算π的5亿位。你甚至能从网上找到包含 π的一百亿位的文本文件(注意啦!下载这个文件可能得花一会儿时间,并且没法用你平时使用的记事本应用程序打开。)。对于我而言,如何用几行简单的Python来计算π才是我的兴趣所在。
你总是可以 使用 math.pi 变量的 。它被 包含在 标准库中, 在你试图自己 计算它之前,你应该去使用它 。 事实上 , 我们将 用它来计算 精度 。作为 开始, 让我们看 一个 非常直截了当的 计算Pi的 方法 。像往常一样,我将使用Python 2.7,同样的想法和代码可能应用于不同的版本。我们将要使用的大部分算法来自Pi WikiPedia page并加以实现。让我们看看下面的代码:
 

importsys
importmath
 
defmain(argv):
 
  iflen(argv) !=1:
    sys.exit('Usage: calc_pi.py <n>')
 
  print'\nComputing Pi v.01\n'
   
  a=1.0
  b=1.0/math.sqrt(2)
  t=1.0/4.0
  p=1.0
     
  foriinrange(int(sys.argv[1])):
    at=(a+b)/2
    bt=math.sqrt(a*b)
    tt=t-p*(a-at)**2
    pt=2*p
     
    a=at;b=bt;t=tt;p=pt
     
  my_pi=(a+b)**2/(4*t)
  accuracy=100*(math.pi-my_pi)/my_pi
     
  print"Pi is approximately: "+str(my_pi)
  print"Accuracy with math.pi: "+str(accuracy)
   
if__name__=="__main__":
  main(sys.argv[1:])

这是个非常简单的脚本,你可以下载,运行,修改,和随意分享给别人。你能够看到类似下面的输出结果: 

由Python运算π的值深入Python中科学计算的实现

 你会发现,尽管 n 大于4 ,我们逼近 Pi 精度却没有多大的提升。 我们可以猜到即使 n的值更大,同样的事情(pi的逼近精度没有提升)依旧会发生。幸运的是,有不止一种方法来揭开这个谜。使用 Python Decimal (十进制)库,我们可以就可以得到更高精度的值来逼近Pi。让我们来看看库函数是如何使用的。这个简化的版本,可以得到多于11位的数字 通常情况小Python 浮点数给出的精度。下面是Python Decimal 库中的一个例子 :

wpid-python_decimal_example-2013-05-28-12-54.png

看到这些数字。不对! 我们输入的仅是 3.14,为什么我们得到了一些垃圾(junk)? 这是内存垃圾(memory junk)。 简单点说,Python给你你想要的十进制数,再加上一点点额外的值。 只要精度小于垃圾数,它不会影响任何计算。通过设置getcontext().prec 你可以的到你想要的位数 。我们试试。

由Python运算π的值深入Python中科学计算的实现

看到这些数字。不对! 我们输入的仅是 3.14,为什么我们得到了一些垃圾(junk)? 这是内存垃圾(memory junk)。 简单点说,Python给你你想要的十进制数,再加上一点点额外的值。 只要精度小于垃圾数,它不会影响任何计算。通过设置getcontext().prec 你可以的到你想要的位数 。我们试试。

由Python运算π的值深入Python中科学计算的实现

很好。 现在让我们 试着用这个 来 看看我们是否能 与我们以前的 代码 有更好的 逼近 。 现在, 我通常 是反对 使用“ from library import * ” , 但在这种情况下, 它会 使代码 看起来更漂亮 。
 

importsys
importmath
fromdecimalimport*
 
defmain(argv):
 
  iflen(argv) !=1:
    sys.exit('Usage: calc_pi.py <n>')
 
  print'\nComputing Pi v.01\n'
   
  a=Decimal(1.0)
  b=Decimal(1.0/math.sqrt(2))
  t=Decimal(1.0)/Decimal(4.0)
  p=Decimal(1.0)
     
  foriinrange(int(sys.argv[1])):
    at=Decimal((a+b)/2)
    bt=Decimal(math.sqrt(a*b))
    tt=Decimal(t-p*(a-at)**2)
    pt=Decimal(2*p)
     
    a=at;b=bt;t=tt;p=pt
     
  my_pi=(a+b)**2/(4*t)
  accuracy=100*(Decimal(math.pi)-my_pi)/my_pi
     
  print"Pi is approximately: "+str(my_pi)
  print"Accuracy with math.pi: "+str(accuracy)
   
if__name__=="__main__":
  main(sys.argv[1:])

 
输出结果: 

由Python运算π的值深入Python中科学计算的实现

 好了。我们更准确了,但看起来似乎有一些舍入。从n = 100和n = 1000,我们有相同的精度。现在怎么办?好吧,现在我们来求助于公式。到目前为止,我们计算Pi的方式是通过对几部分加在一起。我从DAN 的关于Calculating Pi 的文章中发现一些代码。他建议我们用以下3个公式:

    Bailey?Borwein?Plouffe 公式
   Bellard的公式
    Chudnovsky 算法

让我们从Bailey?Borwein?Plouffe 公式开始。它看起来是这个样子: 

由Python运算π的值深入Python中科学计算的实现

 在代码中我们可以这样编写它:
 

import sys
import math
from decimal import *
 
def bbp(n):
  pi=Decimal(0)
  k=0
  while k < n:
    pi+=(Decimal(1)/(16**k))*((Decimal(4)/(8*k+1))-(Decimal(2)/(8*k+4))-(Decimal(1)/(8*k+5))-(Decimal(1)/(8*k+6)))
    k+=1
  return pi
 
def main(argv):
 
    if len(argv) !=2:
    sys.exit('Usage: BaileyBorweinPlouffe.py <prec> <n>')
     
  getcontext().prec=(int(sys.argv[1]))
  my_pi=bbp(int(sys.argv[2]))
  accuracy=100*(Decimal(math.pi)-my_pi)/my_pi
 
  print"Pi is approximately "+str(my_pi)
  print"Accuracy with math.pi: "+str(accuracy)
   
if __name__=="__main__":
  main(sys.argv[1:])

 
抛开“ 包装”的代码,BBP(N)的功能是你真正想要的。你给它越大的N和给 getcontext().prec 设置越大的值,你就会使计算越精确。让我们看看一些代码结果:

由Python运算π的值深入Python中科学计算的实现

这有许多数字位。你可以看出,我们并没有比以前更准确。所以我们需要前进到下一个公式,贝拉公式,希望能获得更好的精度。它看起来像这样: 

由Python运算π的值深入Python中科学计算的实现

 我们将只改变我们的变换公式,其余的代码将保持不变。点击这里下载Python实现的贝拉公式。让我们看一看bellards(n):
 

def bellard(n):
  pi=Decimal(0)
  k=0
  while k < n:
    pi+=(Decimal(-1)**k/(1024**k))*( Decimal(256)/(10*k+1)+Decimal(1)/(10*k+9)-Decimal(64)/(10*k+3)-Decimal(32)/(4*k+1)-Decimal(4)/(10*k+5)-Decimal(4)/(10*k+7)-Decimal(1)/(4*k+3))
    k+=1
  pi=pi*1/(2**6)
  return pi

由Python运算π的值深入Python中科学计算的实现

   哦,不,我们得到的是同样的精度。好吧,让我们试试第三个公式, Chudnovsky 算法,它看起来是这个样子: 

由Python运算π的值深入Python中科学计算的实现

   再一次,让我们看一下这个计算公式(假设我们有一个阶乘公式)。 点击这里可下载用 python 实现的 Chudnovsky 公式。

下面是程序和输出结果:
 

def chudnovsky(n):
  pi=Decimal(0)
  k=0
  while k < n:
    pi+=(Decimal(-1)**k)*(Decimal(factorial(6*k))/((factorial(k)**3)*(factorial(3*k)))*(13591409+545140134*k)/(640320**(3*k)))
    k+=1
  pi=pi*Decimal(10005).sqrt()/4270934400
  pi=pi**(-1)
  return pi

由Python运算π的值深入Python中科学计算的实现

    所以我们有了什么结论?花哨的算法不会使机器浮点世界达到更高标准。我真的很期待能有一个比我们用求和公式时所能得到的更好的精度。我猜那是过分的要求。如果你真的需要用PI,就只需使用math.pi变量了。然而,作为乐趣和测试你的计算机真的能有多快,你总是可以尝试第一个计算出Pi的百万位或者更多位是几。

Python 相关文章推荐
Python设置Socket代理及实现远程摄像头控制的例子
Nov 13 Python
python 实现自动远程登陆scp文件实例代码
Mar 13 Python
tensorflow获取变量维度信息
Mar 10 Python
python面向对象多线程爬虫爬取搜狐页面的实例代码
May 31 Python
Django model序列化为json的方法示例
Oct 16 Python
python将字符串list写入excel和txt的实例
Jul 20 Python
使用python快速在局域网内搭建http传输文件服务的方法
Nov 14 Python
Python csv文件的读写操作实例详解
Nov 19 Python
Pycharm2020.1安装无法启动问题即设置中文插件的方法
Aug 07 Python
Python 列表推导式需要注意的地方
Oct 23 Python
使用pandas实现筛选出指定列值所对应的行
Dec 13 Python
python使用opencv对图像添加噪声(高斯/椒盐/泊松/斑点)
Apr 06 Python
在Python中实现贪婪排名算法的教程
Apr 17 #Python
在Linux下调试Python代码的各种方法
Apr 17 #Python
Python脚本在Appium库上对移动应用实现自动化测试
Apr 17 #Python
Python中生成器和yield语句的用法详解
Apr 17 #Python
使用Python脚本在Linux下实现部分Bash Shell的教程
Apr 17 #Python
使用Python的Scrapy框架编写web爬虫的简单示例
Apr 17 #Python
用Python的Django框架编写从Google Adsense中获得报表的应用
Apr 17 #Python
You might like
php面向对象的方法重载两种版本比较
2008/09/08 PHP
PHP采集相关教程之一 CURL函数库
2010/02/15 PHP
php抓取页面的几种方法详解
2013/06/17 PHP
Fatal error: session_start(): Failed to initialize storage module: files问题解决方法
2014/05/04 PHP
PHP截取指定图片大小的方法
2014/12/10 PHP
在html页面中包含共享页面的方法
2008/10/24 Javascript
Jquery封装tab自动切换效果的具体实现
2013/07/13 Javascript
简单实用的全选反选按钮例子
2013/10/18 Javascript
BootStrap 智能表单实战系列(五) 表单依赖插件处理
2016/06/13 Javascript
基于JS实现导航条之调用网页助手小精灵的方法
2016/06/17 Javascript
详解AngularJs中$sce与$sceDelegate上下文转义服务
2016/09/21 Javascript
ionic2屏幕适配实现适配手机、平板等设备的示例代码
2017/08/11 Javascript
浅析Vue实例以及生命周期
2018/08/14 Javascript
JavaScript使用prototype原型实现的封装继承多态示例
2018/08/31 Javascript
解决vue props 拿不到值的问题
2018/09/11 Javascript
Vue动态创建注册component的实例代码
2019/06/14 Javascript
JavaScript创建表格的方法
2020/04/13 Javascript
JavaScript实现串行请求的示例代码
2020/09/14 Javascript
JavaScript实现弹出窗口效果
2020/12/09 Javascript
Python列表(list)、字典(dict)、字符串(string)基本操作小结
2014/11/28 Python
python通过pil模块将raw图片转换成png图片的方法
2015/03/16 Python
Python编程之gui程序实现简单文件浏览器代码
2017/12/08 Python
用python标准库difflib比较两份文件的异同详解
2018/11/16 Python
python正则表达式匹配不包含某几个字符的字符串方法
2019/07/23 Python
Django 拆分model和view的实现方法
2019/08/16 Python
python 经典数字滤波实例
2019/12/16 Python
TensorBoard 计算图的查看方式
2020/02/15 Python
pandas DataFrame运算的实现
2020/06/14 Python
HTML5对比HTML4的主要改变和改进总结
2016/05/27 HTML / CSS
中国京东和泰国中央集团合资的网站:JD CENTRAL
2020/08/22 全球购物
生日宴会答谢词
2014/01/09 职场文书
教师求职自荐书
2014/06/14 职场文书
学校运动会报道稿
2014/09/23 职场文书
2019银行员工个人工作自我鉴定
2019/06/27 职场文书
python3 sqlite3限制条件查询的操作
2021/04/07 Python
MySQL详解进行JDBC编程与增删改查方法
2022/06/16 MySQL