Repository: scipy/scipy

Issue:
scipy.ndimage.label: Minor documentation issue
<!-- 
Thank you for taking the time to report a SciPy issue.
Please describe the issue in detail, and for bug reports
fill in the fields below. You can delete the sections that 
don't apply to your issue. You can view the final output
by clicking the preview button above.
-->

The current documentation for scipy.ndimage.label(input, structure=None, output=None) states that the *structure* parameter must be "symmetric".

It should say "centrosymmetric". There is a difference. This can be shown with the following code fragment:

### Reproducing code example:
<!-- 
If you place your code between the triple backticks below, 
it will be marked as a code block automatically 
-->

```
import numpy as np
from scipy import ndimage as ndi
y = np.around(np.random.uniform(size=(10,10))) # Any 2-D array will do here
z = np.array([[1,1,0],[1,1,0],[0,0,1]])
np.array_equal(z,z.T)
x = ndi.label(y, structure=z)
```
The call to np.array_equal returns True. This shows that 'z' has to be a symmetric matrix, because it is equal to its own transpose. That is the definition of a symmetric matrix. However, the subsequent call to ndi.label will throw a "Structure element is not symmetric" error. The reason for the error is that 'z' is not centrosymmetric.

Further, if we replace the definition of 'z' above with

z = np.array([[0,0,0],[1,1,1],[0,0,0]])

which is centrosymmetric but *not* symmetric, then ndi.label will run fine with the expected behaviour.

There are two Wikipedia articles titled "Symmetric matrix" and "Centrosymmetric matrix". These show the difference graphically, which is probably the easiest way to understand the problem.

This really is a minor nitpicking issue -- but I tripped over it, so others may as well.

Cheers
Grump


Discussion:

Resolving patch:
diff --git a/scipy/ndimage/measurements.py b/scipy/ndimage/measurements.py
--- a/scipy/ndimage/measurements.py
+++ b/scipy/ndimage/measurements.py
@@ -54,7 +54,9 @@ def label(input, structure=None, output=None):
         counted as features and zero values are considered the background.
     structure : array_like, optional
         A structuring element that defines feature connections.
-        `structure` must be symmetric.  If no structuring element is provided,
+        `structure` must be centrosymmetric
+        (see Notes).
+        If no structuring element is provided,
         one is automatically generated with a squared connectivity equal to
         one.  That is, for a 2-D `input` array, the default structuring element
         is::
@@ -65,7 +67,7 @@ def label(input, structure=None, output=None):
 
     output : (None, data-type, array_like), optional
         If `output` is a data type, it specifies the type of the resulting
-        labeled feature array
+        labeled feature array.
         If `output` is an array-like object, then `output` will be updated
         with the labeled features from this function.  This function can
         operate in-place, by passing output=input.
@@ -93,6 +95,29 @@ def label(input, structure=None, output=None):
                    objects); useful for finding features' position or
                    dimensions
 
+    Notes
+    -----
+    A centrosymmetric matrix is a matrix that is symmetric about the center.
+    See [1]_ for more information.
+
+    The `structure` matrix must be centrosymmetric to ensure
+    two-way connections.
+    For instance, if the `structure` matrix is not centrosymmetric
+    and is defined as::
+
+        [[0,1,0],
+         [1,1,0],
+         [0,0,0]]
+
+    and the `input` is::
+
+        [[1,2],
+         [0,3]]
+
+    then the structure matrix would indicate the
+    entry 2 in the input is connected to 1,
+    but 1 is not connected to 2.
+
     Examples
     --------
     Create an image with some features, then label it using the default
@@ -141,6 +166,14 @@ def label(input, structure=None, output=None):
            [2, 2, 0, 0, 1, 0],
            [0, 0, 0, 1, 0, 0]])
 
+    References
+    ----------
+
+    .. [1] James R. Weaver, "Centrosymmetric (cross-symmetric)
+       matrices, their basic properties, eigenvalues, and
+       eigenvectors." The American Mathematical Monthly 92.10
+       (1985): 711-717.
+
     """
     input = numpy.asarray(input)
     if numpy.iscomplexobj(input):


Test patch: