NumPy位操作技巧

3

我试图实现通用版本的快速反平方根,我在这里找到了相关内容。目前为止,我的实现如下:

import numpy as np

def get_K(exponent, B=127, L=2**23, sigma=0.0450465, f=np.float32):
    return f((1 - exponent) * L * (B - f(sigma)))

def get_result(exponent, B=127, L=2**23, sigma=0.0450465, f=np.float32):
    K = f(get_K(exponent, 127, 2**23, f(0.0450465)))
    return lambda num: (K + f(num*exponent))

if __name__ == '__main__':
    print((get_result(0.5)(2)).astype(np.int32))

但是当我运行上面的示例时,得到的结果是532487680,这与使用numpy.float32表示对get_result(0.5)(2)的结果相同。

我做错了什么?换句话说,如何像在C语言中一样使用numpy将这个数字从32位浮点数转换为32位整数?


3
请使用.view(np.int32)代替.astype(np.int32)。 - Jaime
你期望得到什么答案? - Padraic Cunningham
对于脚本的最后一条语句,我期望得到2的平方根。 - Francesco Gramano
@Jaime 谢谢,我不知道那个方法。但是我仍然没有得到正确的结果,所以我可能误解了公式。 - Francesco Gramano
1个回答

2
下面这个快速反平方根的实现可以在numpy中使用(改编自[1])。
def fast_inv_sqrt(x):
    x = x.astype('float32')
    x2 = x * 0.5;
    y = x.view(dtype='int32')
    y = 0x5f3759df - np.right_shift(y, 1)
    y = y.view(dtype='float32')
    y  = y * ( 1.5 - ( x2 * y * y ) )
    return y

现在由于NumPy将会分配许多临时数组,因此速度不是很快。
 import numpy as np

 x = np.array(1,10000, dtype='float32')

 %timeit fast_inv_sqrt(x)
 # 10000 loops, best of 3: 36.2 µs per loop

 %timeit 1./np.sqrt(x)
 # 10000 loops, best of 3: 13.1 µs per loop

如果你需要速度,最好用C语言执行这个计算,并使用Cython、f2py等编写Python接口。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接