对于小数组,比scipy. nimage .filters.laplace更快的离散拉普拉斯

A faster discrete Laplacian than scipy.ndimage.filters.laplace for small arrays

本文关键字:普拉斯 laplace filters 数组 于小 nimage scipy      更新时间:2023-10-16

My在scipy.ndimage.filters.laplace()中花费了大量的计算时间

scipynumpy的主要优点是将C/C++的矢量化计算包裹在python中。scipy.ndimage.filters.laplace()_nd_image.correlate1d衍生而来部分优化库nd_image.h

是否有更快的方法在大小为10-100的数组中执行此操作?

定义 拉普拉斯滤波器 -忽略除法

  • a[i-1] - 2*a[i] + a[i+1]
  • 可选可以理想地绕过n=a.shape[0]边界a[n-1] - 2*a[n-1] + a[0]

问题的根源在于scipy出色的错误处理和调试。然而,在用户知道他们在做什么的情况下,它只是提供了额外的开销。

下面的代码剥离了scipy后端的所有python混乱,并直接访问C++函数以获得~6x加速!

laplace == Mine ? True
testing timings...
array size 10
100000 loops, best of 3: 12.7 µs per loop
100000 loops, best of 3: 2.3 µs per loop
array size 100
100000 loops, best of 3: 12.7 µs per loop
100000 loops, best of 3: 2.5 µs per loop
array size 100000
1000 loops, best of 3: 413 µs per loop
1000 loops, best of 3: 404 µs per loop

from scipy import ndimage
from scipy.ndimage import _nd_image
import numpy as np
laplace_filter = np.asarray([1, -2, 1], dtype=np.float64)
def fastLaplaceNd(arr):
    output = np.zeros(arr.shape, 'float64')
    if arr.ndim > 0:
        _nd_image.correlate1d(arr, laplace_filter, 0, output, 1, 0.0, 0)
        if arr.ndim == 1: return output
        for ax in xrange(1, arr.ndim):
            output += _nd_image.correlate1d(arr, laplace_filter, ax, output, 1, 0.0, 0)
    return output
if __name__ == '__main__':
    arr = np.random.random(10)
    test = (ndimage.filters.laplace(arr, mode='wrap') == fastLaplace(arr)).all()
    assert test
    print "laplace == Mine ?", test
    print 'testing timings...'
    print "array size 10"
    %timeit ndimage.filters.laplace(arr, mode='wrap')
    %timeit fastLaplace(arr)
    print 'array size 100'
    arr = np.random.random(100)
    %timeit ndimage.filters.laplace(arr, mode='wrap')
    %timeit fastLaplace(arr)
    print "array size 100000"
    arr = np.random.random(100000)
    %timeit ndimage.filters.laplace(arr, mode='wrap')
    %timeit fastLaplace(arr)