[Numpy-discussion] Geometrically defined masking arrays; how to optimize?

Daπid davidmenhur at gmail.com
Tue Feb 11 16:28:24 EST 2014


A small improvement:

# Dimensions
N = 100
M = 200

# Coordinates of the centre
x0 = 40
y0 = 70

x, y = np.meshgrid(np.arange(N) - x0, np.arange(M) - y0, sparse=True)

# Center at 40, 70, radius 20
out_circle = (x * x + y * y < 20**2)

out_ring = out_circle - (x * x + y * y < 10**2)

plt.imshow(out_circle)
plt.figure()
plt.imshow(out_ring)
plt.show()

Using sparse you can avoid the repetition of the arrays, getting the same
functionality. Also, if the image is big, you can delegate the computations
of out_circle and out_ring to numexpr for speed.

/David.


On 11 February 2014 22:16, Daπid <davidmenhur at gmail.com> wrote:

> Here it is an example:
>
> import numpy as np
> import pylab as plt
>
> N = 100
> M = 200
> x, y = np.meshgrid(np.arange(N), np.arange(M))
>
> # Center at 40, 70, radius 20
> x -= 40
> y -= 70
> out_circle = (x * x + y * y < 20**2)
>
> out_ring = out_circle - (x * x + y * y < 10**2)
>
> plt.imshow(out_circle)
> plt.figure()
> plt.imshow(out_ring)
> plt.show()
>
> Note that I have avoided taking the costly square root of each element by
> just taking the square of the radius. It can also be generalised to
> ellipses or rectangles, if you need it.
>
> Also, don't use 0 as a False value, and don't force it to be a 0. Instead,
> use "if not ring:"
>
>
> /David
>
>
>
>
>
> On 11 February 2014 21:56, Wolfgang Draxinger <
> Wolfgang.Draxinger at physik.uni-muenchen.de> wrote:
>
>> Hi,
>>
>> I implemented the following helper function to create masking arrays:
>>
>> def gen_mask(self, ring, sector):
>>         in_segment = None
>>         if ring == 0:
>>                 radius = self.scales()[0]
>>                 def in_center_circle(xy):
>>                         dx = xy[0] - self.xy[0]
>>                         dy = xy[1] - self.xy[1]
>>                         r = math.sqrt( dx**2 + dy**2 )
>>                         return r < radius
>>                 in_segment = in_center_circle
>>         else:
>>                 angle = ( self.a_sector(sector, ring),
>>                           self.a_sector( (sector+1) % self.n_sectors(),
>> ring) )
>>                 radii = self.scales()[ring:ring+1]
>>                 def in_segment_ring(xy):
>>                         dx = xy[0] - self.xy[0]
>>                         dy = xy[1] - self.xy[1]
>>                         r = math.sqrt( dx**2 + dy**2 )
>>                         a = math.atan2( dy, dx )
>>                         return r >= radii[0] and r < radii[1] \
>>                            and a >= angle[0] and a < angle[1]
>>                 in_segment = in_segment_ring
>>
>>         width,height = self.arr.shape
>>
>>         mask = numpy.zeros(shape=(width, height), dtype=numpy.bool)
>>         for y in range(height):
>>                 for x in range(width):
>>                         mask[x][y] = in_segment((x,y))
>>         return mask
>>
>> self.scales() generates a list of radius scaling factors.
>> self.a_sector() gives the dividing angle between sectors "sector" and
>> "sector+1" on the given ring.
>>
>> The function works, it generates the masks as I need it. The problem is
>> - of course - that it's quite slow due to the inner loops the perform
>> the geometrical test if the given element of the array self.arr is
>> withing the bounds of the ring-sector for which the mask is generated.
>>
>> I wonder if you guys have some ideas, on how I could accelerate this.
>> This can be perfectly well constructed by boolean combination of
>> elementary geometrical objects. For example a ring would be
>>
>> ring(p, r0, r1): disk(p, r1) xor disk(p, r0) # where r0 < r1
>>
>> The sector would then be
>>
>> ring_sector(p, r, s): ring(p, r, r + ...) and sector(p, s, s+1)
>>
>> I'd like to avoid doing this using some C helper routine. I'm looking
>> for something that is the most efficient when it comes to
>> "speedup"/"time invested to develop this".
>>
>>
>> Cheers,
>>
>> Wolfgang
>> _______________________________________________
>> NumPy-Discussion mailing list
>> NumPy-Discussion at scipy.org
>> http://mail.scipy.org/mailman/listinfo/numpy-discussion
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/numpy-discussion/attachments/20140211/8a680387/attachment.html>


More information about the NumPy-Discussion mailing list