# [SciPy-User] How to do symmetry detection?

josef.pktd@gmai... josef.pktd@gmai...
Wed Jan 20 09:43:57 CST 2010

```On Wed, Jan 20, 2010 at 10:20 AM, iCy-fLaME <icy.flame.gm@gmail.com> wrote:
> Hello,
>
> I have some signals in mirror pairs in an 1D/2D array, and I am trying
> to identify the symmetry axis.
>
> A simplified example of the signal pair can look like this:
> [0, 0, 0, 0, 2, 3, 4, 0, 0, 0, 4, 3, 2, 0]
>
> The ideal output in this case will probably be:
> [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
>
> As long as the symmetry point has the largest value, it will be fine.
>
> There can be multiple pairs of signals in the array, and the length of
> separation and duration of the signal can vary from pair to pair. The
> overall length of the array is about 1k points. The output array
> should reflect the level of likeness between the two sides of the
> array.
>
> I tried doing a loop as follows:
>
> ############ Begin ############
> from numpy import array
> from numpy import zeros
> from numpy import arange
>
> data =  array([0,0,0,0,2,3,4,0,0,0,4,3,2,0])
> length = len(data)
> result = zeros(length)
>
> left = arange(length)
> left[0] = 0                 # Index to be used for the end of the left portion
>
> right = arange(length) + 1
> right[-1] = length - 1      # Index to be used for the begining of the
> right hand portion
>
> for i in range(length):
>    l_part = zeros(length)  # Default values to be zero, so
> non-overlapping region will
>    r_part = zeros(length)  #   return zero after the multiplication.
>
>    l_part[:left[i]] = data[:left[i]][::-1]     # Take the left hand
> side and mirror it
>    r_part[:length-right[i]] = data[right[i]:]  # Take the right hand side
>    result[i] = sum(l_part*r_part)/length   # Use the product and
> integral to find the similarity metric.
>
>    print l_part
>    print r_part
>    print "===============================", result[i]
>
>
> print result
>
>
> ############ END ############
>
>
> But it is rather slow for a 1000x1000 2D array, anyone got any
> suggestion for a more elegant solution?

not as general and flexible but fast

>>> a=np.array([0, 0, 0, 0, 2, 3, 4, 0, 0, 0, 4, 3, 2, 0])
>>> kw = [-1.,-1,-1,0,1,1,1]

>>> (signal.convolve(a,kw,'valid')==0).astype(int)
array([0, 0, 0, 0, 0, 1, 0, 0])

convolve can handle also nd

One idea might be to use something like this in a first round, and use
the more correct loop solution only if there are several shorter
mirrors found by convolve. Also a guess on the likely length might
improve the choice of window.
Distance measure is additive not multiplicative.

Josef

>