1

Numpy 是一个用于高效数值数组的库。

mpmath 在 gmpy 的支持下,是一个用于高效多精度数的库。

如何有效地将它们组合在一起?还是仅使用带有 mpmath 数字的 Numpy 数组已经很有效?

要求“与本机浮点数一样高效”是没有意义的,但您可以要求它接近等效 C 代码(或者,如果不这样做,Java/C# 代码)的效率。特别是,一个高效的多精度数字数组意味着您可以进行矢量化操作,而不必__add__在 Global Interpreter 中查找一百万次。

编辑:致亲密的选民:我的问题是关于将它们组合在一起的有效方法。可能重复中的答案特别指出,幼稚的方法效率不高。

拥有一个 dtype=object 的 numpy 数组可能会产生误导,因为强大的 numpy 机制使得使用标准 dtypes 的操作超级快,现在由默认对象的 python 运算符处理,这意味着速度不会存在不再

4

3 回答 3

2

免责声明:我坚持gmpy2. 以下测试是使用开发版本进行的。

a并且是 1000 个元素列表,其中包含250 位精度b的伪随机值。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 函数。使用 's 的类型转换规则处理数字类型gmpy2,完成错误检查等。检查上下文设置,如果请求则创建次正规数,如果需要则引发异常等。如果您忽略所有 Python 增强并假设所有值已经是gmpy2.mpfr,我能够在第四次尝试时缩短时间:

%timeit vector2(a,b)
10000 loops, best of 3: 200 µs per loop

第四个版本没有进行足够的错误检查以供普遍使用,但第三和第四次尝试之间的版本可能是可能的。

可以减少 Python 开销,但随着精度的提高,有效节省的费用会减少。

于 2015-07-09T07:46:44.167 回答
0

据我所知,没有现有的 Python 库支持对多个精度值进行矢量化数组操作。不幸的是,没有特别有效的方法可以在 numpy ndarray 中使用多个精度值,而且极不可能有,因为多个精度值与 numpy 的基本数组模型不兼容。

浮点 numpy ndarray 中的每个元素占用相同数量的字节,因此可以根据第一个元素的内存地址、维度和连续数组元素之间的常规字节偏移量(或步幅)来表示数组。

该方案具有显着的性能优势——相邻的数组元素位于相邻的内存地址,因此对数组的顺序读/写受益于更好的引用局部性。跨步对于可用性也非常重要,因为它允许您执行诸如操作同一数组的视图之类的操作,而无需在内存中创建新副本。当你这样做时x[::2],你实际上只是将数组第一个轴上的步幅加倍,这样你就可以处理所有其他元素。

相比之下,包含多个精度值的数组必须包含大小不等的元素,因为精度较高的值会比低精度值占用更多的字节。因此,多精度数组不能有规律地跨步,并且失去了上面提到的好处。

除了构造数组的问题外,即使是多精度标量的简单算术也可能比浮点标量慢得多。几乎所有现代处理器都有专门的浮点单元,而多精度运算必须用软件而不是硬件来实现。

我怀疑这些性能问题可能是目前还没有提供您正在寻找的功能的 Python 库的重要原因。

于 2015-07-07T22:39:44.670 回答
0

当前的一个项目是qd,它将能够通过利用其值在内存中的固定大小来将高精度数字嵌入到 Numpy 数组中。目前,该类型可用于 Numpy,但还不能作为 dtype;但是,您已经可以将它与对象 dtype 一起使用。

(如果您想查看 dtype 的外观,您可能已经取消了使用 Numpy 支持编译它的相关行的注释;它应该可以一目了然,但尚未实现任何功能;下一个版本应该在 9 月或十月。)

于 2015-07-31T07:02:40.973 回答