Numpy是一个高效数值数组的库。
mpmath,当由gmpy支持时,是一个有效的多精度数字库。
如何有效地将它们组合在一起?或者使用带有mpmath数字的Numpy数组已经很有效了吗?
要求"与本机浮点数一样高效并没有任何意义,但你可以要求它接近等效C代码的效率(或者,失败,Java / C#代码)。特别是,一个有效的多精度数字数组意味着你可以进行矢量化操作,而不必在全局解释器中查找__add__
一百万次。
编辑:关闭投票人:我的问题是将高效的方式放在一起。可能重复的答案明确指出,天真的方法效率不高。
拥有一个ntype = object的numpy数组可能会误导,因为使用标准dtypes进行操作的强大的numpy机器现在由默认对象的python运算符处理,这意味着那速度不再存在
答案 0 :(得分:2)
免责声明:我保留gmpy2
。使用开发版本执行以下测试。
a
和b
是1000个元素列表,包含250位精度的伪随机gmpy2.mpfr
值。该测试执行两个列表的逐元素乘法。
第一个测试使用列表解析:
%timeit [x*y for x,y in zip(a,b)]
1000 loops, best of 3: 322 µs per loop
第二个测试使用map
函数来执行循环:
%timeit list(map(gmpy2.mul, a, b))
1000 loops, best of 3: 299 µs per loop
第三个测试是列表理解的C实现:
%timeit vector2(a,b)
1000 loops, best of 3: 243 µs per loop
在第三次尝试中,vector2
试图成为一个表现良好的Python函数。使用gmpy2
类型转换规则处理数字类型,完成错误检查等。检查上下文设置,如果请求则创建次正规数,如果需要则引发异常等。如果您忽略所有Python增强功能并假设所有值都已gmpy2.mpfr
,我能够在第四次尝试时得到时间:
%timeit vector2(a,b)
10000 loops, best of 3: 200 µs per loop
第四个版本没有做足够的错误检查以供一般使用,但第三次和第四次尝试之间的版本是可能的。
可以减少Python开销,但随着精度的提高,有效节省会减少。
答案 1 :(得分:0)
据我所知,没有现有的Python库支持多个精度值的矢量化数组操作。遗憾的是,在numpy ndarray中使用多个精度值没有特别有效的方法,并且由于多个精度值与numpy的基本数组模型不兼容,因此极不可能存在。
浮点numpy ndarray中的每个元素占用相同的字节数,因此数组可以用第一个元素的内存地址,维度和连续之间的常规字节偏移(或步幅)来表示数组元素。
此方案具有显着的性能优势 - 相邻的数组元素位于相邻的内存地址,因此对数组的顺序读/写可从更好的引用局部性中受益。跨步对于可用性也非常重要,因为它允许您执行诸如操作相同阵列的视图而不在内存中创建新副本的操作。当你执行x[::2]
时,你实际上只是将数组的第一个轴上的步幅加倍,这样就可以解决所有其他元素。
相比之下,包含多个精度值的数组必须包含大小不等的元素,因为较高的精度值将占用比低精度值更多的字节。因此,多精度阵列不能定期跨越,并且失去了上述优点。
除了构造数组的问题之外,即使是多个精度标量的简单算术也可能比浮点标量慢得多。几乎所有现代处理器都有专门的浮点单元,而多个精度算术必须用软件而不是硬件来实现。
我怀疑这些性能问题可能是为什么还没有提供您正在寻找的功能的Python库的重要原因。
答案 2 :(得分:0)
当前项目是qd,它可以通过利用内存中固定大小的值来在Numpy数组中嵌入高精度数字。现在,该类型可用于Numpy但尚未作为dtype;但是你可以将它与对象dtype一起使用。
(如果你想看看dtype会是什么样子,你可能已经取消注释用Numpy支持编译它的相关行;它应该工作一目了然但还没有实现任何功能;下一步发布应该在九月或十月。)