gmpy2

转载 2016年05月22日 23:02:18

PARI/GP是一个比较强大的数论库,“针对数论中的快速计算(大数分解,代数数论,椭圆曲线…)而设计”,它既可以被C/C++或Python之类的编程语言调用,而且它本身又是一种自成一体的脚本语言。而如果仅仅需要高精度的大数运算功能,那么GMP似乎更满足我们的需求。

了解C/C++的读者都会知道GMP(全称是GNU Multiple Precision Arithmetic Library,即GNU高精度算术运算库),它是一个开源的高精度运算库,其中不但有普通的整数、实数、浮点数的高精度运算,还有随机数生成,尤其是提供了非常完备的数论中的运算接口,比如Miller-Rabin素数测试算法、大素数生成、欧几里德算法、求域中元素的逆、Jacobi符号、legendre符号等[来源]。虽然在C/C++中调用GMP并不算复杂,但是如果能在以高开发效率著称的Python中使用GMP,那么无疑是一件快事。这正是本文要说的gmpy2
gmpy2介绍

gmpy2是Python的一个扩展库,是对GMP的封装,它的前身是gmpy。经过作者的调整和封装,使得gmpy2的使用大大简化。根据笔者目前的体会,在Python中使用gmpy2,跟在C/C++中使用GMP相比,至少以下优势:

1、简化的函数名:作者对GMP的大量函数名做了简化,比如素数的概率性测试,在C/C++中,命令是mpz_probab_prime_p,在gmpy2中,只需要简单的is_prime;

2、方便的运算符重载:如果在C/C++中,两个mpz整数相加,我们要用mpz_add(z_i, z_i, z_o),在gmpy2中,我们只需要用+号即可,更一般的,将一个mpz整数与int整数相加,也只需要+号,类似的还有减、乘、除、求模、乘方等。

作为第三方语言的调用,gmpy2的效率总比直接在C/C++中直接调用GMP会低一些,但差别是很小的,因为gmpy2就是预先编译好的C语言库而已。具体的gmpy2教程请看:
http://gmpy2.readthedocs.org/en/latest/

基本使用
本文只做简单介绍。以下代码均在Python 3.4中运行。初始化一个大整数,只需要

    import gmpy2
    n=gmpy2.mpz(1257787) #初始化
    gmpy2.is_prime(n) #概率性素性测试

这里跟C/C++是平行的,其实括号里边的参数,可以是整型,也可以是字符串。gmpy2中不仅集成了大整数mpz,还有高精度浮点数mpfr,用法跟C/C++都是平行的。下面是一些基本计算

a+2 #求和,结果是一个mpz
a-2 #求差,结果是一个mpz
a*2 #求积,结果是一个mpz
a/2 #求商,结果是一个mpfr
a//2 #求商,结果是一个mpz
a**2 #求平方,结果是一个mpz
a%2 #求模,结果是一个mpz

这些运算符的重载既直观又方便,其中将数字2换成mpz类型变量也是可以的,这自然不用多说。事实上,运算a+2,就是先将2转换为mpz中的2,然后执行mpz中的加法。
与Python自身比较

Python本身支持高精度大整数运算,一般的数字比较小的范围足够了,只是并非“快速”,读者只需要分别运行以下两句代码

gmpy2.mpz(1257787)**123456 #gmpy2计算
1257787**123456 #Python自带计算

就能感觉到了(当然,可能读者的配置还不错,两者并没有明显差别,那么请把指数扩大十倍~笔者的笔记本配置不高,见笑了^_^)。

尝试大数分解

下面来一段自己编写的大数分解的代码:

from gmpy2 import *
import time
start=time.clock()
n = mpz(63281217910257742583918406571)
x = mpz(2)
y = x**2 + 1
for i in range(n):
  p = gcd(y-x,n)
  if p != 1:
    print(p)
    break
  else:
    y=(((y**2+1)%n)**2+1)%n
    x=(x**2+1)%n
end=time.clock()
print(end-start)

该代码调用了gmpy2,算法则是Pollard rho方法,只是最单纯地运行,并没做任何优化。该算法在我的笔记本上分解
63281217910257742583918406571 = 125778791843321 × 503115167373251
耗时84秒(获得一个因子即停止)。当然这不是什么了不起的成绩,这个数字在Mathematica和PARI/GP中都是瞬间完成的。这个脚本只是纯粹练习和测试Python对gmpy2的调用。
关于Pollard rho方法的步骤:

1、给定合数n,以及x0=2,y0=x20+12、计算p=Gcd(x0−y0,n),如果p非1,则结果为n的一个因子,停止;

3、如果p=1,则按照xn+1=x2n+1,yn+1=(y2n+1)2+1,然后重复第2步。

其中,为了减少计算量,每一步xn,yn的计算,都要作模n运算,以降低计算量。上述步骤只是最简单的计算部分,还没有处理各种可能出现的异常,比如出现n|(xn−yn)等;也没有对某些细节进行优化,请谨慎引用。

参考网址:
http://hi.baidu.com/pytvzcnbuolrsue/item/ae714592f1fda8d87b7f010a

相关文章推荐

kali Linux 64位安装python的gmpy2库报错

前段时间 网上找了个解密RSA的Python脚本,兴高采烈地拿到Kali Linux中跑一下,然后提示没安装gmpy2这个库,接下来就遇到了一系列小的问题,大概说一下解决办法。 1. 执行p...

实验吧-看起来有点难【基于sleep的sql注入脚本】

原题内容: 切,你那水平也就这么点了,这都是什么题啊!!! 解题链接: http://ctf5.shiyanbar.com/basic/inject  先吐槽下,,,,这题目开了嘲讽!!! ...
  • wy_97
  • wy_97
  • 2017-08-05 13:17
  • 686

在python中用gmpy实现高精度计算

https://code.google.com/p/gmpy/wiki/UsingGmpy2AndMpfr  点击打开链接 Using gmpy2 and mpfr...

Struts2项目实战 微云盘(一):项目分析

一、项目简述 进入github下载本项目(开源) 点击这里下载完整源码压缩包(1币) 这是一个模仿网盘的项目,主要是为了熟悉Struts2框架,该项目不涉及底层DAO操作,只涉及到Struts2...

ELK之logstath的使用(2)----多行日志input插件的使用

如何使用logstath进行日志多行合并采集

考研英语真题 阅读理解翻译及笔记——1994/section 2/text3

[注]加粗单词是不认识、不熟悉的单词;划掉汉字是翻译不准确的地方;加粗汉字是书上的翻译;[这里的内容是一些语法解释]; text 3 Exceptional children are ...

python与数据挖掘-笔记2

1,python的数据结构可以分为三种类型:标量(scaler),序列(sequence),映射(mapping) 1.1,序列:python中最为基础的内建类型,分为七种类型:列表,字符串,元组,U...

Debian&Ubuntu安装apache2

Debian&Ubuntu安装apache2 先更新一下 apt-get update 查看可安装软件列表(后面加上grep,可以使用正则) apt-cache search apach |g...

剑指offer-面试题2 实现单例模式

我也不知道面试题1去哪儿了。。面试题2.实现单例模式1. 单例模式的定义  单例模式是一种常用的软件设计模式。通过单例模式可以保证系统中只有类的实例的唯一性。单例模式最初的定义出现于《设计模式》(艾迪...

使用H2O进行集成学习

使用H2O进行集成学习介绍集成学习就是组合多个机器学习算法,从而得到更好的预测性能。许多流行的现代机器学习算法实际上就是集成。比如说随机森林 和 Gradient Boosting Machine (...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)