gpt4 book ai didi

python - 高效地将 gmpy2.mpz 转换为 numpy bool 数组

转载 作者:太空宇宙 更新时间:2023-11-03 16:32:08 27 4
gpt4 key购买 nike

我尝试从 gmpy2.mpz 转换为 numpy bool 数组,但不能完全正确。 (gmpy2:https://gmpy2.readthedocs.io)

import gmpy2
import numpy as np

x = gmpy2.mpz(int('1'*1000,2))

print("wrong conversion 1")
y = np.fromstring(gmpy2.to_binary(x), dtype=bool) # this is wrong
print(np.sum(y)) # this returns 127 instead of 1000

print("wrong conversion 2")
y = np.fromstring(gmpy2.to_binary(x), dtype=np.uint8)
print(y) # array([ 1, 1, 255 ... 255], dtype=uint8)
y_bool = np.unpackbits(y)
slow_popcount = np.sum(y_bool, dtype=int)
print(slow_popcount) # 1002. should be 1000

print("Fudging an answer. This is wrong as well.")
y = np.fromstring(gmpy2.to_binary(x)[2:], dtype=np.uint8)
# is that slicing [2:] a slow operation?
y_bool = np.unpackbits(y)
print np.sum(y_bool, dtype=int) # 1000

更多测试:

np.fromstring(gmpy2.to_binary(gmpy2.mpz(int('1'*64,2))), dtype=np.uint8)
# array([ 1, 1, 255, 255, 255, 255, 255, 255, 255, 255], dtype=uint8)
np.fromstring(gmpy2.to_binary(gmpy2.mpz(int('1'*65,2))), dtype=np.uint8)
# array([ 1, 1, 255, 255, 255, 255, 255, 255, 255, 255, 1], dtype=uint8
np.fromstring(gmpy2.to_binary(gmpy2.mpz(int('1'*66,2))), dtype=np.uint8)
# array([ 1, 1, 255, 255, 255, 255, 255, 255, 255, 255, 3], dtype=uint8)
np.fromstring(gmpy2.to_binary(gmpy2.mpz(int('1'*1024,2))), dtype=np.uint8)
# array([ 1, 1, 255 ... 255], dtype=uint8)

顺便说一句,我实际上想快速获取 gmpy2.mpz 的所有设置位的索引列表、数组或 numpy 数组。我尝试转换的实际 4,777,000 个 gmpy2.mpz 每个都有 760,000 位,其中大约 2,000 位为 1。计算机上的 gmp 库是用 intel icc 编译的。

谢谢

最佳答案

有几个选项。函数 gmpy2.bit_scan1(x, n) 将返回索引 >= n 的第一个设置位的索引。

>>> x = gmpy2.mpz(123456)
>>> bin(x)
'0b11110001001000000'
>>> n = 0
>>> while True:
... n = gmpy2.bit_scan1(x, n)
... if n is None:
... break
... print(n)
... n = n + 1
...
6
9
13
14
15
16

gmpy2 还支持名为 xmpz 的整数类型。它是 mpz 类型的实验版本。主要区别在于 xmpz 类型是可变的 - 就地操作将直接修改值而不创建副本。这使得 xmpz 类型对于位操作非常有用。例如,您可以使用切片表示法提取和修改位位置。

xmpz 类型还支持名为 iter_setiter_cleariter_bits 的方法。

>>> x_str='1'*8+'01'
>>> x_int=gmpy2.xmpz(x_str, 2)
>>> list(x_int.iter_set())
[0, 2, 3, 4, 5, 6, 7, 8, 9]
>>> list(x_int.iter_clear())
[1]
>>> list(x_int.iter_bits())
[True, False, True, True, True, True, True, True, True, True]

我最初编写 xmpz 类型是为了评估优化就地操作的任何性能改进。位操作带来了最大的好处。这是埃拉托斯特尼筛法的简短而快速的实现。

def sieve(limit=1000000):
'''Returns a generator that yields the prime numbers up to limit.'''

sieve_limit = gmpy2.isqrt(limit) + 1
limit += 1
# Mark bit positions 0 and 1 as not prime.
bitmap = gmpy2.xmpz(3)
# Process 2 separately. This allows us to use p+p for the step size
# when sieving the remaining primes.
bitmap[4 : limit : 2] = -1
# Sieve the remaining primes.
for p in bitmap.iter_clear(3, sieve_limit):
bitmap[p*p : limit : p+p] = -1
return bitmap.iter_clear(2, limit)

关于python - 高效地将 gmpy2.mpz 转换为 numpy bool 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37517022/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com