# [pypy-svn] r76268 - pypy/branch/micronumpy/pypy/tool

dan at codespeak.net dan at codespeak.net
Sat Jul 17 00:41:04 CEST 2010

```Author: dan
Date: Sat Jul 17 00:41:02 2010
New Revision: 76268

pypy/branch/micronumpy/pypy/tool/convolve.py
Modified:
pypy/branch/micronumpy/pypy/tool/numpybench.py
Log:
Oops, I forgot the most important part of the benchmark!

==============================================================================
--- (empty file)
+++ pypy/branch/micronumpy/pypy/tool/convolve.py	Sat Jul 17 00:41:02 2010
@@ -0,0 +1,43 @@
+from __future__ import division
+from __main__ import numpy as np
+
+def naive_convolve(f, g):
+    # f is an image and is indexed by (v, w)
+    # g is a filter kernel and is indexed by (s, t),
+    #   it needs odd dimensions
+    # h is the output image and is indexed by (x, y),
+    #   it is not cropped
+    if g.shape[0] % 2 != 1 or g.shape[1] % 2 != 1:
+        raise ValueError("Only odd dimensions on filter supported")
+    # smid and tmid are number of pixels between the center pixel
+    # and the edge, ie for a 5x5 filter they will be 2.
+    #
+    # The output size is calculated by adding smid, tmid to each
+    # side of the dimensions of the input image.
+    vmax = f.shape[0]
+    wmax = f.shape[1]
+    smax = g.shape[0]
+    tmax = g.shape[1]
+    smid = smax // 2
+    tmid = tmax // 2
+    xmax = vmax + 2*smid
+    ymax = wmax + 2*tmid
+    # Allocate result image.
+    h = np.zeros([xmax, ymax], dtype=f.dtype)
+    # Do convolution
+    for x in range(xmax):
+        for y in range(ymax):
+            # Calculate pixel value for h at (x,y). Sum one component
+            # for each pixel (s, t) of the filter g.
+            s_from = max(smid - x, -smid)
+            s_to = min((xmax - x) - smid, smid + 1)
+            t_from = max(tmid - y, -tmid)
+            t_to = min((ymax - y) - tmid, tmid + 1)
+            value = 0
+            for s in range(s_from, s_to):
+                for t in range(t_from, t_to):
+                    v = x - smid + s
+                    w = y - tmid + t
+                    value += g[smid - s, tmid - t] * f[v, w]
+            h[x, y] = value
+    return h

Modified: pypy/branch/micronumpy/pypy/tool/numpybench.py
==============================================================================
--- pypy/branch/micronumpy/pypy/tool/numpybench.py	(original)
+++ pypy/branch/micronumpy/pypy/tool/numpybench.py	Sat Jul 17 00:41:02 2010
@@ -21,13 +21,29 @@
return numpy.array(kernel)

if __name__ == '__main__':
-    from sys import argv as args
-    width, height, kwidth, kheight = [int(x) for x in args[1:]]
+    from optparse import OptionParser
+
+    option_parser = OptionParser()
+                             help="The size of the convolution kernel, given as WxH. ie 3x3"
+                                  "Note that both dimensions must be odd.")
+                             help="The size of the image, given as WxH. ie. 256x256")
+                             help="The number of times to run the convolution filter")
+
+    options, args = option_parser.parse_args()
+
+    def parse_dimension(arg):
+        return [int(s.strip()) for s in arg.split('x')]
+
+    width, height = parse_dimension(options.image)
+    kwidth, kheight = parse_dimension(options.kernel)
+    count = int(options.count)

image = generate_image(width, height)
kernel = generate_kernel(kwidth, kheight)

from timeit import Timer
convolve_timer = Timer('naive_convolve(image, kernel)', 'from convolve import naive_convolve; from __main__ import image, kernel; gc.enable()')
-    count = 100
print "%.5f sec/pass" % (convolve_timer.timeit(number=count)/count)

```